1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Minor refactoring of the expression-compaction logic for clarity of

presentation.  New comments added.  The EXPRDUP_DISTINCTSPAN flag is
removed as obsolete. (CVS 6470)

FossilOrigin-Name: 44ded2ea67374f187a111df69c3f51f866735400
This commit is contained in:
drh
2009-04-08 13:51:51 +00:00
parent 0a9aa2253c
commit 12ffee8cb9
7 changed files with 88 additions and 88 deletions

View File

@@ -1,5 +1,5 @@
C Do\snot\sattempt\sto\swalk\sa\sTokenOnly\sor\sSpanOnly\sexpression\stree\snode.\nTicket\s#3791.\s(CVS\s6469) C Minor\srefactoring\sof\sthe\sexpression-compaction\slogic\sfor\sclarity\sof\npresentation.\s\sNew\scomments\sadded.\s\sThe\sEXPRDUP_DISTINCTSPAN\sflag\sis\nremoved\sas\sobsolete.\s(CVS\s6470)
D 2009-04-08T12:21:31 D 2009-04-08T13:51:51
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -98,7 +98,7 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 472c0a4733de40f1d997ff4fd746042b707faf7b F src/alter.c 472c0a4733de40f1d997ff4fd746042b707faf7b
F src/analyze.c 3585d1a4c480ee85b65cf0a676e05d2c29eb6bdb F src/analyze.c 3585d1a4c480ee85b65cf0a676e05d2c29eb6bdb
F src/attach.c d34589d5c85d81e755e4a8fc946d313915a6fa6d F src/attach.c af80fa85d391ad302c148c4e2524a2cebec64cb2
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
@@ -106,12 +106,12 @@ F src/btmutex.c 341502bc496dc0840dcb00cde65680fb0e85c3ab
F src/btree.c 0d02176d76c6e202cff0788929e8eee71bf60e88 F src/btree.c 0d02176d76c6e202cff0788929e8eee71bf60e88
F src/btree.h 8007018c1753944790c39610280894ab280210b8 F src/btree.h 8007018c1753944790c39610280894ab280210b8
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5 F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
F src/build.c 72357fd75ef036d0afbf1756edab6d62c56fcf4b F src/build.c 2882f22078db1c3f887b1aca77ff460cf9461c62
F src/callback.c 73016376d6848ba987709e8c9048d4f0e0776036 F src/callback.c 73016376d6848ba987709e8c9048d4f0e0776036
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
F src/date.c 3e5c554b2f4f2d798761597c08147d7b15f35bea F src/date.c 3e5c554b2f4f2d798761597c08147d7b15f35bea
F src/delete.c eb1066b2f35489fee46ad765d2b66386fc7d8adf F src/delete.c eb1066b2f35489fee46ad765d2b66386fc7d8adf
F src/expr.c b7ce173d17b80e937473147604bfde4bb339a8a0 F src/expr.c ccc5b5fa3bac249a9ab6e5e10629d77ff293c9f8
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c 99ae90d46154952e08282fcdfe72d08e9601e174 F src/func.c 99ae90d46154952e08282fcdfe72d08e9601e174
F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c
@@ -159,7 +159,7 @@ F src/select.c 462d9671e91accd983110fa38674be0d2a3daa66
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7 F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
F src/sqlite.h.in 718a026b4cf3c766fc7ac5ff582faa60324b116c F src/sqlite.h.in 718a026b4cf3c766fc7ac5ff582faa60324b116c
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 7b341ab7d570b271e8566e7e7ed6993453f84964 F src/sqliteInt.h fcdad0896da9c8b6372db974131e33b7a06606ce
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3 F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
@@ -208,7 +208,7 @@ F src/vdbeaux.c 570aaa5e15ae141115194d22443c73c8beb5032b
F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38 F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
F src/vdbemem.c 9798905787baae83d0b53b62030e32ecf7a0586f F src/vdbemem.c 9798905787baae83d0b53b62030e32ecf7a0586f
F src/vtab.c f1aba5a6dc1f83b97a39fbbc58ff8cbc76311347 F src/vtab.c f1aba5a6dc1f83b97a39fbbc58ff8cbc76311347
F src/walker.c b32028f411cd4faa4e9e75da6f192f3e6e3dc7af F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
F src/where.c ddf26069d03f9e0c6ef14d537422df02e0c593f0 F src/where.c ddf26069d03f9e0c6ef14d537422df02e0c593f0
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911 F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
@@ -716,7 +716,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P ee5a4a0e595a7b916db7d55d30ddfda0a8d40d90 P 8362d883248f00a8ec7294bf027fd19758aec5f2
R 17434378e2db6c8fd2ad9ea648250d41 R 4b30b803e3cfb8e04c48c3d2b8d2124a
U drh U drh
Z 66c9263486f4e7d1bb93c05e15462035 Z 869480ece5a998deade5da75d4798c3b

