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) | ||||
| D 2005-01-20T13:03:10 | ||||
| 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:36:20 | ||||
| F Makefile.in ffd81f5e926d40b457071b4de8d7c1fa18f39b5a | ||||
| F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 | ||||
| F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 | ||||
| @@ -36,7 +36,7 @@ F src/cursor.c de73c00aefc4747ad59b5105cf38bbff0667922e | ||||
| F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f | ||||
| F src/delete.c b3accca9c38d9a67dbd724f67b04151a13735ebd | ||||
| F src/experimental.c 8cc66b2be6a011055d75ef19ed2584bcfbb585ad | ||||
| F src/expr.c 09022cbd4fbdff66fbab0f04d010d413cb06b493 | ||||
| F src/expr.c 12b37893ab7e3a41d1d9e9a4931eeb3690951d1f | ||||
| F src/func.c dc188d862d7276ea897655b248e2cb17022686e3 | ||||
| F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5 | ||||
| F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 | ||||
| @@ -54,14 +54,14 @@ F src/os_win.c 3c0b0a3bc33318cf555a1cd130232ad1b9a5a711 | ||||
| F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b | ||||
| F src/pager.c 05d23abbcfa3133f716a99589e53883c10551b1f | ||||
| F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862 | ||||
| F src/parse.y 276efb30de5d8582bda9b6a98b17aac6875ab3e9 | ||||
| F src/parse.y 301d07db056f5125806e84994b5f41a8355d28ad | ||||
| F src/pragma.c 8ab313986673aa4c45e8693d8aabb9b95ee7b14a | ||||
| F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357 | ||||
| F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 | ||||
| F src/select.c 1686f2503c9c7f9de4d564944584015b71c50ac3 | ||||
| F src/select.c 8a4a38310c5168d1f6e1759494e57cf838d6d37c | ||||
| F src/shell.c 591364a0e9ca4ce53873e21e0294476c0c2b4770 | ||||
| F src/sqlite.h.in 8249b697d71ef6d7f7f752ba4ca04058e9e8b5ff | ||||
| F src/sqliteInt.h c1acfbeb8b84444e5b86dfce19ff42b5854f6478 | ||||
| F src/sqliteInt.h 9a582fcb8333b5a30706250282d9697654305dbc | ||||
| F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 | ||||
| F src/tclsqlite.c fd27457b228118be96524dae285146c76efe032b | ||||
| F src/test1.c 59fc0f0c35cb3bccdf166f36a1a5f9ffb0b951e7 | ||||
| @@ -214,7 +214,7 @@ F tool/lempar.c 1e61d2b6cb9d8affa264a13336bc0c088498caa4 | ||||
| F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133 | ||||
| F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 | ||||
| F tool/memleak3.tcl b8eb053190e95a55dc188896afb972e8108822d6 | ||||
| F tool/mkkeywordhash.c 408dccad57ed50dc67a9a1ee7fd258e0f0a07bd2 | ||||
| F tool/mkkeywordhash.c db33613e94e9ed3fb0838e2c3ca4415c5fd7ec0e | ||||
| F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x | ||||
| F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c | ||||
| F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816 | ||||
| @@ -270,7 +270,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc | ||||
| F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618 | ||||
| F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 | ||||
| F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746 | ||||
| P 5b1a9bf6aa5a5c466b88f649e322e81b8466851f | ||||
| R db2528b7bd532f73e60abad289bd81fd | ||||
| U danielk1977 | ||||
| Z b2590dd052208a3aa6c3782df4f94dd4 | ||||
| P 417bbba93ad7ed5c03d9db6afc12e170155bd152 | ||||
| R 0a5b2b3342f1338802ba7063dbaea636 | ||||
| U drh | ||||
| 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 | ||||
| ** 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 <ctype.h> | ||||
| @@ -1176,6 +1176,7 @@ struct QueryCoder { | ||||
| ** sqlite3ExprCodeSubquery().  See comments on those routines for | ||||
| ** additional information. | ||||
| */ | ||||
| #ifndef SQLITE_OMIT_SUBQUERY | ||||
| static int codeSubqueryStep(void *pArg, Expr *pExpr){ | ||||
|   QueryCoder *pCoder = (QueryCoder*)pArg; | ||||
|   Parse *pParse = pCoder->pParse; | ||||
| @@ -1263,6 +1264,7 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){ | ||||
|       return 1; | ||||
|     } | ||||
|  | ||||
|     case TK_EXISTS: | ||||
|     case TK_SELECT: { | ||||
|       /* This has to be a scalar SELECT.  Generate code to put the | ||||
|       ** 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; | ||||
|       Vdbe *v; | ||||
|       int addr; | ||||
|       int sop; | ||||
|       Select *pSel; | ||||
|  | ||||
|       pNC = pCoder->pNC; | ||||
|       if( pNC ) nRef = pNC->nRef; | ||||
| @@ -1279,7 +1283,17 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){ | ||||
|       v = sqlite3GetVdbe(pParse); | ||||
|       addr = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); | ||||
|       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 ){ | ||||
|         /* Subquery value changes.  Evaluate at each use */ | ||||
|         pExpr->iTable = addr+1; | ||||
| @@ -1295,6 +1309,7 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){ | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| #endif /* SQLITE_OMIT_SUBQUERY */ | ||||
|  | ||||
| /* | ||||
| ** Generate code to evaluate subqueries and IN operators contained | ||||
| @@ -1305,10 +1320,12 @@ static int sqlite3ExprCodeSubquery( | ||||
|   NameContext *pNC,    /* First enclosing namespace.  Often NULL */ | ||||
|   Expr *pExpr          /* Subquery to be coded */ | ||||
| ){ | ||||
| #ifndef SQLITE_OMIT_SUBQUERY | ||||
|   QueryCoder sCoder; | ||||
|   sCoder.pParse = pParse; | ||||
|   sCoder.pNC = pNC; | ||||
|   walkExprTree(pExpr, codeSubqueryStep, &sCoder); | ||||
| #endif | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										24
									
								
								src/parse.y
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/parse.y
									
									
									
									
									
								
							| @@ -14,7 +14,7 @@ | ||||
| ** the parser.  Lemon will also generate a header file containing | ||||
| ** 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_type {Token} | ||||
| @@ -418,6 +418,7 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). { | ||||
|     else { sqlite3IdListDelete(U); } | ||||
|   } | ||||
| } | ||||
| %ifndef SQLITE_OMIT_SUBQUERY | ||||
|   seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP | ||||
|                     as(Z) on_opt(N) using_opt(U). { | ||||
|     A = sqlite3SrcListAppend(X,0,0); | ||||
| @@ -443,6 +444,7 @@ seltablist_paren(A) ::= select(S).      {A = S;} | ||||
|   seltablist_paren(A) ::= seltablist(F).  { | ||||
|      A = sqlite3SelectNew(0,F,0,0,0,0,0,-1,0); | ||||
|   } | ||||
| %endif // SQLITE_OMIT_SUBQUERY | ||||
|  | ||||
| %type dbnm {Token} | ||||
| 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); | ||||
|   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} | ||||
| between_op(A) ::= BETWEEN.     {A = 0;} | ||||
| between_op(A) ::= NOT BETWEEN. {A = 1;} | ||||
| @@ -717,6 +714,12 @@ expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { | ||||
|   if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); | ||||
|   sqlite3ExprSpan(A,&X->span,&E); | ||||
| } | ||||
| %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); | ||||
|     if( A ) A->pSelect = Y; | ||||
| @@ -730,7 +733,14 @@ expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] { | ||||
|     if( N ) A = sqlite3Expr(TK_NOT, A, 0, 0); | ||||
|     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 */ | ||||
| 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 | ||||
| ** 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" | ||||
|  | ||||
| @@ -504,6 +504,7 @@ static int selectInnerLoop( | ||||
|     ** store the results in the appropriate memory cell and break out | ||||
|     ** of the scan loop. | ||||
|     */ | ||||
|     case SRT_Exists: | ||||
|     case SRT_Mem: { | ||||
|       assert( nColumn==1 ); | ||||
|       if( pOrderBy ){ | ||||
| @@ -617,6 +618,7 @@ static void generateSortTail( | ||||
|       sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); | ||||
|       break; | ||||
|     } | ||||
|     case SRT_Exists: | ||||
|     case SRT_Mem: { | ||||
|       assert( nColumn==1 ); | ||||
|       sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); | ||||
| @@ -2373,6 +2375,7 @@ int sqlite3Select( | ||||
|   /* If writing to memory or generating a set | ||||
|   ** only a single column may be output. | ||||
|   */ | ||||
|   assert( eDest!=SRT_Exists || pEList->nExpr==1 ); | ||||
|   if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){ | ||||
|     sqlite3ErrorMsg(pParse, "only a single result allowed for " | ||||
|        "a SELECT that is part of an expression"); | ||||
| @@ -2460,6 +2463,7 @@ int sqlite3Select( | ||||
|  | ||||
|   /* 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++){ | ||||
|     const char *zSavedAuthContext = 0; | ||||
|     int needRestoreContext; | ||||
| @@ -2486,6 +2490,7 @@ int sqlite3Select( | ||||
|     pHaving = p->pHaving; | ||||
|     isDistinct = p->isDistinct; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   /* Check for the special case of a min() or max() function by itself | ||||
|   ** 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 ){ | ||||
|     sqlite3VdbeAddOp(v, OP_String8, 0, 0); | ||||
|   if( eDest==SRT_Mem || eDest==SRT_Exists ){ | ||||
|     sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0); | ||||
|     sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| ************************************************************************* | ||||
| ** 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_ | ||||
| #define _SQLITEINT_H_ | ||||
| @@ -832,6 +832,7 @@ struct Expr { | ||||
| #define EP_Agg          0x0002  /* Contains one or more aggregate functions */ | ||||
| #define EP_Resolved     0x0004  /* IDs have been resolved to COLUMNs */ | ||||
| #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  | ||||
| @@ -1016,6 +1017,7 @@ struct Select { | ||||
| #define SRT_Discard      9  /* Do not save the results anywhere */ | ||||
| #define SRT_Sorter      10  /* Store results in the sorter */ | ||||
| #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)") | ||||
|   | ||||
| @@ -80,20 +80,25 @@ struct Keyword { | ||||
| #else | ||||
| #  define REINDEX    1024 | ||||
| #endif | ||||
| #ifdef SQLITE_OMIT_SUBQUERY | ||||
| #  define SUBQUERY   0 | ||||
| #else | ||||
| #  define SUBQUERY   2048 | ||||
| #endif | ||||
| #ifdef SQLITE_OMIT_TRIGGER | ||||
| #  define TRIGGER    0 | ||||
| #else | ||||
| #  define TRIGGER    2048 | ||||
| #  define TRIGGER    4096 | ||||
| #endif | ||||
| #ifdef SQLITE_OMIT_VACUUM | ||||
| #  define VACUUM     0 | ||||
| #else | ||||
| #  define VACUUM     4096 | ||||
| #  define VACUUM     8192 | ||||
| #endif | ||||
| #ifdef SQLITE_OMIT_VIEW | ||||
| #  define VIEW       0 | ||||
| #else | ||||
| #  define VIEW       8192 | ||||
| #  define VIEW       16384 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| @@ -146,6 +151,7 @@ static Keyword aKeywordTable[] = { | ||||
|   { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 }, | ||||
|   { "EXCEPT",           "TK_EXCEPT",       COMPOUND               }, | ||||
|   { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 }, | ||||
|   { "EXISTS",           "TK_EXISTS",       SUBQUERY               }, | ||||
|   { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                }, | ||||
|   { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       }, | ||||
|   { "FETCH",            "TK_FETCH",        CURSOR                 }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user