From: dan Date: Tue, 24 Apr 2018 18:53:24 +0000 (+0000) Subject: Fix a problem with processing "LEFT JOIN tbl ON tbl.a = ? AND (tbl.b=? OR X-Git-Tag: version-3.24.0~98 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=820fcd2ce9379d3ee4619016c53f450b6422332b;p=thirdparty%2Fsqlite.git Fix a problem with processing "LEFT JOIN tbl ON tbl.a = ? AND (tbl.b=? OR tbl.c=?)" in cases where there are indexes on both tbl(a, b) and tbl(a, c). FossilOrigin-Name: ce35e39c5cc2b00dd6b4a9ffaa9d5eb7d9b862759e87d5f053729de7643eee9c --- diff --git a/manifest b/manifest index 4754d46a07..425acebba3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sto\suse\sterms\sfrom\sthe\sWHERE\sclause\sto\sdrive\sindexes\son\sthe\nright\stable\sof\sa\sLEFT\sJOIN.\s\sFix\sfor\sticket\s[4ba5abf65c5b0f9a96a7a40cd18b] -D 2018-04-24T17:34:03.981 +C Fix\sa\sproblem\swith\sprocessing\s"LEFT\sJOIN\stbl\sON\stbl.a\s=\s?\sAND\s(tbl.b=?\sOR\ntbl.c=?)"\sin\scases\swhere\sthere\sare\sindexes\son\sboth\stbl(a,\sb)\sand\stbl(a,\sc). +D 2018-04-24T18:53:24.943 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439 @@ -578,7 +578,7 @@ F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f F src/where.c 7a1c5555c00bcf49c677472ae83bb49bf24c8d8e9a060d475e86dee39be2fb3a F src/whereInt.h 2610cb87dd95509995b63decc674c60f2757697a206cfe0c085ee53d9c43cfff -F src/wherecode.c 52225f6b519c7742a593341a13308d8fd08af7f91af0fa765c6adad85978d525 +F src/wherecode.c 3cb591fe7323e1bfd49059d75fcab75e383dfcf16a51c0e4f9368ac1b93e291b F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1011,7 +1011,7 @@ F test/join.test 2ad9d7fe10e0cc06bc7803c22e5533be11cdadbc592f5f95d789a873b57a5a6 F test/join2.test f5ea0fd3b0a441c8e439706339dcd17cec63a896a755c04a30bfd442ecce1190 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 -F test/join5.test cb052e7126fe3492dce2e851b980b487a823a0a4cb2ce2d773c92f14a453dad7 +F test/join5.test 000a18e9ccc9fc716e550eb2337729d3aee99031d0ddd9682f6b7d73aa99b924 F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 @@ -1725,7 +1725,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8acb42f48929d908fe67a8536e240ca252a9ab780dce79eaa85b8fba35d52250 -R 4eebdb5072e10414126cf7987af3576c -U drh -Z 0f34fac3f1b4f07abfd291b9539f090e +P aeb694e3f787f1f8b55650c17f90c197eee3f7f9b890a88f458c33e43009a082 +R 56c49ae18195fa15548a505c9f447aff +U dan +Z 3395e9aff5f6302e6b05ef897c94003f diff --git a/manifest.uuid b/manifest.uuid index 93572b4b4f..728dc6f2e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aeb694e3f787f1f8b55650c17f90c197eee3f7f9b890a88f458c33e43009a082 \ No newline at end of file +ce35e39c5cc2b00dd6b4a9ffaa9d5eb7d9b862759e87d5f053729de7643eee9c \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 3432d4b6b1..818a7a208b 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1215,6 +1215,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ + assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) + || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0 + ); if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); @@ -1913,7 +1916,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( for(iTerm=0; iTermnTerm; iTerm++){ Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; - if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; @@ -1938,7 +1940,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( WhereInfo *pSubWInfo; /* Info for single OR-term scan */ Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ int jmp1 = 0; /* Address of jump operation */ - if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ + assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 + || ExprHasProperty(pOrExpr, EP_FromJoin) + ); + if( pAndExpr ){ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; } @@ -2121,7 +2126,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } pE = pTerm->pExpr; assert( pE!=0 ); - if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ + if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){ continue; } diff --git a/test/join5.test b/test/join5.test index 9e994cede5..12fe56cb92 100644 --- a/test/join5.test +++ b/test/join5.test @@ -241,5 +241,53 @@ do_execsql_test 6.3.2 { SELECT ifnull(z, '!!!') FROM t3 LEFT JOIN t4 ON (x=y); } {!!!} +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1); +} + +do_execsql_test 7.1 { + CREATE TABLE t2(x, y, z); + CREATE INDEX t2xy ON t2(x, y); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000 + ) + INSERT INTO t2 SELECT i/10, i, NULL FROM s; + ANALYZE; +} + +do_eqp_test 7.2 { + SELECT * FROM t1 LEFT JOIN t2 ON ( + t2.x = t1.x AND (t2.y=? OR (t2.y=? AND t2.z IS NOT NULL)) + ); +} { + 0 0 0 {SCAN TABLE t1} + 0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)} + 0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)} +} + +do_execsql_test 7.3 { + CREATE TABLE t3(x); + + CREATE TABLE t4(x, y, z); + CREATE INDEX t4xy ON t4(x, y); + CREATE INDEX t4xz ON t4(x, z); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000) + INSERT INTO t4 SELECT i/10, i, i FROM s; + + ANALYZE; +} + +do_eqp_test 7.4 { + SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?); +} { + 0 0 0 {SCAN TABLE t3} + 0 1 1 {SEARCH TABLE t4 USING INDEX t4xz (x=?)} +} + finish_test