Do not flatten the right term of a LEFT join. Ticket #3300. (CVS 5565)

FossilOrigin-Name: 8947c72f93d0b79c8061a3bfd5ab595edfb155a5
This commit is contained in:
drh 2008-08-14 00:19:48 +00:00
parent 87cf137735
commit 2b300d5d6f
4 changed files with 35 additions and 22 deletions

View File

@ -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

View File

@ -1 +1 @@
a519cdb2f46fffe16e666f161479a22463616cb3
8947c72f93d0b79c8061a3bfd5ab595edfb155a5

View File

@ -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;
}

View File

@ -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