mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
More efficient handling of the LIMIT clause. Scalar subqueries and EXISTS
on compound SELECT statements now working properly. Ticket #1473. (CVS 2747) FossilOrigin-Name: edca8913ca012fc0c17343a27f819de95147b1bd
This commit is contained in:
23
manifest
23
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Check-in\s(2744)\sas\sincomplete\sand\sbroke\spragma\sintegrity_check.\s\sThis\ncompletes\sthe\schange\sand\sfixes\sthe\sproblem.\s(CVS\s2746)
|
C More\sefficient\shandling\sof\sthe\sLIMIT\sclause.\s\sScalar\ssubqueries\sand\sEXISTS\non\scompound\sSELECT\sstatements\snow\sworking\sproperly.\s\sTicket\s#1473.\s(CVS\s2747)
|
||||||
D 2005-10-06T13:59:27
|
D 2005-10-06T16:53:15
|
||||||
F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
|
F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
|
||||||
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -41,7 +41,7 @@ F src/complete.c 4de937dfdd4c79a501772ab2035b26082f337a79
|
|||||||
F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940
|
F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940
|
||||||
F src/delete.c 29dac493f4d83b05f91233b116827c133bcdab72
|
F src/delete.c 29dac493f4d83b05f91233b116827c133bcdab72
|
||||||
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
||||||
F src/expr.c bb2cf5d5b065eaa23d5ae2620f6de0568768147d
|
F src/expr.c 6881c8dfe363c1ee5a5dcb463b880704acb77709
|
||||||
F src/func.c f63d417248808ff2632a3b576536abffcc21d858
|
F src/func.c f63d417248808ff2632a3b576536abffcc21d858
|
||||||
F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
|
F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
@@ -64,11 +64,11 @@ F src/pragma.c 9ec219dc4ee2d4e78f4ec5c9d1422089758af13f
|
|||||||
F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4
|
F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4
|
||||||
F src/printf.c bd421c1ad5e01013c89af63c60eab02852ccd15e
|
F src/printf.c bd421c1ad5e01013c89af63c60eab02852ccd15e
|
||||||
F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
|
F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
|
||||||
F src/select.c 034c7f7447b8711f85bef578a437ea12ca7cac53
|
F src/select.c 80c95f3cebd6f7096cdcad1968316e4bb96b18b2
|
||||||
F src/shell.c 3596c1e559b82663057940d19ba533ad421c7dd3
|
F src/shell.c 3596c1e559b82663057940d19ba533ad421c7dd3
|
||||||
F src/sqlite.h.in 461b2535550cf77aedfd44385da11ef7d63e57a2
|
F src/sqlite.h.in 461b2535550cf77aedfd44385da11ef7d63e57a2
|
||||||
F src/sqliteInt.h 53daa72541b4336c5e89773cf39717ed695bd523
|
F src/sqliteInt.h c9afda257c9649aef17f9ddb67ae443b800e2bae
|
||||||
F src/table.c abc7b6946a2c2ee0603f067f8210ed004ea9a9ac
|
F src/table.c e03b60eaabaeb54a00d7e931566d77302dfc19b0
|
||||||
F src/tclsqlite.c 4f274fae3d4a1863451a553dd8e5015747a5d91d
|
F src/tclsqlite.c 4f274fae3d4a1863451a553dd8e5015747a5d91d
|
||||||
F src/test1.c 0f1a66f65a54fba029f7e93b7500d49443dc959b
|
F src/test1.c 0f1a66f65a54fba029f7e93b7500d49443dc959b
|
||||||
F src/test2.c 4196848c845626e7df894470f27329e80bfe92aa
|
F src/test2.c 4196848c845626e7df894470f27329e80bfe92aa
|
||||||
@@ -81,7 +81,7 @@ F src/update.c ac506fb7400158f826ec6c3a0dbe65e7ed3928d5
|
|||||||
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
|
||||||
F src/util.c 55caaffbb2716f9928ab452d20f3e9cbbeab872d
|
F src/util.c 55caaffbb2716f9928ab452d20f3e9cbbeab872d
|
||||||
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
|
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
|
||||||
F src/vdbe.c 3f1adcf4535dd35e4244d19d332fb6b515491c0d
|
F src/vdbe.c c9aca7cc6dc381c4ce5a59c97ac148ed0659fb3c
|
||||||
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
||||||
F src/vdbeInt.h 7bedbb9553a10e86b53f75d99e197f3f00a732bf
|
F src/vdbeInt.h 7bedbb9553a10e86b53f75d99e197f3f00a732bf
|
||||||
F src/vdbeapi.c 85bbe1d0243a89655433d60711b4bd71979b59cd
|
F src/vdbeapi.c 85bbe1d0243a89655433d60711b4bd71979b59cd
|
||||||
@@ -224,6 +224,7 @@ F test/tkt1435.test f768e5415d102fa1d8de3f548469d8fd1b79abd8
|
|||||||
F test/tkt1443.test 1e83b6a1e7f6e261682e67106ab3bc05f6c70e90
|
F test/tkt1443.test 1e83b6a1e7f6e261682e67106ab3bc05f6c70e90
|
||||||
F test/tkt1444.test 0f0fc1f277691f904dea2abece6db919dcae2351
|
F test/tkt1444.test 0f0fc1f277691f904dea2abece6db919dcae2351
|
||||||
F test/tkt1449.test f8de8a84ec12ee805ed80055e1209560f8bee4d8
|
F test/tkt1449.test f8de8a84ec12ee805ed80055e1209560f8bee4d8
|
||||||
|
F test/tkt1473.test e4637c27d606fd002de78113a8e1a142e48ffb18
|
||||||
F test/trace.test 9fd28695c463b90c2d32c387a432e01eb26e8ccf
|
F test/trace.test 9fd28695c463b90c2d32c387a432e01eb26e8ccf
|
||||||
F test/trans.test 10506dc30305cfb8c4098359f7f6f64786f69c5e
|
F test/trans.test 10506dc30305cfb8c4098359f7f6f64786f69c5e
|
||||||
F test/trigger1.test 152aed5a1fa90709fe171f2ca501a6b7f7901479
|
F test/trigger1.test 152aed5a1fa90709fe171f2ca501a6b7f7901479
|
||||||
@@ -243,7 +244,7 @@ F test/vacuum.test 5d4857ae2afc9c20d0edb8acc58bdc8d630126a9
|
|||||||
F test/vacuum2.test 5d77e98c458bcdbeecc6327de5107179ba1aa095
|
F test/vacuum2.test 5d77e98c458bcdbeecc6327de5107179ba1aa095
|
||||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||||
F test/view.test ce0f0ad39fa4a3572acffcf1e634850ee151aae0
|
F test/view.test ce0f0ad39fa4a3572acffcf1e634850ee151aae0
|
||||||
F test/where.test ce21f4910ef6a0c08f8172857baecefca20a3b0c
|
F test/where.test 752728413eab42e5854690d84c7319cdf7edc515
|
||||||
F test/where2.test 503e2e2b6abe14c5c10222e72d08ef84c1bf1ffb
|
F test/where2.test 503e2e2b6abe14c5c10222e72d08ef84c1bf1ffb
|
||||||
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||||
F tool/lemon.c c88936c67f6411608db8fa4254d254f509fa40f6
|
F tool/lemon.c c88936c67f6411608db8fa4254d254f509fa40f6
|
||||||
@@ -314,7 +315,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 9709f0f6bcb2a1ed07e678b73cb518488b8ff333
|
P 4862eaafd875eb1069076864c7cad600a76620c7
|
||||||
R 4e003316fcdb49418371e800e7deae56
|
R 24aa61823d2322d621f097e15a448b5d
|
||||||
U drh
|
U drh
|
||||||
Z 348c11fe0babe3db160a693e1bb13ff7
|
Z e25e42a04ed4277adccd254634ad3dc4
|
||||||
|
@@ -1 +1 @@
|
|||||||
4862eaafd875eb1069076864c7cad600a76620c7
|
edca8913ca012fc0c17343a27f819de95147b1bd
|
20
src/expr.c
20
src/expr.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.230 2005/09/23 21:11:54 drh Exp $
|
** $Id: expr.c,v 1.231 2005/10/06 16:53:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -1390,21 +1390,25 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||||||
** value of this select in a memory cell and record the number
|
** value of this select in a memory cell and record the number
|
||||||
** of the memory cell in iColumn.
|
** of the memory cell in iColumn.
|
||||||
*/
|
*/
|
||||||
int sop;
|
static const Token one = { "1", 0, 1 };
|
||||||
Select *pSel;
|
Select *pSel;
|
||||||
|
int iMem;
|
||||||
|
int sop;
|
||||||
|
|
||||||
pExpr->iColumn = pParse->nMem++;
|
pExpr->iColumn = iMem = pParse->nMem++;
|
||||||
pSel = pExpr->pSelect;
|
pSel = pExpr->pSelect;
|
||||||
if( pExpr->op==TK_SELECT ){
|
if( pExpr->op==TK_SELECT ){
|
||||||
sop = SRT_Mem;
|
sop = SRT_Mem;
|
||||||
|
sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0);
|
||||||
|
VdbeComment((v, "# Init subquery result"));
|
||||||
}else{
|
}else{
|
||||||
static const Token one = { "1", 0, 1 };
|
|
||||||
sop = SRT_Exists;
|
sop = SRT_Exists;
|
||||||
sqlite3ExprListDelete(pSel->pEList);
|
sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem);
|
||||||
pSel->pEList = sqlite3ExprListAppend(0,
|
VdbeComment((v, "# Init EXISTS result"));
|
||||||
sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
|
|
||||||
}
|
}
|
||||||
sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0);
|
sqlite3ExprDelete(pSel->pLimit);
|
||||||
|
pSel->pLimit = sqlite3Expr(TK_INTEGER, 0, 0, &one);
|
||||||
|
sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
98
src/select.c
98
src/select.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** to handle SELECT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: select.c,v 1.276 2005/09/20 18:13:24 drh Exp $
|
** $Id: select.c,v 1.277 2005/10/06 16:53:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -360,13 +360,12 @@ static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add code to implement the OFFSET and LIMIT
|
** Add code to implement the OFFSET
|
||||||
*/
|
*/
|
||||||
static void codeLimiter(
|
static void codeOffset(
|
||||||
Vdbe *v, /* Generate code into this VM */
|
Vdbe *v, /* Generate code into this VM */
|
||||||
Select *p, /* The SELECT statement being coded */
|
Select *p, /* The SELECT statement being coded */
|
||||||
int iContinue, /* Jump here to skip the current record */
|
int iContinue, /* Jump here to skip the current record */
|
||||||
int iBreak, /* Jump here to end the loop */
|
|
||||||
int nPop /* Number of times to pop stack when jumping */
|
int nPop /* Number of times to pop stack when jumping */
|
||||||
){
|
){
|
||||||
if( p->iOffset>=0 && iContinue!=0 ){
|
if( p->iOffset>=0 && iContinue!=0 ){
|
||||||
@@ -380,10 +379,6 @@ static void codeLimiter(
|
|||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
|
sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
|
||||||
VdbeComment((v, "# skip OFFSET records"));
|
VdbeComment((v, "# skip OFFSET records"));
|
||||||
}
|
}
|
||||||
if( p->iLimit>=0 && iBreak!=0 ){
|
|
||||||
sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
|
|
||||||
VdbeComment((v, "# exit when LIMIT reached"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -449,7 +444,7 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
|
hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
|
||||||
if( pOrderBy==0 && !hasDistinct ){
|
if( pOrderBy==0 && !hasDistinct ){
|
||||||
codeLimiter(v, p, iContinue, iBreak, 0);
|
codeOffset(v, p, iContinue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pull the requested columns.
|
/* Pull the requested columns.
|
||||||
@@ -471,7 +466,7 @@ static int selectInnerLoop(
|
|||||||
int n = pEList->nExpr;
|
int n = pEList->nExpr;
|
||||||
codeDistinct(v, distinct, iContinue, n, n+1);
|
codeDistinct(v, distinct, iContinue, n, n+1);
|
||||||
if( pOrderBy==0 ){
|
if( pOrderBy==0 ){
|
||||||
codeLimiter(v, p, iContinue, iBreak, nColumn);
|
codeOffset(v, p, iContinue, nColumn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,18 +542,26 @@ static int selectInnerLoop(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If any row exists in the result set, record that fact and abort.
|
||||||
|
*/
|
||||||
|
case SRT_Exists: {
|
||||||
|
sqlite3VdbeAddOp(v, OP_MemInt, 1, iParm);
|
||||||
|
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||||
|
/* The LIMIT clause will terminate the loop for us */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* If this is a scalar select that is part of an expression, then
|
/* If this is a scalar select that is part of an expression, then
|
||||||
** store the results in the appropriate memory cell and break out
|
** store the results in the appropriate memory cell and break out
|
||||||
** of the scan loop.
|
** of the scan loop.
|
||||||
*/
|
*/
|
||||||
case SRT_Exists:
|
|
||||||
case SRT_Mem: {
|
case SRT_Mem: {
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
pushOntoSorter(pParse, v, pOrderBy);
|
pushOntoSorter(pParse, v, pOrderBy);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBreak);
|
/* The LIMIT clause will jump out of the loop for us */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -594,6 +597,13 @@ static int selectInnerLoop(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Jump to the end of the loop if the LIMIT is reached.
|
||||||
|
*/
|
||||||
|
if( p->iLimit>=0 && pOrderBy==0 ){
|
||||||
|
sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, 0);
|
||||||
|
sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, iBreak);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +671,7 @@ static void generateSortTail(
|
|||||||
|
|
||||||
iTab = pOrderBy->iECursor;
|
iTab = pOrderBy->iECursor;
|
||||||
addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk);
|
addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk);
|
||||||
codeLimiter(v, p, cont, brk, 0);
|
codeOffset(v, p, cont, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1);
|
sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1);
|
||||||
switch( eDest ){
|
switch( eDest ){
|
||||||
case SRT_Table:
|
case SRT_Table:
|
||||||
@@ -681,11 +691,10 @@ static void generateSortTail(
|
|||||||
sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
|
sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SRT_Exists:
|
|
||||||
case SRT_Mem: {
|
case SRT_Mem: {
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
||||||
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
/* The LIMIT clause will terminate the loop for us */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -710,6 +719,16 @@ static void generateSortTail(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Jump to the end of the loop when the LIMIT is reached
|
||||||
|
*/
|
||||||
|
if( p->iLimit>=0 ){
|
||||||
|
sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, 0);
|
||||||
|
sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, brk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The bottom of the loop
|
||||||
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, cont);
|
sqlite3VdbeResolveLabel(v, cont);
|
||||||
sqlite3VdbeAddOp(v, OP_Next, iTab, addr);
|
sqlite3VdbeAddOp(v, OP_Next, iTab, addr);
|
||||||
sqlite3VdbeResolveLabel(v, brk);
|
sqlite3VdbeResolveLabel(v, brk);
|
||||||
@@ -1328,7 +1347,7 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Compute the iLimit and iOffset fields of the SELECT based on the
|
** Compute the iLimit and iOffset fields of the SELECT based on the
|
||||||
** pLimit and pOffset expressions. nLimit and nOffset hold the expressions
|
** pLimit and pOffset expressions. pLimit and pOffset hold the expressions
|
||||||
** that appear in the original SQL statement after the LIMIT and OFFSET
|
** that appear in the original SQL statement after the LIMIT and OFFSET
|
||||||
** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
|
** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
|
||||||
** are the integer memory register numbers for counters used to compute
|
** are the integer memory register numbers for counters used to compute
|
||||||
@@ -1336,15 +1355,15 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){
|
|||||||
** iLimit and iOffset are negative.
|
** iLimit and iOffset are negative.
|
||||||
**
|
**
|
||||||
** This routine changes the values if iLimit and iOffset only if
|
** This routine changes the values if iLimit and iOffset only if
|
||||||
** a limit or offset is defined by nLimit and nOffset. iLimit and
|
** a limit or offset is defined by pLimit and pOffset. iLimit and
|
||||||
** iOffset should have been preset to appropriate default values
|
** iOffset should have been preset to appropriate default values
|
||||||
** (usually but not always -1) prior to calling this routine.
|
** (usually but not always -1) prior to calling this routine.
|
||||||
** Only if nLimit>=0 or nOffset>0 do the limit registers get
|
** Only if pLimit!=0 or pOffset!=0 do the limit registers get
|
||||||
** redefined. The UNION ALL operator uses this property to force
|
** redefined. The UNION ALL operator uses this property to force
|
||||||
** the reuse of the same limit and offset registers across multiple
|
** the reuse of the same limit and offset registers across multiple
|
||||||
** SELECT statements.
|
** SELECT statements.
|
||||||
*/
|
*/
|
||||||
static void computeLimitRegisters(Parse *pParse, Select *p){
|
static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
||||||
/*
|
/*
|
||||||
** "LIMIT -1" always shows all rows. There is some
|
** "LIMIT -1" always shows all rows. There is some
|
||||||
** contraversy about what the correct behavior should be.
|
** contraversy about what the correct behavior should be.
|
||||||
@@ -1360,6 +1379,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p){
|
|||||||
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
|
||||||
VdbeComment((v, "# LIMIT counter"));
|
VdbeComment((v, "# LIMIT counter"));
|
||||||
|
sqlite3VdbeAddOp(v, OP_IfMemZero, iMem, iBreak);
|
||||||
p->iLimit = iMem;
|
p->iLimit = iMem;
|
||||||
}
|
}
|
||||||
if( p->pOffset ){
|
if( p->pOffset ){
|
||||||
@@ -1519,6 +1539,7 @@ static int multiSelect(
|
|||||||
switch( p->op ){
|
switch( p->op ){
|
||||||
case TK_ALL: {
|
case TK_ALL: {
|
||||||
if( pOrderBy==0 ){
|
if( pOrderBy==0 ){
|
||||||
|
int addr = 0;
|
||||||
assert( !pPrior->pLimit );
|
assert( !pPrior->pLimit );
|
||||||
pPrior->pLimit = p->pLimit;
|
pPrior->pLimit = p->pLimit;
|
||||||
pPrior->pOffset = p->pOffset;
|
pPrior->pOffset = p->pOffset;
|
||||||
@@ -1531,11 +1552,18 @@ static int multiSelect(
|
|||||||
p->iOffset = pPrior->iOffset;
|
p->iOffset = pPrior->iOffset;
|
||||||
p->pLimit = 0;
|
p->pLimit = 0;
|
||||||
p->pOffset = 0;
|
p->pOffset = 0;
|
||||||
|
if( p->iLimit>=0 ){
|
||||||
|
addr = sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, 0);
|
||||||
|
VdbeComment((v, "# Jump ahead if LIMIT reached"));
|
||||||
|
}
|
||||||
rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
|
rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
|
||||||
p->pPrior = pPrior;
|
p->pPrior = pPrior;
|
||||||
if( rc ){
|
if( rc ){
|
||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
|
if( addr ){
|
||||||
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* For UNION ALL ... ORDER BY fall through to the next case */
|
/* For UNION ALL ... ORDER BY fall through to the next case */
|
||||||
@@ -1622,8 +1650,8 @@ static int multiSelect(
|
|||||||
}
|
}
|
||||||
iBreak = sqlite3VdbeMakeLabel(v);
|
iBreak = sqlite3VdbeMakeLabel(v);
|
||||||
iCont = sqlite3VdbeMakeLabel(v);
|
iCont = sqlite3VdbeMakeLabel(v);
|
||||||
|
computeLimitRegisters(pParse, p, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
|
sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
|
||||||
computeLimitRegisters(pParse, p);
|
|
||||||
iStart = sqlite3VdbeCurrentAddr(v);
|
iStart = sqlite3VdbeCurrentAddr(v);
|
||||||
rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
|
rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
|
||||||
pOrderBy, -1, eDest, iParm,
|
pOrderBy, -1, eDest, iParm,
|
||||||
@@ -1698,8 +1726,8 @@ static int multiSelect(
|
|||||||
}
|
}
|
||||||
iBreak = sqlite3VdbeMakeLabel(v);
|
iBreak = sqlite3VdbeMakeLabel(v);
|
||||||
iCont = sqlite3VdbeMakeLabel(v);
|
iCont = sqlite3VdbeMakeLabel(v);
|
||||||
|
computeLimitRegisters(pParse, p, iBreak);
|
||||||
sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
|
sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
|
||||||
computeLimitRegisters(pParse, p);
|
|
||||||
iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0);
|
iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
|
sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
|
||||||
rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
|
rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
|
||||||
@@ -2166,10 +2194,10 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
int base;
|
int base;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
int seekOp;
|
int seekOp;
|
||||||
int cont;
|
|
||||||
ExprList *pEList, *pList, eList;
|
ExprList *pEList, *pList, eList;
|
||||||
struct ExprList_item eListItem;
|
struct ExprList_item eListItem;
|
||||||
SrcList *pSrc;
|
SrcList *pSrc;
|
||||||
|
int brk;
|
||||||
|
|
||||||
/* Check to see if this query is a simple min() or max() query. Return
|
/* Check to see if this query is a simple min() or max() query. Return
|
||||||
** zero if it is not.
|
** zero if it is not.
|
||||||
@@ -2233,11 +2261,11 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
*/
|
*/
|
||||||
sqlite3CodeVerifySchema(pParse, pTab->iDb);
|
sqlite3CodeVerifySchema(pParse, pTab->iDb);
|
||||||
base = pSrc->a[0].iCursor;
|
base = pSrc->a[0].iCursor;
|
||||||
computeLimitRegisters(pParse, p);
|
brk = sqlite3VdbeMakeLabel(v);
|
||||||
|
computeLimitRegisters(pParse, p, brk);
|
||||||
if( pSrc->a[0].pSelect==0 ){
|
if( pSrc->a[0].pSelect==0 ){
|
||||||
sqlite3OpenTableForReading(v, base, pTab);
|
sqlite3OpenTableForReading(v, base, pTab);
|
||||||
}
|
}
|
||||||
cont = sqlite3VdbeMakeLabel(v);
|
|
||||||
if( pIdx==0 ){
|
if( pIdx==0 ){
|
||||||
sqlite3VdbeAddOp(v, seekOp, base, 0);
|
sqlite3VdbeAddOp(v, seekOp, base, 0);
|
||||||
}else{
|
}else{
|
||||||
@@ -2266,8 +2294,8 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
memset(&eListItem, 0, sizeof(eListItem));
|
memset(&eListItem, 0, sizeof(eListItem));
|
||||||
eList.a = &eListItem;
|
eList.a = &eListItem;
|
||||||
eList.a[0].pExpr = pExpr;
|
eList.a[0].pExpr = pExpr;
|
||||||
selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont, 0);
|
selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, brk, brk, 0);
|
||||||
sqlite3VdbeResolveLabel(v, cont);
|
sqlite3VdbeResolveLabel(v, brk);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2615,6 +2643,7 @@ int sqlite3Select(
|
|||||||
int rc = 1; /* Value to return from this function */
|
int rc = 1; /* Value to return from this function */
|
||||||
int addrSortIndex; /* Address of an OP_OpenVirtual instruction */
|
int addrSortIndex; /* Address of an OP_OpenVirtual instruction */
|
||||||
AggInfo sAggInfo; /* Information used by aggregate queries */
|
AggInfo sAggInfo; /* Information used by aggregate queries */
|
||||||
|
int iEnd; /* Address of the end of the query */
|
||||||
|
|
||||||
if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1;
|
if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1;
|
||||||
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
||||||
@@ -2663,7 +2692,6 @@ int sqlite3Select(
|
|||||||
/* If writing to memory or generating a set
|
/* If writing to memory or generating a set
|
||||||
** only a single column may be output.
|
** only a single column may be output.
|
||||||
*/
|
*/
|
||||||
assert( eDest!=SRT_Exists || pEList->nExpr==1 );
|
|
||||||
#ifndef SQLITE_OMIT_SUBQUERY
|
#ifndef SQLITE_OMIT_SUBQUERY
|
||||||
if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
|
if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
|
||||||
sqlite3ErrorMsg(pParse, "only a single result allowed for "
|
sqlite3ErrorMsg(pParse, "only a single result allowed for "
|
||||||
@@ -2772,7 +2800,8 @@ int sqlite3Select(
|
|||||||
|
|
||||||
/* Set the limiter.
|
/* Set the limiter.
|
||||||
*/
|
*/
|
||||||
computeLimitRegisters(pParse, p);
|
iEnd = sqlite3VdbeMakeLabel(v);
|
||||||
|
computeLimitRegisters(pParse, p, iEnd);
|
||||||
|
|
||||||
/* If the output is destined for a temporary table, open that table.
|
/* If the output is destined for a temporary table, open that table.
|
||||||
*/
|
*/
|
||||||
@@ -2780,15 +2809,6 @@ int sqlite3Select(
|
|||||||
sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, pEList->nExpr);
|
sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, pEList->nExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
|
|
||||||
*/
|
|
||||||
if( eDest==SRT_Mem ){
|
|
||||||
sqlite3VdbeAddOp(v, OP_MemNull, iParm, 0);
|
|
||||||
}else if( eDest==SRT_Exists ){
|
|
||||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iParm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open a virtual index to use for the distinct set.
|
/* Open a virtual index to use for the distinct set.
|
||||||
*/
|
*/
|
||||||
if( isDistinct ){
|
if( isDistinct ){
|
||||||
@@ -3112,6 +3132,10 @@ int sqlite3Select(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Jump here to skip this query
|
||||||
|
*/
|
||||||
|
sqlite3VdbeResolveLabel(v, iEnd);
|
||||||
|
|
||||||
/* The SELECT was successfully coded. Set the return code to 0
|
/* The SELECT was successfully coded. Set the return code to 0
|
||||||
** to indicate no errors.
|
** to indicate no errors.
|
||||||
*/
|
*/
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.421 2005/09/19 21:05:49 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.422 2005/10/06 16:53:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -1149,7 +1149,7 @@ struct Select {
|
|||||||
#define SRT_Table 7 /* Store result as data with an automatic rowid */
|
#define SRT_Table 7 /* Store result as data with an automatic rowid */
|
||||||
#define SRT_VirtualTab 8 /* Create virtual table and store like SRT_Table */
|
#define SRT_VirtualTab 8 /* Create virtual table and store like SRT_Table */
|
||||||
#define SRT_Subroutine 9 /* Call a subroutine to handle results */
|
#define SRT_Subroutine 9 /* Call a subroutine to handle results */
|
||||||
#define SRT_Exists 10 /* Put 0 or 1 in a memory cell */
|
#define SRT_Exists 10 /* Store 1 if the result is not empty */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An SQL parser context. A copy of this structure is passed through
|
** An SQL parser context. A copy of this structure is passed through
|
||||||
|
@@ -196,4 +196,4 @@ void sqlite3_free_table(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif SQLITE_OMIT_GET_TABLE
|
#endif /* SQLITE_OMIT_GET_TABLE */
|
||||||
|
29
src/vdbe.c
29
src/vdbe.c
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.491 2005/09/20 17:42:23 drh Exp $
|
** $Id: vdbe.c,v 1.492 2005/10/06 16:53:16 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -4141,7 +4141,7 @@ case OP_MemMax: { /* no-push */
|
|||||||
/* Opcode: MemIncr P1 P2 *
|
/* Opcode: MemIncr P1 P2 *
|
||||||
**
|
**
|
||||||
** Increment the integer valued memory cell P1 by 1. If P2 is not zero
|
** Increment the integer valued memory cell P1 by 1. If P2 is not zero
|
||||||
** and the result after the increment is exactly 1, then jump
|
** and the result after the increment is exactly 0, then jump
|
||||||
** to P2.
|
** to P2.
|
||||||
**
|
**
|
||||||
** This instruction throws an error if the memory cell is not initially
|
** This instruction throws an error if the memory cell is not initially
|
||||||
@@ -4154,7 +4154,7 @@ case OP_MemIncr: { /* no-push */
|
|||||||
pMem = &p->aMem[i];
|
pMem = &p->aMem[i];
|
||||||
assert( pMem->flags==MEM_Int );
|
assert( pMem->flags==MEM_Int );
|
||||||
pMem->i++;
|
pMem->i++;
|
||||||
if( pOp->p2>0 && pMem->i==1 ){
|
if( pOp->p2>0 && pMem->i==0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4162,16 +4162,31 @@ case OP_MemIncr: { /* no-push */
|
|||||||
|
|
||||||
/* Opcode: IfMemPos P1 P2 *
|
/* Opcode: IfMemPos P1 P2 *
|
||||||
**
|
**
|
||||||
** If the value of memory cell P1 is 1 or greater, jump to P2. This
|
** If the value of memory cell P1 is 1 or greater, jump to P2. If
|
||||||
** opcode assumes that memory cell P1 holds an integer value.
|
** the memory cell holds an integer of 0 or less or if it holds something
|
||||||
|
** that is not an integer, then fall thru.
|
||||||
*/
|
*/
|
||||||
case OP_IfMemPos: { /* no-push */
|
case OP_IfMemPos: { /* no-push */
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Mem *pMem;
|
Mem *pMem;
|
||||||
assert( i>=0 && i<p->nMem );
|
assert( i>=0 && i<p->nMem );
|
||||||
pMem = &p->aMem[i];
|
pMem = &p->aMem[i];
|
||||||
assert( pMem->flags==MEM_Int );
|
if( pMem->flags==MEM_Int && pMem->i>0 ){
|
||||||
if( pMem->i>0 ){
|
pc = pOp->p2 - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Opcode: IfMemZero P1 P2 *
|
||||||
|
**
|
||||||
|
** If the value of memory cell P1 is exactly 0, jump to P2.
|
||||||
|
*/
|
||||||
|
case OP_IfMemZero: { /* no-push */
|
||||||
|
int i = pOp->p1;
|
||||||
|
Mem *pMem;
|
||||||
|
assert( i>=0 && i<p->nMem );
|
||||||
|
pMem = &p->aMem[i];
|
||||||
|
if( pMem->flags==MEM_Int && pMem->i==0 ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
716
test/tkt1473.test
Normal file
716
test/tkt1473.test
Normal file
@@ -0,0 +1,716 @@
|
|||||||
|
# 2005 September 19
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library.
|
||||||
|
#
|
||||||
|
# This file implements tests to verify that ticket #1473 has been
|
||||||
|
# fixed.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
do_test tkt1473-1.1 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t1(a,b);
|
||||||
|
INSERT INTO t1 VALUES(1,2);
|
||||||
|
INSERT INTO t1 VALUES(3,4);
|
||||||
|
SELECT * FROM t1
|
||||||
|
}
|
||||||
|
} {1 2 3 4}
|
||||||
|
|
||||||
|
do_test tkt1473-1.2 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=0
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-1.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=0
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-1.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=4
|
||||||
|
}
|
||||||
|
} {1 2}
|
||||||
|
do_test tkt1473-1.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=4
|
||||||
|
}
|
||||||
|
} {1 2}
|
||||||
|
do_test tkt1473-1.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=4
|
||||||
|
}
|
||||||
|
} {2}
|
||||||
|
do_test tkt1473-1.7 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=0 UNION SELECT 2 FROM t1 WHERE b=4
|
||||||
|
}
|
||||||
|
} {2}
|
||||||
|
do_test tkt1473-1.8 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=0
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
do_test tkt1473-1.9 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t1 WHERE a=0 UNION SELECT 2 FROM t1 WHERE b=0
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_test tkt1473-2.2 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-2.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-2.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-2.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-2.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {2}
|
||||||
|
do_test tkt1473-2.7 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=0 UNION SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {2}
|
||||||
|
do_test tkt1473-2.8 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {{}}
|
||||||
|
do_test tkt1473-2.9 {
|
||||||
|
execsql {
|
||||||
|
SELECT (SELECT 1 FROM t1 WHERE a=0 UNION SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {{}}
|
||||||
|
|
||||||
|
do_test tkt1473-3.2 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-3.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-3.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-3.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-3.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-3.7 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=0 UNION SELECT 2 FROM t1 WHERE b=4)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-3.8 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
do_test tkt1473-3.9 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS
|
||||||
|
(SELECT 1 FROM t1 WHERE a=0 UNION SELECT 2 FROM t1 WHERE b=0)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
do_test tkt1473-4.1 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE t2(x,y);
|
||||||
|
INSERT INTO t2 VALUES(1,2);
|
||||||
|
INSERT INTO t2 SELECT x+2, y+2 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT x+4, y+4 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT x+8, y+8 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT x+16, y+16 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT x+32, y+32 FROM t2;
|
||||||
|
INSERT INTO t2 SELECT x+64, y+64 FROM t2;
|
||||||
|
SELECT count(*), sum(x), sum(y) FROM t2;
|
||||||
|
}
|
||||||
|
} {64 4096 4160}
|
||||||
|
do_test tkt1473-4.2 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
}
|
||||||
|
} {2 4 8 10}
|
||||||
|
do_test tkt1473-4.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {2}
|
||||||
|
do_test tkt1473-4.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {4}
|
||||||
|
do_test tkt1473-4.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=-4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {8}
|
||||||
|
do_test tkt1473-4.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {10}
|
||||||
|
do_test tkt1473-4.7 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=-4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {{}}
|
||||||
|
|
||||||
|
do_test tkt1473-5.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-5.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_test tkt1473-5.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=-4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-5.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-5.7 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION ALL
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION ALL
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION ALL
|
||||||
|
SELECT 10 FROM t2 WHERE y=-4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
do_test tkt1473-6.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION
|
||||||
|
SELECT 2 FROM t2 WHERE x=1
|
||||||
|
UNION
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION
|
||||||
|
SELECT 4 FROM t2 WHERE x=3
|
||||||
|
UNION
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-6.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION
|
||||||
|
SELECT 4 FROM t2 WHERE x=3
|
||||||
|
UNION
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
do_test tkt1473-6.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION
|
||||||
|
SELECT 4 FROM t2 WHERE x=-1
|
||||||
|
UNION
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION
|
||||||
|
SELECT 8 FROM t2 WHERE y=2
|
||||||
|
UNION
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION
|
||||||
|
SELECT 10 FROM t2 WHERE y=-4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-6.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-6.7 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION
|
||||||
|
SELECT 10 FROM t2 WHERE y=-4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
do_test tkt1473-6.8 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION
|
||||||
|
SELECT 10 FROM t2 WHERE y=4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-6.9 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0
|
||||||
|
UNION
|
||||||
|
SELECT 2 FROM t2 WHERE x=-1
|
||||||
|
UNION
|
||||||
|
SELECT 3 FROM t2 WHERE x=2
|
||||||
|
UNION
|
||||||
|
SELECT 4 FROM t2 WHERE x=-2
|
||||||
|
UNION
|
||||||
|
SELECT 5 FROM t2 WHERE x=4
|
||||||
|
UNION ALL
|
||||||
|
SELECT 6 FROM t2 WHERE y=0
|
||||||
|
UNION
|
||||||
|
SELECT 7 FROM t2 WHERE y=1
|
||||||
|
UNION
|
||||||
|
SELECT 8 FROM t2 WHERE y=-3
|
||||||
|
UNION
|
||||||
|
SELECT 9 FROM t2 WHERE y=3
|
||||||
|
UNION
|
||||||
|
SELECT 10 FROM t2 WHERE y=-4
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
do_test tkt1473-7.1 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 EXCEPT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-7.2 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 EXCEPT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-7.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 EXCEPT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-7.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0 EXCEPT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {{}}
|
||||||
|
do_test tkt1473-7.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0 EXCEPT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
do_test tkt1473-8.1 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 INTERSECT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
do_test tkt1473-8.1 {
|
||||||
|
execsql {
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 INTERSECT SELECT 1 FROM t2 WHERE y=2
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-8.3 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 INTERSECT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {{}}
|
||||||
|
do_test tkt1473-8.4 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 INTERSECT SELECT 1 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-8.5 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 INTERSECT SELECT 2 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
do_test tkt1473-8.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 INTERSECT SELECT 1 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {1}
|
||||||
|
do_test tkt1473-8.7 {
|
||||||
|
execsql {
|
||||||
|
SELECT (
|
||||||
|
SELECT 1 FROM t2 WHERE x=0 INTERSECT SELECT 1 FROM t2 WHERE y=2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {{}}
|
||||||
|
do_test tkt1473-8.8 {
|
||||||
|
execsql {
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT 1 FROM t2 WHERE x=1 INTERSECT SELECT 1 FROM t2 WHERE y=0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the use of indices in WHERE clases.
|
# focus of this file is testing the use of indices in WHERE clases.
|
||||||
#
|
#
|
||||||
# $Id: where.test,v 1.36 2005/09/08 10:37:02 drh Exp $
|
# $Id: where.test,v 1.37 2005/10/06 16:53:17 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -306,7 +306,7 @@ do_test where-4.2 {
|
|||||||
count {
|
count {
|
||||||
SELECT * FROM t1 WHERE 1 LIMIT 1
|
SELECT * FROM t1 WHERE 1 LIMIT 1
|
||||||
}
|
}
|
||||||
} {1 0 4 1}
|
} {1 0 4 0}
|
||||||
do_test where-4.3 {
|
do_test where-4.3 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT 99 WHERE 0
|
SELECT 99 WHERE 0
|
||||||
|
Reference in New Issue
Block a user