View File

@@ -1 +1 @@
8362d883248f00a8ec7294bf027fd19758aec5f2 44ded2ea67374f187a111df69c3f51f866735400

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands. ** This file contains code used to implement the ATTACH and DETACH commands.
** **
** $Id: attach.c,v 1.83 2009/02/19 14:39:25 danielk1977 Exp $ ** $Id: attach.c,v 1.84 2009/04/08 13:51:51 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -488,7 +488,7 @@ int sqlite3FixExpr(
Expr *pExpr /* The expression to be fixed to one database */ Expr *pExpr /* The expression to be fixed to one database */
){ ){
while( pExpr ){ while( pExpr ){
if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanOnly) ) break; if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{ }else{

View File

@@ -22,7 +22,7 @@
** COMMIT ** COMMIT
** ROLLBACK ** ROLLBACK
** **
** $Id: build.c,v 1.527 2009/03/31 03:41:57 shane Exp $ ** $Id: build.c,v 1.528 2009/04/08 13:51:51 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -1112,9 +1112,7 @@ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
** is required by pragma table_info. ** is required by pragma table_info.
*/ */
sqlite3ExprDelete(db, pCol->pDflt); sqlite3ExprDelete(db, pCol->pDflt);
pCol->pDflt = sqlite3ExprDup( pCol->pDflt = sqlite3ExprDup(db, pExpr, EXPRDUP_REDUCE|EXPRDUP_SPAN);
db, pExpr, EXPRDUP_REDUCE|EXPRDUP_DISTINCTSPAN
);
} }
} }
sqlite3ExprDelete(db, pExpr); sqlite3ExprDelete(db, pExpr);

View File

