SQLite Forum

Query triggers Segmentation Fault
Login

Query triggers Segmentation Fault

(1) By Yu Liang (LY1598773890) on 2021-05-19 19:13:23 [link]

Hi all.

For query:

```SQL
CREATE TABLE v0 ( v2 INTEGER );
CREATE TABLE v3 ( v5 INTEGER );
WITH v0 AS ( SELECT * FROM v3 ) UPDATE v0 SET v2 = 'x' FROM v3;

```

Segmentation Fault triggered. Address Sanitizer outputs the following information: 

```
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3922846==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000007d7f8c bp 0x7fff139364d0 sp 0x7fff13936380 T0)
==3922846==The signal is caused by a READ memory access.
==3922846==Hint: address points to the zero page.
    #0 0x7d7f8c in sqlite3ExprVectorSize /home/hong/sqlite-asan-build/sqlite3.c:101589:18
    #1 0x7d7f8c in sqlite3ExprIsVector /home/hong/sqlite-asan-build/sqlite3.c:101579:10
    #2 0x7d7f8c in substExpr /home/hong/sqlite-asan-build/sqlite3.c:135568:11
    #3 0x7d7310 in substExprList /home/hong/sqlite-asan-build/sqlite3.c:135635:25
    #4 0x7d7310 in substSelect /home/hong/sqlite-asan-build/sqlite3.c:135648:5
    #5 0x6d726d in flattenSubquery /home/hong/sqlite-asan-build/sqlite3.c:136313:7
    #6 0x6d726d in sqlite3Select /home/hong/sqlite-asan-build/sqlite3.c:138246:9
    #7 0x862613 in updateFromSelect /home/hong/sqlite-asan-build/sqlite3.c:141142:3
    #8 0x7136e0 in sqlite3Update /home/hong/sqlite-asan-build/sqlite3.c:141555:9
    #9 0x6902b8 in yy_reduce /home/hong/sqlite-asan-build/sqlite3.c:161919:3
    #10 0x56e010 in sqlite3Parser /home/hong/sqlite-asan-build/sqlite3.c:162963:15
    #11 0x56e010 in sqlite3RunParser /home/hong/sqlite-asan-build/sqlite3.c:164259:5
    #12 0x663e3d in sqlite3Prepare /home/hong/sqlite-asan-build/sqlite3.c:131652:5
    #13 0x56a6af in sqlite3LockAndPrepare /home/hong/sqlite-asan-build/sqlite3.c:131727:10
    #14 0x53e804 in sqlite3_prepare_v2 /home/hong/sqlite-asan-build/sqlite3.c:131812:8
    #15 0x4f5482 in shell_exec /home/hong/sqlite-asan-build/shell.c:13602:10
    #16 0x52a90f in runOneSqlLine /home/hong/sqlite-asan-build/shell.c:20626:8
    #17 0x4f9e8b in process_input /home/hong/sqlite-asan-build/shell.c:20726:17
    #18 0x4d6e10 in main /home/hong/sqlite-asan-build/shell.c
    #19 0x7fc161e9e0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #20 0x41c63d in _start (/home/hong/sqlite-asan-build/sqlite3+0x41c63d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/hong/sqlite-asan-build/sqlite3.c:101589:18 in sqlite3ExprVectorSize
==3922846==ABORTING

```

This behavior can be reproduced by one of the latest development version, fossil:  b480aacb3430a789d98ffd81a1886bbbc3cda5b0e736ec9a3e2b463db2a3b3ad, but seems not affecting the stable release: tested with SQLite version 3.32.3 with correct run through. 

Look forward to your reply.

(2) By Richard Hipp (drh) on 2021-05-19 21:59:57 in reply to 1 [link]

The segfault is due to recent, unreleased changes.  Specifically, the
[removal of "rowid" from VIEWs][1].  So, you shouldn't be able to segfault
an official release version of SQLite using the example above.

[1]: src:/timeline?c=a2ddb89b206c1387

However, this example does point to a name resolution problem with
common table expressions.  In particular, the following SQL results
in an incorrect answer:

> ~~~~
CREATE TABLE t1(k);
CREATE TABLE log(k, cte_map, main_map);
CREATE TABLE map(k, v);
INSERT INTO map VALUES(1, 'main1'), (2, 'main2');
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
  INSERT INTO log
      WITH map(k,v) AS (VALUES(1,'cte1'),(2,'cte2'))
      SELECT
        new.k,
        (SELECT v FROM map WHERE k=new.k),
        (SELECT v FROM main.map WHERE k=new.k);
END;
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
SELECT * FROM log;
~~~~

The output here should be:

~~~~
┌───┬─────────┬──────────┐
│ k │ cte_map │ main_map │
├───┼─────────┼──────────┤
│ 1 │ cte1    │ main1    │
│ 2 │ cte2    │ main2    │
└───┴─────────┴──────────┘
~~~~

But instead we get:

~~~~
┌───┬─────────┬──────────┐
│ k │ cte_map │ main_map │
├───┼─────────┼──────────┤
│ 1 │ cte1    │ cte1     │
│ 2 │ cte2    │ cte2     │
└───┴─────────┴──────────┘
~~~~

The problem is that "main.map" in the trigger is getting bound
to the common-table expression called "map" rather than to the
table called "map".  This name resolution problem has existed
ever since common-table expression support was added to SQLite
with version 3.8.3 (2014-02-03).

[Check-in 0f0959c6f95046e8][2] should resolve the segfault,
or at least the specific example you provide above.  But
consider that check-in to be an interim fix.  The deeper
problem of name resolution inside of common table expressions
will take a bit more work, and might not be fixed for another
day or two.

[2]: src:/timeline?c=0f0959c6f95046e8

(3) By Yu Liang (LY1598773890) on 2021-05-20 00:35:02 in reply to 2 [link]

Thank you for patch and the explanation.

(4) By Richard Hipp (drh) on 2021-05-20 00:53:25 in reply to 2 [link]

[Check-in 5614279daff5007d][1] is an alternative fix that handles both
the CTE name resolution problem and the original segfault.

[1]: src:/timeline?c=5614279daff5007d

(5) By Mark Lawrence (mark) on 2021-05-21 07:55:08 in reply to 2

Richard, Your use of a CTE in the trigger above appears to contradict chapter 5 of [](https://sqlite.org/lang_with.html). Has something changed or do I misunderstand the documentation?