Do not flatten subqueries that are part of a compound SELECT and which

have both an ORDER BY and a LIMIT clause.  Ticket #2339. (CVS 3932)

FossilOrigin-Name: 9600a998043c6dd1d5ecb03d1ee9a9273910243d
This commit is contained in:
drh
2007-05-06 20:04:24 +00:00
parent 83852acc44
commit ad91c6cd40
4 changed files with 112 additions and 9 deletions
+8 -7
View File
@@ -1,5 +1,5 @@
C Add\sthe\sstart\sof\sthe\sICU\sextension.\s(CVS\s3931)
D 2007-05-06T16:04:12
C Do\snot\sflatten\ssubqueries\sthat\sare\spart\sof\sa\scompound\sSELECT\sand\swhich\r\nhave\sboth\san\sORDER\sBY\sand\sa\sLIMIT\sclause.\s\sTicket\s#2339.\s(CVS\s3932)
D 2007-05-06T20:04:25
F Makefile.in ea8888bdcf53313d26576fcabcb6d0a10ecd35cd
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -98,7 +98,7 @@ F src/pragma.c 3f16c1274bc25afb630b61a3630ea19a2fd0b5dc
F src/prepare.c 03277063bc4f5860efbf23548fa0123ac0f6eaec
F src/printf.c 0c6f40648770831341ac45ab32423a80b4c87f05
F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
F src/select.c e6a2546de63cd9cdad2499e224f8535743b99f1a
F src/select.c a306d03fc7d8365055bef70c3563e8fca897460f
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c d07ae326b3815d80f71c69b3c7584382e47f6447
F src/sqlite.h.in a666300976897eced975b448f722a722b362c6b1
@@ -368,6 +368,7 @@ F test/tkt2213.test 8cf7c446e1fcd0627fffe7fc19046eb24ac7333b
F test/tkt2251.test 3f0549213386ed911715665a908ff2bb7a871002
F test/tkt2285.test c618085f0c13ec3347e607f83c34ada0721b4bfa
F test/tkt2332.test cb1bb0ed1ae6a3b9ff412520ed4a496745f4ffa5
F test/tkt2339.test 7016415bda86af1406a27260ac46f44885617606
F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567
F test/trans.test 3fe1b9e03b523482eee2b869858c5c1eca7b218b
F test/trigger1.test b361161cf20614024cc1e52ea0bdec250776b2ae
@@ -480,7 +481,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P 25cfa7740a0899511d9200d99c2617c45ff00f32
R 404e1ba474e37ae2a0e69793ca2f91cc
U danielk1977
Z 18a7c2474aed82907ffca52bb141507e
P f473e8526770b6a332dfde3e1fd1ddf8df493e9a
R 21e848c0f101c93214bfc30bc6b1f9ee
U drh
Z 693622110cd5648bc06ead4f26037afd
+1 -1
View File
@@ -1 +1 @@
f473e8526770b6a332dfde3e1fd1ddf8df493e9a
9600a998043c6dd1d5ecb03d1ee9a9273910243d
+8 -1
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.340 2007/05/04 13:15:56 drh Exp $
** $Id: select.c,v 1.341 2007/05/06 20:04:25 drh Exp $
*/
#include "sqliteInt.h"
@@ -2128,6 +2128,10 @@ static void substSelect(Select *p, int iTable, ExprList *pEList){
**
** (14) The subquery does not use OFFSET
**
** (15) The outer query is not part of a compound select or the
** subquery does not have both an ORDER BY and a LIMIT clause.
** (See ticket #2339)
**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
@@ -2172,6 +2176,9 @@ static int flattenSubquery(
** and (14). */
if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
if( pSub->pOffset ) return 0; /* Restriction (14) */
if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){
return 0; /* Restriction (15) */
}
if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
if( (pSub->isDistinct || pSub->pLimit)
&& (pSrc->nSrc>1 || isAgg) ){ /* Restrictions (4)(5)(8)(9) */
+95
View File
@@ -0,0 +1,95 @@
# 2007 May 6
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: tkt2339.test,v 1.1 2007/05/06 20:04:25 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test tkt2339.1 {
execsql {
create table t1(num int);
insert into t1 values (1);
insert into t1 values (2);
insert into t1 values (3);
insert into t1 values (4);
create table t2(num int);
insert into t2 values (11);
insert into t2 values (12);
insert into t2 values (13);
insert into t2 values (14);
SELECT * FROM (SELECT * FROM t1 ORDER BY num DESC LIMIT 2)
UNION
SELECT * FROM (SELECT * FROM t2 ORDER BY num DESC LIMIT 2)
}
} {3 4 13 14}
do_test tkt2339.2 {
execsql {
SELECT * FROM (SELECT * FROM t1 ORDER BY num DESC LIMIT 2)
UNION ALL
SELECT * FROM (SELECT * FROM t2 ORDER BY num DESC LIMIT 2)
}
} {4 3 14 13}
do_test tkt2339.3 {
execsql {
SELECT * FROM (SELECT * FROM t1 ORDER BY num DESC)
UNION ALL
SELECT * FROM (SELECT * FROM t2 ORDER BY num DESC LIMIT 2)
}
} {4 3 2 1 14 13}
do_test tkt2339.4 {
execsql {
SELECT * FROM (SELECT * FROM t1 ORDER BY num DESC LIMIT 2)
UNION ALL
SELECT * FROM (SELECT * FROM t2 ORDER BY num DESC)
}
} {4 3 14 13 12 11}
do_test tkt2339.5 {
execsql {
SELECT * FROM (SELECT * FROM t1 ORDER BY num DESC LIMIT 2)
UNION
SELECT * FROM (SELECT * FROM t2 ORDER BY num DESC)
}
} {3 4 11 12 13 14}
do_test tkt2339.6 {
execsql {
SELECT * FROM (SELECT * FROM t1 ORDER BY num DESC LIMIT 2)
EXCEPT
SELECT * FROM (SELECT * FROM t2 ORDER BY num DESC)
}
} {3 4}
do_test tkt2339.7 {
execsql {
SELECT * FROM (SELECT * FROM t1 LIMIT 2)
UNION
SELECT * FROM (SELECT * FROM t2 ORDER BY num DESC LIMIT 2)
}
} {1 2 13 14}
do_test tkt2339.8 {
execsql {
SELECT * FROM (SELECT * FROM t1 LIMIT 2)
UNION
SELECT * FROM (SELECT * FROM t2 LIMIT 2)
}
} {1 2 11 12}
do_test tkt2339.9 {
execsql {
SELECT * FROM (SELECT * FROM t1 ORDER BY num DESC LIMIT 2)
UNION
SELECT * FROM (SELECT * FROM t2 LIMIT 2)
}
} {3 4 11 12}
finish_test