From b5246e518bd0fbec3459f5e2f88cb2fc45112da3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 8 Jul 2013 21:12:57 +0000 Subject: [PATCH] Fix an adverse interaction between the IS NOT NULL optimization (available only with SQLITE_ENABLE_STAT3) and the transitive constraint processing. Fix for ticket [d805526eae253] FossilOrigin-Name: 3b30b75b342bb6b424ad2bf7cd841b2c88bdad44 --- manifest | 14 +++++------ manifest.uuid | 2 +- src/where.c | 11 +++++++-- test/transitive1.test | 55 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6d2e4c747d..9d121d87b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\soptional\s5th\sparameter\sto\sthe\snext_char()\sfunction\sthat\sis\sthe\ncollating\ssequence\sto\suse\sfor\scomparison. -D 2013-07-08T01:27:43.173 +C Fix\san\sadverse\sinteraction\sbetween\sthe\sIS\sNOT\sNULL\soptimization\s(available\nonly\swith\sSQLITE_ENABLE_STAT3)\sand\sthe\stransitive\sconstraint\sprocessing.\nFix\sfor\sticket\s[d805526eae253] +D 2013-07-08T21:12:57.346 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c 7867ef5b45785847ae68a93a68d05861344f07f0 +F src/where.c cd7ef913bbdcbc34b20d02daf13f16c1eaa4a474 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -960,7 +960,7 @@ F test/trace2.test e7a988fdd982cdec62f1f1f34b0360e6476d01a0 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 -F test/transitive1.test d04aa9023e425d6f2d4aa61dd81ee9e102f89062 +F test/transitive1.test 0ee69546d6fa20e577a4a706d7daa01c7eba9239 F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03 F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 @@ -1101,7 +1101,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P cdb97d41abf4a3b8e22fa8ca9f3aab4a3f968d27 -R cddb399d89cded656ee0c42122eb620d +P 9415db6ef255d27ca8473c17e65749a197c30455 +R a093ccd9e68cbc04e5f435cf1a230f1a U drh -Z 856ce6a2b43d394812cb00c43d8e6345 +Z 54f267cd767cbb6a7ba6c4b63d0480c1 diff --git a/manifest.uuid b/manifest.uuid index 570225806b..6778efe7d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9415db6ef255d27ca8473c17e65749a197c30455 \ No newline at end of file +3b30b75b342bb6b424ad2bf7cd841b2c88bdad44 \ No newline at end of file diff --git a/src/where.c b/src/where.c index a241e12842..023ad2eb90 100644 --- a/src/where.c +++ b/src/where.c @@ -3335,10 +3335,11 @@ static Bitmask codeOneLoopStart( assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ + assert( (pStart->wtFlags & TERM_VNULL)==0 ); testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ pX = pStart->pExpr; assert( pX!=0 ); - assert( pStart->leftCursor==iCur ); + testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); VdbeComment((v, "pk")); @@ -3352,7 +3353,8 @@ static Bitmask codeOneLoopStart( Expr *pX; pX = pEnd->pExpr; assert( pX!=0 ); - assert( pEnd->leftCursor==iCur ); + assert( (pEnd->wtFlags & TERM_VNULL)==0 ); + testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */ testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ memEndValue = ++pParse->nMem; sqlite3ExprCode(pParse, pX->pRight, memEndValue); @@ -4282,6 +4284,11 @@ static int whereLoopAddBtreeIndex( for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ int nIn = 0; if( pTerm->prereqRight & pNew->maskSelf ) continue; +#ifdef SQLITE_ENABLE_STAT3 + if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){ + continue; /* skip IS NOT NULL constraints on a NOT NULL column */ + } +#endif pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; pNew->nLTerm = saved_nLTerm; diff --git a/test/transitive1.test b/test/transitive1.test index ff81af6421..4cf439bb45 100644 --- a/test/transitive1.test +++ b/test/transitive1.test @@ -47,4 +47,59 @@ do_execsql_test transitive1-220 { SELECT * FROM t2 WHERE a=b AND c=b AND c<=20 ORDER BY +a; } {20 20 20 100 100 100} +# Test cases for ticket [[d805526eae253103] 2013-07-08 +# "Incorrect join result or assertion fault due to transitive constraints" +# +do_execsql_test transitive1-300 { + CREATE TABLE t301(w INTEGER PRIMARY KEY, x); + CREATE TABLE t302(y INTEGER UNIQUE, z); + INSERT INTO t301 VALUES(1,2),(3,4),(5,6); + INSERT INTO t302 VALUES(1,3),(3,6),(5,7); + SELECT * + FROM t301 CROSS JOIN t302 + WHERE w=y AND y IS NOT NULL + ORDER BY +w; +} {1 2 1 3 3 4 3 6 5 6 5 7} +do_execsql_test transitive1-301 { + SELECT * + FROM t301 CROSS JOIN t302 + WHERE w=y AND y IS NOT NULL + ORDER BY w; +} {1 2 1 3 3 4 3 6 5 6 5 7} +do_execsql_test transitive1-310 { + SELECT * + FROM t301 CROSS JOIN t302 ON w=y + WHERE y>1 + ORDER BY +w +} {3 4 3 6 5 6 5 7} +do_execsql_test transitive1-311 { + SELECT * + FROM t301 CROSS JOIN t302 ON w=y + WHERE y>1 + ORDER BY w +} {3 4 3 6 5 6 5 7} +do_execsql_test transitive1-312 { + SELECT * + FROM t301 CROSS JOIN t302 ON w=y + WHERE y>1 + ORDER BY w DESC +} {5 6 5 7 3 4 3 6} +do_execsql_test transitive1-320 { + SELECT * + FROM t301 CROSS JOIN t302 ON w=y + WHERE y BETWEEN 2 AND 4; +} {3 4 3 6} +do_execsql_test transitive1-331 { + SELECT * + FROM t301 CROSS JOIN t302 ON w=y + WHERE y BETWEEN 1 AND 4 + ORDER BY w; +} {1 2 1 3 3 4 3 6} +do_execsql_test transitive1-332 { + SELECT * + FROM t301 CROSS JOIN t302 ON w=y + WHERE y BETWEEN 1 AND 4 + ORDER BY w DESC; +} {3 4 3 6 1 2 1 3} + finish_test