mirror of
https://github.com/sqlite/sqlite.git
synced 2025-10-31 18:11:01 +03:00
Added the SQLITE_OMIT_SUBQUERY compile-time option and the EXISTS operator.
Regression tests are currently failing with an assertion fault. (CVS 2245) FossilOrigin-Name: d30fdf0f2c24cb74b48fab9b83fba4e4b2fe878a
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Remove\sa\sfew\smore\slines\sof\scode\swhen\sSQLITE_OMIT_**\smacros\sare\sdefined.\s(CVS\s2244)
|
C Added\sthe\sSQLITE_OMIT_SUBQUERY\scompile-time\soption\sand\sthe\sEXISTS\soperator.\nRegression\stests\sare\scurrently\sfailing\swith\san\sassertion\sfault.\s(CVS\s2245)
|
||||||
D 2005-01-20T13:03:10
|
D 2005-01-20T13:36:20
|
||||||
F Makefile.in ffd81f5e926d40b457071b4de8d7c1fa18f39b5a
|
F Makefile.in ffd81f5e926d40b457071b4de8d7c1fa18f39b5a
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
||||||
@@ -36,7 +36,7 @@ F src/cursor.c de73c00aefc4747ad59b5105cf38bbff0667922e
|
|||||||
F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f
|
F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f
|
||||||
F src/delete.c b3accca9c38d9a67dbd724f67b04151a13735ebd
|
F src/delete.c b3accca9c38d9a67dbd724f67b04151a13735ebd
|
||||||
F src/experimental.c 8cc66b2be6a011055d75ef19ed2584bcfbb585ad
|
F src/experimental.c 8cc66b2be6a011055d75ef19ed2584bcfbb585ad
|
||||||
F src/expr.c 09022cbd4fbdff66fbab0f04d010d413cb06b493
|
F src/expr.c 12b37893ab7e3a41d1d9e9a4931eeb3690951d1f
|
||||||
F src/func.c dc188d862d7276ea897655b248e2cb17022686e3
|
F src/func.c dc188d862d7276ea897655b248e2cb17022686e3
|
||||||
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
@@ -54,14 +54,14 @@ F src/os_win.c 3c0b0a3bc33318cf555a1cd130232ad1b9a5a711
|
|||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c 05d23abbcfa3133f716a99589e53883c10551b1f
|
F src/pager.c 05d23abbcfa3133f716a99589e53883c10551b1f
|
||||||
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
|
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
|
||||||
F src/parse.y 276efb30de5d8582bda9b6a98b17aac6875ab3e9
|
F src/parse.y 301d07db056f5125806e84994b5f41a8355d28ad
|
||||||
F src/pragma.c 8ab313986673aa4c45e8693d8aabb9b95ee7b14a
|
F src/pragma.c 8ab313986673aa4c45e8693d8aabb9b95ee7b14a
|
||||||
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||||
F src/select.c 1686f2503c9c7f9de4d564944584015b71c50ac3
|
F src/select.c 8a4a38310c5168d1f6e1759494e57cf838d6d37c
|
||||||
F src/shell.c 591364a0e9ca4ce53873e21e0294476c0c2b4770
|
F src/shell.c 591364a0e9ca4ce53873e21e0294476c0c2b4770
|
||||||
F src/sqlite.h.in 8249b697d71ef6d7f7f752ba4ca04058e9e8b5ff
|
F src/sqlite.h.in 8249b697d71ef6d7f7f752ba4ca04058e9e8b5ff
|
||||||
F src/sqliteInt.h c1acfbeb8b84444e5b86dfce19ff42b5854f6478
|
F src/sqliteInt.h 9a582fcb8333b5a30706250282d9697654305dbc
|
||||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
||||||
F src/tclsqlite.c fd27457b228118be96524dae285146c76efe032b
|
F src/tclsqlite.c fd27457b228118be96524dae285146c76efe032b
|
||||||
F src/test1.c 59fc0f0c35cb3bccdf166f36a1a5f9ffb0b951e7
|
F src/test1.c 59fc0f0c35cb3bccdf166f36a1a5f9ffb0b951e7
|
||||||
@@ -214,7 +214,7 @@ F tool/lempar.c 1e61d2b6cb9d8affa264a13336bc0c088498caa4
|
|||||||
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
|
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
|
||||||
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
|
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
|
||||||
F tool/memleak3.tcl b8eb053190e95a55dc188896afb972e8108822d6
|
F tool/memleak3.tcl b8eb053190e95a55dc188896afb972e8108822d6
|
||||||
F tool/mkkeywordhash.c 408dccad57ed50dc67a9a1ee7fd258e0f0a07bd2
|
F tool/mkkeywordhash.c db33613e94e9ed3fb0838e2c3ca4415c5fd7ec0e
|
||||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
|
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
|
||||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||||
F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
|
F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
|
||||||
@@ -270,7 +270,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
|
|||||||
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
|
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
|
F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746
|
||||||
P 5b1a9bf6aa5a5c466b88f649e322e81b8466851f
|
P 417bbba93ad7ed5c03d9db6afc12e170155bd152
|
||||||
R db2528b7bd532f73e60abad289bd81fd
|
R 0a5b2b3342f1338802ba7063dbaea636
|
||||||
U danielk1977
|
U drh
|
||||||
Z b2590dd052208a3aa6c3782df4f94dd4
|
Z 9bd559beb0f6f23bafe4d9cc37e5f07d
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
417bbba93ad7ed5c03d9db6afc12e170155bd152
|
d30fdf0f2c24cb74b48fab9b83fba4e4b2fe878a
|
||||||
21
src/expr.c
21
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.184 2005/01/20 13:03:10 danielk1977 Exp $
|
** $Id: expr.c,v 1.185 2005/01/20 13:36:20 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -1176,6 +1176,7 @@ struct QueryCoder {
|
|||||||
** sqlite3ExprCodeSubquery(). See comments on those routines for
|
** sqlite3ExprCodeSubquery(). See comments on those routines for
|
||||||
** additional information.
|
** additional information.
|
||||||
*/
|
*/
|
||||||
|
#ifndef SQLITE_OMIT_SUBQUERY
|
||||||
static int codeSubqueryStep(void *pArg, Expr *pExpr){
|
static int codeSubqueryStep(void *pArg, Expr *pExpr){
|
||||||
QueryCoder *pCoder = (QueryCoder*)pArg;
|
QueryCoder *pCoder = (QueryCoder*)pArg;
|
||||||
Parse *pParse = pCoder->pParse;
|
Parse *pParse = pCoder->pParse;
|
||||||
@@ -1263,6 +1264,7 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TK_EXISTS:
|
||||||
case TK_SELECT: {
|
case TK_SELECT: {
|
||||||
/* This has to be a scalar SELECT. Generate code to put the
|
/* This has to be a scalar SELECT. Generate code to put the
|
||||||
** value of this select in a memory cell and record the number
|
** value of this select in a memory cell and record the number
|
||||||
@@ -1272,6 +1274,8 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){
|
|||||||
int nRef;
|
int nRef;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
int addr;
|
int addr;
|
||||||
|
int sop;
|
||||||
|
Select *pSel;
|
||||||
|
|
||||||
pNC = pCoder->pNC;
|
pNC = pCoder->pNC;
|
||||||
if( pNC ) nRef = pNC->nRef;
|
if( pNC ) nRef = pNC->nRef;
|
||||||
@@ -1279,7 +1283,17 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
addr = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
addr = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
||||||
pExpr->iColumn = pParse->nMem++;
|
pExpr->iColumn = pParse->nMem++;
|
||||||
sqlite3Select(pParse, pExpr->pSelect, SRT_Mem,pExpr->iColumn,0,0,0,0,pNC);
|
pSel = pExpr->pSelect;
|
||||||
|
if( pExpr->op==TK_SELECT ){
|
||||||
|
sop = SRT_Mem;
|
||||||
|
}else{
|
||||||
|
static const Token one = { "1", 0, 1 };
|
||||||
|
sop = SRT_Exists;
|
||||||
|
sqlite3ExprListDelete(pSel->pEList);
|
||||||
|
pSel->pEList = sqlite3ExprListAppend(0,
|
||||||
|
sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
|
||||||
|
}
|
||||||
|
sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0, pNC);
|
||||||
if( pNC && pNC->nRef>nRef ){
|
if( pNC && pNC->nRef>nRef ){
|
||||||
/* Subquery value changes. Evaluate at each use */
|
/* Subquery value changes. Evaluate at each use */
|
||||||
pExpr->iTable = addr+1;
|
pExpr->iTable = addr+1;
|
||||||
@@ -1295,6 +1309,7 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* SQLITE_OMIT_SUBQUERY */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate code to evaluate subqueries and IN operators contained
|
** Generate code to evaluate subqueries and IN operators contained
|
||||||
@@ -1305,10 +1320,12 @@ static int sqlite3ExprCodeSubquery(
|
|||||||
NameContext *pNC, /* First enclosing namespace. Often NULL */
|
NameContext *pNC, /* First enclosing namespace. Often NULL */
|
||||||
Expr *pExpr /* Subquery to be coded */
|
Expr *pExpr /* Subquery to be coded */
|
||||||
){
|
){
|
||||||
|
#ifndef SQLITE_OMIT_SUBQUERY
|
||||||
QueryCoder sCoder;
|
QueryCoder sCoder;
|
||||||
sCoder.pParse = pParse;
|
sCoder.pParse = pParse;
|
||||||
sCoder.pNC = pNC;
|
sCoder.pNC = pNC;
|
||||||
walkExprTree(pExpr, codeSubqueryStep, &sCoder);
|
walkExprTree(pExpr, codeSubqueryStep, &sCoder);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
54
src/parse.y
54
src/parse.y
@@ -14,7 +14,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.160 2005/01/20 02:14:31 drh Exp $
|
** @(#) $Id: parse.y,v 1.161 2005/01/20 13:36:20 drh Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
@@ -418,7 +418,8 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
|
|||||||
else { sqlite3IdListDelete(U); }
|
else { sqlite3IdListDelete(U); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
|
%ifndef SQLITE_OMIT_SUBQUERY
|
||||||
|
seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
|
||||||
as(Z) on_opt(N) using_opt(U). {
|
as(Z) on_opt(N) using_opt(U). {
|
||||||
A = sqlite3SrcListAppend(X,0,0);
|
A = sqlite3SrcListAppend(X,0,0);
|
||||||
A->a[A->nSrc-1].pSelect = S;
|
A->a[A->nSrc-1].pSelect = S;
|
||||||
@@ -431,18 +432,19 @@ seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
|
|||||||
if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
|
if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
|
||||||
else { sqlite3IdListDelete(U); }
|
else { sqlite3IdListDelete(U); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A seltablist_paren nonterminal represents anything in a FROM that
|
// A seltablist_paren nonterminal represents anything in a FROM that
|
||||||
// is contained inside parentheses. This can be either a subquery or
|
// is contained inside parentheses. This can be either a subquery or
|
||||||
// a grouping of table and subqueries.
|
// a grouping of table and subqueries.
|
||||||
//
|
//
|
||||||
%type seltablist_paren {Select*}
|
%type seltablist_paren {Select*}
|
||||||
%destructor seltablist_paren {sqlite3SelectDelete($$);}
|
%destructor seltablist_paren {sqlite3SelectDelete($$);}
|
||||||
seltablist_paren(A) ::= select(S). {A = S;}
|
seltablist_paren(A) ::= select(S). {A = S;}
|
||||||
seltablist_paren(A) ::= seltablist(F). {
|
seltablist_paren(A) ::= seltablist(F). {
|
||||||
A = sqlite3SelectNew(0,F,0,0,0,0,0,-1,0);
|
A = sqlite3SelectNew(0,F,0,0,0,0,0,-1,0);
|
||||||
}
|
}
|
||||||
|
%endif // SQLITE_OMIT_SUBQUERY
|
||||||
|
|
||||||
%type dbnm {Token}
|
%type dbnm {Token}
|
||||||
dbnm(A) ::= . {A.z=0; A.n=0;}
|
dbnm(A) ::= . {A.z=0; A.n=0;}
|
||||||
@@ -692,11 +694,6 @@ expr(A) ::= PLUS(B) expr(X). [UPLUS] {
|
|||||||
A = sqlite3Expr(TK_UPLUS, X, 0, 0);
|
A = sqlite3Expr(TK_UPLUS, X, 0, 0);
|
||||||
sqlite3ExprSpan(A,&B,&X->span);
|
sqlite3ExprSpan(A,&B,&X->span);
|
||||||
}
|
}
|
||||||
expr(A) ::= LP(B) select(X) RP(E). {
|
|
||||||
A = sqlite3Expr(TK_SELECT, 0, 0, 0);
|
|
||||||
if( A ) A->pSelect = X;
|
|
||||||
sqlite3ExprSpan(A,&B,&E);
|
|
||||||
}
|
|
||||||
%type between_op {int}
|
%type between_op {int}
|
||||||
between_op(A) ::= BETWEEN. {A = 0;}
|
between_op(A) ::= BETWEEN. {A = 0;}
|
||||||
between_op(A) ::= NOT BETWEEN. {A = 1;}
|
between_op(A) ::= NOT BETWEEN. {A = 1;}
|
||||||
@@ -717,20 +714,33 @@ expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
|
|||||||
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||||
sqlite3ExprSpan(A,&X->span,&E);
|
sqlite3ExprSpan(A,&X->span,&E);
|
||||||
}
|
}
|
||||||
expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] {
|
%ifndef SQLITE_OMIT_SUBQUERY
|
||||||
|
expr(A) ::= LP(B) select(X) RP(E). {
|
||||||
|
A = sqlite3Expr(TK_SELECT, 0, 0, 0);
|
||||||
|
if( A ) A->pSelect = X;
|
||||||
|
sqlite3ExprSpan(A,&B,&E);
|
||||||
|
}
|
||||||
|
expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] {
|
||||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||||
if( A ) A->pSelect = Y;
|
if( A ) A->pSelect = Y;
|
||||||
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||||
sqlite3ExprSpan(A,&X->span,&E);
|
sqlite3ExprSpan(A,&X->span,&E);
|
||||||
}
|
}
|
||||||
expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] {
|
expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] {
|
||||||
SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z);
|
SrcList *pSrc = sqlite3SrcListAppend(0,&Y,&Z);
|
||||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||||
if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0);
|
if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0);
|
||||||
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||||
sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y);
|
sqlite3ExprSpan(A,&X->span,Z.z?&Z:&Y);
|
||||||
}
|
}
|
||||||
|
expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
|
||||||
|
Expr *p = A = sqlite3Expr(TK_EXISTS, 0, 0, 0);
|
||||||
|
if( p ){
|
||||||
|
p->pSelect = Y;
|
||||||
|
sqlite3ExprSpan(p,&B,&E);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%endif // SQLITE_OMIT_SUBQUERY
|
||||||
|
|
||||||
/* CASE expressions */
|
/* CASE expressions */
|
||||||
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
||||||
|
|||||||
13
src/select.c
13
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.230 2005/01/20 13:03:10 danielk1977 Exp $
|
** $Id: select.c,v 1.231 2005/01/20 13:36:20 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -504,6 +504,7 @@ static int selectInnerLoop(
|
|||||||
** 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 ){
|
||||||
@@ -617,6 +618,7 @@ static void generateSortTail(
|
|||||||
sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
|
sqlite3VdbeAddOp(v, OP_PutStrKey, (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);
|
||||||
@@ -2373,6 +2375,7 @@ 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 );
|
||||||
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 "
|
||||||
"a SELECT that is part of an expression");
|
"a SELECT that is part of an expression");
|
||||||
@@ -2460,6 +2463,7 @@ int sqlite3Select(
|
|||||||
|
|
||||||
/* Generate code for all sub-queries in the FROM clause
|
/* Generate code for all sub-queries in the FROM clause
|
||||||
*/
|
*/
|
||||||
|
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||||
for(i=0; i<pTabList->nSrc; i++){
|
for(i=0; i<pTabList->nSrc; i++){
|
||||||
const char *zSavedAuthContext = 0;
|
const char *zSavedAuthContext = 0;
|
||||||
int needRestoreContext;
|
int needRestoreContext;
|
||||||
@@ -2486,6 +2490,7 @@ int sqlite3Select(
|
|||||||
pHaving = p->pHaving;
|
pHaving = p->pHaving;
|
||||||
isDistinct = p->isDistinct;
|
isDistinct = p->isDistinct;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check for the special case of a min() or max() function by itself
|
/* Check for the special case of a min() or max() function by itself
|
||||||
** in the result set.
|
** in the result set.
|
||||||
@@ -2590,10 +2595,10 @@ int sqlite3Select(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the memory cell to NULL
|
/* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
|
||||||
*/
|
*/
|
||||||
if( eDest==SRT_Mem ){
|
if( eDest==SRT_Mem || eDest==SRT_Exists ){
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.358 2005/01/20 02:14:31 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.359 2005/01/20 13:36:20 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -832,6 +832,7 @@ struct Expr {
|
|||||||
#define EP_Agg 0x0002 /* Contains one or more aggregate functions */
|
#define EP_Agg 0x0002 /* Contains one or more aggregate functions */
|
||||||
#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */
|
#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */
|
||||||
#define EP_Error 0x0008 /* Expression contains one or more errors */
|
#define EP_Error 0x0008 /* Expression contains one or more errors */
|
||||||
|
#define EP_Not 0x0010 /* Operator preceeded by NOT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** These macros can be used to test, set, or clear bits in the
|
** These macros can be used to test, set, or clear bits in the
|
||||||
@@ -1016,6 +1017,7 @@ struct Select {
|
|||||||
#define SRT_Discard 9 /* Do not save the results anywhere */
|
#define SRT_Discard 9 /* Do not save the results anywhere */
|
||||||
#define SRT_Sorter 10 /* Store results in the sorter */
|
#define SRT_Sorter 10 /* Store results in the sorter */
|
||||||
#define SRT_Subroutine 11 /* Call a subroutine to handle results */
|
#define SRT_Subroutine 11 /* Call a subroutine to handle results */
|
||||||
|
#define SRT_Exists 12 /* Put 0 or 1 in a memory cell */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
|
** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
|
||||||
|
|||||||
@@ -80,20 +80,25 @@ struct Keyword {
|
|||||||
#else
|
#else
|
||||||
# define REINDEX 1024
|
# define REINDEX 1024
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQLITE_OMIT_SUBQUERY
|
||||||
|
# define SUBQUERY 0
|
||||||
|
#else
|
||||||
|
# define SUBQUERY 2048
|
||||||
|
#endif
|
||||||
#ifdef SQLITE_OMIT_TRIGGER
|
#ifdef SQLITE_OMIT_TRIGGER
|
||||||
# define TRIGGER 0
|
# define TRIGGER 0
|
||||||
#else
|
#else
|
||||||
# define TRIGGER 2048
|
# define TRIGGER 4096
|
||||||
#endif
|
#endif
|
||||||
#ifdef SQLITE_OMIT_VACUUM
|
#ifdef SQLITE_OMIT_VACUUM
|
||||||
# define VACUUM 0
|
# define VACUUM 0
|
||||||
#else
|
#else
|
||||||
# define VACUUM 4096
|
# define VACUUM 8192
|
||||||
#endif
|
#endif
|
||||||
#ifdef SQLITE_OMIT_VIEW
|
#ifdef SQLITE_OMIT_VIEW
|
||||||
# define VIEW 0
|
# define VIEW 0
|
||||||
#else
|
#else
|
||||||
# define VIEW 8192
|
# define VIEW 16384
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -146,6 +151,7 @@ static Keyword aKeywordTable[] = {
|
|||||||
{ "ESCAPE", "TK_ESCAPE", ALWAYS },
|
{ "ESCAPE", "TK_ESCAPE", ALWAYS },
|
||||||
{ "EXCEPT", "TK_EXCEPT", COMPOUND },
|
{ "EXCEPT", "TK_EXCEPT", COMPOUND },
|
||||||
{ "EXCLUSIVE", "TK_EXCLUSIVE", ALWAYS },
|
{ "EXCLUSIVE", "TK_EXCLUSIVE", ALWAYS },
|
||||||
|
{ "EXISTS", "TK_EXISTS", SUBQUERY },
|
||||||
{ "EXPLAIN", "TK_EXPLAIN", EXPLAIN },
|
{ "EXPLAIN", "TK_EXPLAIN", EXPLAIN },
|
||||||
{ "FAIL", "TK_FAIL", CONFLICT|TRIGGER },
|
{ "FAIL", "TK_FAIL", CONFLICT|TRIGGER },
|
||||||
{ "FETCH", "TK_FETCH", CURSOR },
|
{ "FETCH", "TK_FETCH", CURSOR },
|
||||||
|
|||||||
Reference in New Issue
Block a user