From: drh Date: Thu, 14 Aug 2008 00:19:48 +0000 (+0000) Subject: Do not flatten the right term of a LEFT join. Ticket #3300. (CVS 5565) X-Git-Tag: version-3.6.10~612 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b300d5d6f41ec5b76c8f296b94fbbb913269ce0;p=thirdparty%2Fsqlite.git Do not flatten the right term of a LEFT join. Ticket #3300. (CVS 5565) FossilOrigin-Name: 8947c72f93d0b79c8061a3bfd5ab595edfb155a5 --- diff --git a/manifest b/manifest index 5570a858c0..e035eaedfa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Explicit\scasts\sof\sthe\sreturn\sfrom\sstrlen()\sto\sint\sin\slemon.\s\sThis\shas\nno\seffect\son\sSQLite.\s\sIt\shas\sno\seffect\son\sany\slemon-generated\sparser\nwith\sa\sgrammar\sthat\sis\sless\sthan\s2GB\sin\ssize.\s\sTicket\s#3293.\s(CVS\s5564) -D 2008-08-13T20:09:07 +C Do\snot\sflatten\sthe\sright\sterm\sof\sa\sLEFT\sjoin.\s\sTicket\s#3300.\s(CVS\s5565) +D 2008-08-14T00:19:49 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 2713ea64947be3b35f35d9a3158bb8299c90b019 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -142,7 +142,7 @@ F src/pragma.c 6e207b4f69901089758c02c02e0bf86ed12a4d8f F src/prepare.c fceb567b359daaa6c6e2a4d04a01dec01ac0c907 F src/printf.c 2e984b2507291a7e16d89dc9bb60582904f6247d F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a -F src/select.c 390d1bdde0c24f0225e369896da8e60ef2aeffbe +F src/select.c defdb8cdf7d2d8e1e0df117e50af6378fdaf1329 F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967 F src/sqlite.h.in 54e51c22e2294c5989156b0aec87aa44168ac1f0 F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e @@ -374,7 +374,7 @@ F test/ioerr2.test 5598405c48842c6c0187daad9eb49eff2c54f80d F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd F test/ioerr4.test fc6eddfec2efc2f1ed217b9eae4c1c1d3516ce86 F test/ioerr5.test fe59ee3e3d45a121bcdb8f462b718076e66b4ca7 -F test/join.test fc6c4e2132c40edb8af5ad5f0f49996825d5950d +F test/join.test e0664af757049ba1f19a0d42c470a58299f36a3e F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -618,7 +618,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 4887e8fc4af9e2963b3eff3187dee5b0d6297eb5 -R 6ddaa6c8e2519b5e2a6ee90e75b9e9c6 +P a519cdb2f46fffe16e666f161479a22463616cb3 +R 4f817c5e785c5409dbaded5f21e587f1 U drh -Z 904bb51f739e17f7654b323ec4f1ab68 +Z 3d91f3841f779b95c0adaebee822ab63 diff --git a/manifest.uuid b/manifest.uuid index 59ac21baa2..1ead3a4268 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a519cdb2f46fffe16e666f161479a22463616cb3 \ No newline at end of file +8947c72f93d0b79c8061a3bfd5ab595edfb155a5 \ No newline at end of file diff --git a/src/select.c b/src/select.c index f957c2611b..7de282e55c 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.464 2008/08/08 18:06:26 drh Exp $ +** $Id: select.c,v 1.465 2008/08/14 00:19:49 drh Exp $ */ #include "sqliteInt.h" @@ -2915,8 +2915,8 @@ static void substSelect( ** ** (2) The subquery is not an aggregate or the outer query is not a join. ** -** (3) The subquery is not the right operand of a left outer join, or -** the subquery is not itself a join. (Ticket #306) +** (3) The subquery is not the right operand of a left outer join +** (Originally ticket #306. Strenghtened by ticket #3300) ** ** (4) The subquery is not DISTINCT or the outer query is not a join. ** @@ -2938,8 +2938,8 @@ static void substSelect( ** ** (11) The subquery and the outer query do not both have ORDER BY clauses. ** -** (12) The subquery is not the right term of a LEFT OUTER JOIN or the -** subquery has no WHERE clause. (added by ticket #350) +** (12) Not implemented. Subsumed into restriction (3). Was previously +** a separate restriction deriving from ticket #350. ** ** (13) The subquery and outer query do not both use LIMIT ** @@ -3033,7 +3033,8 @@ static int flattenSubquery( } if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ - /* Restriction 3: If the subquery is a join, make sure the subquery is + /* OBSOLETE COMMENT 1: + ** Restriction 3: If the subquery is a join, make sure the subquery is ** not used as the right operand of an outer join. Examples of why this ** is not allowed: ** @@ -3044,12 +3045,9 @@ static int flattenSubquery( ** (t1 LEFT OUTER JOIN t2) JOIN t3 ** ** which is not at all the same thing. - */ - if( pSubSrc->nSrc>1 && (pSubitem->jointype & JT_OUTER)!=0 ){ - return 0; - } - - /* Restriction 12: If the subquery is the right operand of a left outer + ** + ** OBSOLETE COMMENT 2: + ** Restriction 12: If the subquery is the right operand of a left outer ** join, make sure the subquery has no WHERE clause. ** An examples of why this is not allowed: ** @@ -3061,8 +3059,13 @@ static int flattenSubquery( ** ** But the t2.x>0 test will always fail on a NULL row of t2, which ** effectively converts the OUTER JOIN into an INNER JOIN. + ** + ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE: + ** Ticket #3300 shows that flattening the right term of a LEFT JOIN + ** is fraught with danger. Best to avoid the whole thing. If the + ** subquery is the right term of a LEFT JOIN, then do not flatten. */ - if( (pSubitem->jointype & JT_OUTER)!=0 && pSub->pWhere!=0 ){ + if( (pSubitem->jointype & JT_OUTER)!=0 ){ return 0; } diff --git a/test/join.test b/test/join.test index 85512e902b..3512ce6c48 100644 --- a/test/join.test +++ b/test/join.test @@ -12,7 +12,7 @@ # # This file implements tests for joins, including outer joins. # -# $Id: join.test,v 1.24 2008/07/09 14:47:21 danielk1977 Exp $ +# $Id: join.test,v 1.25 2008/08/14 00:19:49 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -422,6 +422,16 @@ do_test join-8.3 { SELECT * FROM v10_11 LEFT JOIN t9 ON( a=x ); } } {1 111 1 11 3 333 {} {}} +ifcapable subquery { + # Constant expressions in a subquery that is the right element of a + # LEFT JOIN evaluate to NULL for rows where the LEFT JOIN does not + # match. Ticket #3300 + do_test join-8.4 { + execsql { + SELECT * FROM t9 LEFT JOIN (SELECT 44, p, q FROM t11) AS sub1 ON p=a + } + } {1 11 {} {} {} 2 22 44 2 111} +} } ;# ifcapable view # Ticket #350 describes a scenario where LEFT OUTER JOIN does not