SQLite assertion failure
(1) By Yu Liang (LY1598773890) on 2022-03-02 20:43:29 [link] [source]
Query:
CREATE TABLE v0 ( c1 INT, c2 TEXT PRIMARY KEY, c3 );
INSERT INTO v0 VALUES ( 0, 'x', 'y' );
CREATE INDEX i4 ON v0 ( c3, c1, c2, c2);
CREATE VIEW v5 AS SELECT c2 FROM v0 WHERE c3 = 'y' OR c2 = 'x';
SELECT * FROM v5 WHERE FALSE OR EXISTS ( SELECT * FROM v0 WHERE v5.c2 = v5.c2 );
Run on latest Debug Version 86c5fa2f30:
sqlite3: sqlite3.c:89105: int sqlite3VdbeExec(Vdbe *): Assertion `p2<(u32)pC->nField' failed.
[1] 366577 abort (core dumped) ./sqlite3
Run on Non-Debug Version 86c5fa2f30 with ASAN:
Return x
as expected.
Bisect:
1 BAD 2022-03-02 17:50:59 86c5fa2f301e4bdb
3 BAD 2021-07-09 00:12:05 eb8af9a494fb68c0
6 BAD 2021-06-11 12:02:00 852ee0e91ceae090
7 BAD 2021-05-26 18:46:51 f30fb19ff763a7cb
12 GOOD 2021-05-26 14:32:33 3e2c36a8272ab3c1 CURRENT
11 GOOD 2021-05-25 16:10:12 708ce7ad8acee702
10 GOOD 2021-05-25 11:39:14 b0bc5ab9ceec496a
9 GOOD 2021-05-24 00:17:04 0be6b6c9f7c562e7
8 GOOD 2021-05-20 11:42:51 67bde01614edd944
5 GOOD 2021-05-14 15:37:00 cf63abbe559d04f9
4 GOOD 2021-04-06 16:55:30 039ad662dd899048
2 GOOD 2020-12-01 16:14:00 a26b6597e3ae2722
Timeline
18:46:51 [f30fb19ff7] Take care that the code is not generated for the same Select object more than once, as transformations that apply during the first pass might cause problems for the second pass. dbsqlfuzz 836b625cd8a41809ef80fc7ebaa6554357bcb463. (user: drh tags: trunk)
14:32:33 [3e2c36a827] *BRANCH* *CURRENT* Update an assert() in wherecode.c that might fail following an unrelated SQL error. (user: dan tags: trunk)
Looking forward to your reply. :-)
(2) By Richard Hipp (drh) on 2022-03-03 03:37:12 in reply to 1 [source]
Simplified test case:
CREATE TABLE t0(w); INSERT INTO t0(w) VALUES(1); CREATE TABLE t1(x INT, y INT PRIMARY KEY, z); INSERT INTO t1 VALUES(0,111,222); CREATE INDEX t1zxy ON t1(z,x,y); SELECT y FROM t1 WHERE (z=222 OR y=111) AND (false OR EXISTS(SELECT 1 FROM t0 WHERE t1.y));
Probably there are even simpler test cases lurking but this is the one I've been using for analysis. I think the solution is the following patch:
Index: src/wherecode.c ================================================================== --- src/wherecode.c +++ src/wherecode.c @@ -2355,11 +2355,11 @@ testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); testcase( pWC->a[iTerm].wtFlags & TERM_SLICE ); if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){ continue; } - if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; + if( (pWC->a[iTerm].eOperator & WO_SINGLE)==0 ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); pExpr = sqlite3ExprDup(db, pExpr, 0); pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); } if( pAndExpr ){
Emphasis is on the word "think" because I still need to do a lot more testing and analysis to verify that this is the correct fix. And the final patch will likely contain many new assert() statements to help prevent or at least detect similar problems in the future.
(3) By Richard Hipp (drh) on 2022-03-03 16:01:01 in reply to 1 [link] [source]
Proposed fix on trunk at check-in 61a1c6dbd089979c.