@@ -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.425 2009/04/02 17:23:33 danielk1977 Exp $ ** $Id: expr.c,v 1.426 2009/04/08 13:51:51 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -629,15 +629,18 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
*/ */
void sqlite3ExprClear(sqlite3 *db, Expr *p){ void sqlite3ExprClear(sqlite3 *db, Expr *p){
if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z); if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z);
if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanOnly) ){ if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){
if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z); if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
if( ExprHasProperty(p, EP_Reduced) ){ if( ExprHasProperty(p, EP_Reduced) ){
/* Subtrees are part of the same memory allocation when EP_Reduced set */
if( p->pLeft ) sqlite3ExprClear(db, p->pLeft); if( p->pLeft ) sqlite3ExprClear(db, p->pLeft);
if( p->pRight ) sqlite3ExprClear(db, p->pRight); if( p->pRight ) sqlite3ExprClear(db, p->pRight);
}else{ }else{
/* Subtrees are separate allocations when EP_Reduced is clear */
sqlite3ExprDelete(db, p->pLeft); sqlite3ExprDelete(db, p->pLeft);
sqlite3ExprDelete(db, p->pRight); sqlite3ExprDelete(db, p->pRight);
} }
/* x.pSelect and x.pList are always separately allocated */
if( ExprHasProperty(p, EP_xIsSelect) ){ if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect); sqlite3SelectDelete(db, p->x.pSelect);
}else{ }else{
@@ -674,7 +677,7 @@ void sqlite3DequoteExpr(Expr *p){
*/ */
static int exprStructSize(Expr *p){ static int exprStructSize(Expr *p){
if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
if( ExprHasProperty(p, EP_SpanOnly) ) return EXPR_SPANONLYSIZE; if( ExprHasProperty(p, EP_SpanToken) ) return EXPR_SPANTOKENSIZE;
if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
return EXPR_FULLSIZE; return EXPR_FULLSIZE;
} }
@@ -691,8 +694,8 @@ static int dupedExprStructSize(Expr *p, int flags){
nSize = EXPR_FULLSIZE; nSize = EXPR_FULLSIZE;
}else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){ }else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
nSize = EXPR_REDUCEDSIZE; nSize = EXPR_REDUCEDSIZE;
}else if( flags&(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN) ){ }else if( flags&EXPRDUP_SPAN ){
nSize = EXPR_SPANONLYSIZE; nSize = EXPR_SPANTOKENSIZE;
}else{ }else{
nSize = EXPR_TOKENONLYSIZE; nSize = EXPR_TOKENONLYSIZE;
} }
@@ -708,8 +711,8 @@ static int dupedExprStructSize(Expr *p, int flags){
*/ */
static int dupedExprNodeSize(Expr *p, int flags){ static int dupedExprNodeSize(Expr *p, int flags){
int nByte = dupedExprStructSize(p, flags) + (p->token.z ? p->token.n + 1 : 0); int nByte = dupedExprStructSize(p, flags) + (p->token.z ? p->token.n + 1 : 0);
if( (flags&EXPRDUP_DISTINCTSPAN) if( (flags&EXPRDUP_SPAN)!=0
|| (flags&EXPRDUP_SPAN && (p->token.z!=p->span.z || p->token.n!=p->span.n)) && (p->token.z!=p->span.z || p->token.n!=p->span.n)
){ ){
nByte += p->span.n; nByte += p->span.n;
} }
@@ -736,7 +739,7 @@ static int dupedExprSize(Expr *p, int flags){
if( p ){ if( p ){
nByte = dupedExprNodeSize(p, flags); nByte = dupedExprNodeSize(p, flags);
if( flags&EXPRDUP_REDUCE ){ if( flags&EXPRDUP_REDUCE ){
int f = flags&(~(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN)); int f = flags&(~EXPRDUP_SPAN);
nByte += dupedExprSize(p->pLeft, f) + dupedExprSize(p->pRight, f); nByte += dupedExprSize(p->pLeft, f) + dupedExprSize(p->pRight, f);
} }
} }
@@ -754,8 +757,7 @@ static int dupedExprSize(Expr *p, int flags){
static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
Expr *pNew = 0; /* Value to return */ Expr *pNew = 0; /* Value to return */
if( p ){ if( p ){
const int isRequireDistinctSpan = (flags&EXPRDUP_DISTINCTSPAN); const int isRequireSpan = (flags&EXPRDUP_SPAN);
const int isRequireSpan = (flags&(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN));
const int isReduced = (flags&EXPRDUP_REDUCE); const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc; u8 *zAlloc;
@@ -787,11 +789,11 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
} }
/* Set the EP_Reduced and EP_TokenOnly flags appropriately. */ /* Set the EP_Reduced and EP_TokenOnly flags appropriately. */
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanOnly); pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanToken);
switch( nNewSize ){ switch( nNewSize ){
case EXPR_REDUCEDSIZE: pNew->flags |= EP_Reduced; break; case EXPR_REDUCEDSIZE: pNew->flags |= EP_Reduced; break;
case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break; case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break;
case EXPR_SPANONLYSIZE: pNew->flags |= EP_SpanOnly; break; case EXPR_SPANTOKENSIZE: pNew->flags |= EP_SpanToken; break;
} }
/* Copy the p->token string, if any. */ /* Copy the p->token string, if any. */
@@ -806,9 +808,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
/* Fill in the pNew->span token, if required. */ /* Fill in the pNew->span token, if required. */
if( isRequireSpan ){ if( isRequireSpan ){
if( isRequireDistinctSpan if( p->token.z!=p->span.z || p->token.n!=p->span.n ){
|| p->token.z!=p->span.z || p->token.n!=p->span.n
){
pNew->span.z = &zAlloc[nNewSize+nToken]; pNew->span.z = &zAlloc[nNewSize+nToken];
memcpy((char *)pNew->span.z, p->span.z, p->span.n); memcpy((char *)pNew->span.z, p->span.z, p->span.n);
pNew->span.dyn = 0; pNew->span.dyn = 0;
@@ -822,7 +822,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
} }
} }
if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_SpanOnly)) ){ if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_SpanToken)) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){ if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced); pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
@@ -832,7 +832,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
} }
/* Fill in pNew->pLeft and pNew->pRight. */ /* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanOnly) ){ if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanToken) ){
zAlloc += dupedExprNodeSize(p, flags); zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){ if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc); pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
@@ -841,7 +841,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
if( pzBuffer ){ if( pzBuffer ){
*pzBuffer = zAlloc; *pzBuffer = zAlloc;
} }
}else if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanOnly) ){ }else if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
} }
@@ -2205,31 +2205,34 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
} }
case TK_CONST_FUNC: case TK_CONST_FUNC:
case TK_FUNCTION: { case TK_FUNCTION: {
ExprList *pList = ( ExprList *pFarg; /* List of function arguments */
ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanOnly) ? 0 : pExpr->x.pList int nFarg; /* Number of function arguments */
); FuncDef *pDef; /* The function definition object */
int nExpr = pList ? pList->nExpr : 0; int nId; /* Length of the function name in bytes */
FuncDef *pDef; const char *zId; /* The function name */
int nId; int constMask = 0; /* Mask of function arguments that are constant */
const char *zId; int i; /* Loop counter */
int constMask = 0; u8 enc = ENC(db); /* The text encoding used by this database */
int i; CollSeq *pColl = 0; /* A collating sequence */
u8 enc = ENC(db);
CollSeq *pColl = 0;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
testcase( op==TK_CONST_FUNC ); testcase( op==TK_CONST_FUNC );
testcase( op==TK_FUNCTION ); testcase( op==TK_FUNCTION );
if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
}
nFarg = pFarg ? pFarg->nExpr : 0;
zId = (char*)pExpr->token.z; zId = (char*)pExpr->token.z;
nId = pExpr->token.n; nId = pExpr->token.n;
pDef = sqlite3FindFunction(db, zId, nId, nExpr, enc, 0); pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
assert( pDef!=0 ); assert( pDef!=0 );
if( pList ){ if( pFarg ){
nExpr = pList->nExpr; r1 = sqlite3GetTempRange(pParse, nFarg);
r1 = sqlite3GetTempRange(pParse, nExpr); sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
sqlite3ExprCodeExprList(pParse, pList, r1, 1);
}else{ }else{
nExpr = r1 = 0; r1 = 0;
} }
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
/* Possibly overload the function if the first argument is /* Possibly overload the function if the first argument is
@@ -2244,18 +2247,18 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
** "glob(B,A). We want to use the A in "A glob B" to test ** "glob(B,A). We want to use the A in "A glob B" to test
** for function overloading. But we use the B term in "glob(B,A)". ** for function overloading. But we use the B term in "glob(B,A)".
*/ */
if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){ if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[1].pExpr); pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
}else if( nExpr>0 ){ }else if( nFarg>0 ){
pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[0].pExpr); pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
} }
#endif #endif
for(i=0; i<nExpr && i<32; i++){ for(i=0; i<nFarg && i<32; i++){
if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){ if( sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
constMask |= (1<<i); constMask |= (1<<i);
} }
if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
} }
} }
if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){ if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){
@@ -2264,11 +2267,11 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
} }
sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
(char*)pDef, P4_FUNCDEF); (char*)pDef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nExpr); sqlite3VdbeChangeP5(v, (u8)nFarg);
if( nExpr ){ if( nFarg ){
sqlite3ReleaseTempRange(pParse, r1, nExpr); sqlite3ReleaseTempRange(pParse, r1, nFarg);
} }
sqlite3ExprCacheAffinityChange(pParse, r1, nExpr); sqlite3ExprCacheAffinityChange(pParse, r1, nFarg);
break; break;
} }
#ifndef SQLITE_OMIT_SUBQUERY #ifndef SQLITE_OMIT_SUBQUERY

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.853 2009/04/07 22:06:57 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.854 2009/04/08 13:51:51 drh Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -1452,19 +1452,18 @@ struct AggInfo {
** **
** ALLOCATION NOTES: ** ALLOCATION NOTES:
** **
** Expr structures may be stored as part of the in-memory database schema, ** Expr objects can use a lot of memory space in database schema. To
** for example as part of trigger, view or table definitions. In this case, ** help reduce memory requirements, sometimes an Expr object will be
** the amount of memory consumed by complex expressions may be significant. ** truncated. And to reduce the number of memory allocations, sometimes
** For this reason, less than sizeof(Expr) bytes may be allocated for some ** two or more Expr objects will be stored in a single memory allocation,
** Expr structs stored as part of the in-memory database schema. ** together with Expr.token and/or Expr.span strings.
** **
** If the EP_Reduced flag is set in Expr.flags, then only EXPR_REDUCEDSIZE ** If the EP_Reduced, EP_SpanToken, and EP_TokenOnly flags are set when
** bytes of space are allocated for the expression structure. This is enough ** an Expr object is truncated. When EP_Reduced is set, then all
** space to store all fields up to and including the "Token span;" field. ** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
** ** are contained within the same memory allocation. Note, however, that
** If the EP_TokenOnly flag is set in Expr.flags, then only EXPR_TOKENONLYSIZE ** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
** bytes of space are allocated for the expression structure. This is enough ** allocated, regardless of whether or not EP_Reduced is set.
** space to store all fields up to and including the "Token token;" field.
*/ */
struct Expr { struct Expr {
u8 op; /* Operation performed by this node */ u8 op; /* Operation performed by this node */
@@ -1480,7 +1479,7 @@ struct Expr {
Token span; /* Complete text of the expression */ Token span; /* Complete text of the expression */
/* If the EP_SpanOnly flag is set in the Expr.flags mask, then no /* If the EP_SpanToken flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to ** space is allocated for the fields below this point. An attempt to
** access them will result in a segfault or malfunction. ** access them will result in a segfault or malfunction.
*********************************************************************/ *********************************************************************/
@@ -1528,7 +1527,7 @@ struct Expr {
#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */ #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */ #define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
#define EP_SpanOnly 0x8000 /* Expr struct is EXPR_SPANONLYSIZE bytes only */ #define EP_SpanToken 0x8000 /* Expr size is EXPR_SPANTOKENSIZE bytes */
/* /*
** The following are the meanings of bits in the Expr.vvaFlags field. ** The following are the meanings of bits in the Expr.vvaFlags field.
@@ -1553,18 +1552,17 @@ struct Expr {
** struct, an Expr struct with the EP_Reduced flag set in Expr.flags ** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
** and an Expr struct with the EP_TokenOnly flag set. ** and an Expr struct with the EP_TokenOnly flag set.
*/ */
#define EXPR_FULLSIZE sizeof(Expr) #define EXPR_FULLSIZE sizeof(Expr) /* Full size */
#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) #define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */
#define EXPR_TOKENONLYSIZE offsetof(Expr,span) #define EXPR_SPANTOKENSIZE offsetof(Expr,pLeft) /* Fewer features */
#define EXPR_SPANONLYSIZE offsetof(Expr,pLeft) #define EXPR_TOKENONLYSIZE offsetof(Expr,span) /* Smallest possible */
/* /*
** Flags passed to the sqlite3ExprDup() function. See the header comment ** Flags passed to the sqlite3ExprDup() function. See the header comment
** above sqlite3ExprDup() for details. ** above sqlite3ExprDup() for details.
*/ */
#define EXPRDUP_REDUCE 0x0001 #define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
#define EXPRDUP_SPAN 0x0002 #define EXPRDUP_SPAN 0x0002 /* Make a copy of Expr.span */
#define EXPRDUP_DISTINCTSPAN 0x0004
/* /*
** A list of expressions. Each expression may optionally have a ** A list of expressions. Each expression may optionally have a

View File

@@ -12,7 +12,7 @@
** This file contains routines used for walking the parser tree for ** This file contains routines used for walking the parser tree for
** an SQL statement. ** an SQL statement.
** **
** $Id: walker.c,v 1.3 2009/04/08 12:21:31 drh Exp $ ** $Id: walker.c,v 1.4 2009/04/08 13:51:52 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <stdlib.h> #include <stdlib.h>
@@ -42,10 +42,11 @@ int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
int rc; int rc;
if( pExpr==0 ) return WRC_Continue; if( pExpr==0 ) return WRC_Continue;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_SpanOnly) ); testcase( ExprHasProperty(pExpr, EP_SpanToken) );
testcase( ExprHasProperty(pExpr, EP_Reduced) ); testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr); rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue && !ExprHasAnyProperty(pExpr,EP_TokenOnly|EP_SpanOnly) ){ if( rc==WRC_Continue
&& !ExprHasAnyProperty(pExpr,EP_TokenOnly|EP_SpanToken) ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( ExprHasProperty(pExpr, EP_xIsSelect) ){