]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Minor refactoring of the expression-compaction logic for clarity of
authordrh <drh@noemail.net>
Wed, 8 Apr 2009 13:51:51 +0000 (13:51 +0000)
committerdrh <drh@noemail.net>
Wed, 8 Apr 2009 13:51:51 +0000 (13:51 +0000)
presentation.  New comments added.  The EXPRDUP_DISTINCTSPAN flag is
removed as obsolete. (CVS 6470)

FossilOrigin-Name: 44ded2ea67374f187a111df69c3f51f866735400

manifest
manifest.uuid
src/attach.c
src/build.c
src/expr.c
src/sqliteInt.h
src/walker.c

index 92d9cea077333c0740e855e2b2d7194ade07822c..2d8e18d47fbcbd53ca6d4d0c9cf6bd416cc66cb0 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Do\snot\sattempt\sto\swalk\sa\sTokenOnly\sor\sSpanOnly\sexpression\stree\snode.\nTicket\s#3791.\s(CVS\s6469)
-D 2009-04-08T12:21:31
+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-08T13:51:51
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -98,7 +98,7 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
 F src/alter.c 472c0a4733de40f1d997ff4fd746042b707faf7b
 F src/analyze.c 3585d1a4c480ee85b65cf0a676e05d2c29eb6bdb
-F src/attach.c d34589d5c85d81e755e4a8fc946d313915a6fa6d
+F src/attach.c af80fa85d391ad302c148c4e2524a2cebec64cb2
 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
 F src/backup.c 0082d0e5a63f04e88faee0dff0a7d63d3e92a78d
 F src/bitvec.c ef370407e03440b0852d05024fb016b14a471d3d
@@ -106,12 +106,12 @@ F src/btmutex.c 341502bc496dc0840dcb00cde65680fb0e85c3ab
 F src/btree.c 0d02176d76c6e202cff0788929e8eee71bf60e88
 F src/btree.h 8007018c1753944790c39610280894ab280210b8
 F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
-F src/build.c 72357fd75ef036d0afbf1756edab6d62c56fcf4b
+F src/build.c 2882f22078db1c3f887b1aca77ff460cf9461c62
 F src/callback.c 73016376d6848ba987709e8c9048d4f0e0776036
 F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
 F src/date.c 3e5c554b2f4f2d798761597c08147d7b15f35bea
 F src/delete.c eb1066b2f35489fee46ad765d2b66386fc7d8adf
-F src/expr.c b7ce173d17b80e937473147604bfde4bb339a8a0
+F src/expr.c ccc5b5fa3bac249a9ab6e5e10629d77ff293c9f8
 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
 F src/func.c 99ae90d46154952e08282fcdfe72d08e9601e174
 F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c
@@ -159,7 +159,7 @@ F src/select.c 462d9671e91accd983110fa38674be0d2a3daa66
 F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
 F src/sqlite.h.in 718a026b4cf3c766fc7ac5ff582faa60324b116c
 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
-F src/sqliteInt.h 7b341ab7d570b271e8566e7e7ed6993453f84964
+F src/sqliteInt.h fcdad0896da9c8b6372db974131e33b7a06606ce
 F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
 F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
@@ -208,7 +208,7 @@ F src/vdbeaux.c 570aaa5e15ae141115194d22443c73c8beb5032b
 F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
 F src/vdbemem.c 9798905787baae83d0b53b62030e32ecf7a0586f
 F src/vtab.c f1aba5a6dc1f83b97a39fbbc58ff8cbc76311347
-F src/walker.c b32028f411cd4faa4e9e75da6f192f3e6e3dc7af
+F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
 F src/where.c ddf26069d03f9e0c6ef14d537422df02e0c593f0
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
@@ -716,7 +716,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P ee5a4a0e595a7b916db7d55d30ddfda0a8d40d90
-R 17434378e2db6c8fd2ad9ea648250d41
+P 8362d883248f00a8ec7294bf027fd19758aec5f2
+R 4b30b803e3cfb8e04c48c3d2b8d2124a
 U drh
-Z 66c9263486f4e7d1bb93c05e15462035
+Z 869480ece5a998deade5da75d4798c3b
index e139522d38329bc1d27b2b342f835690727e0604..295711c4469e527467521b596eb67e6f65e55308 100644 (file)
@@ -1 +1 @@
-8362d883248f00a8ec7294bf027fd19758aec5f2
\ No newline at end of file
+44ded2ea67374f187a111df69c3f51f866735400
\ No newline at end of file
index c3fd7ff8f046dec23dc517f7b7295e24be2766cd..0f54bcc055331ca90534980154bc072c08da5f8f 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** 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"
 
@@ -488,7 +488,7 @@ int sqlite3FixExpr(
   Expr *pExpr        /* The expression to be fixed to one database */
 ){
   while( pExpr ){
-    if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanOnly) ) break;
+    if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ) break;
     if( ExprHasProperty(pExpr, EP_xIsSelect) ){
       if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
     }else{
index dd3958876be2f3d3c31992b74898739a5dceb4c6..a54efcf5d28dcd723ae7e59de63ca9daaccf338c 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     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"
 
@@ -1112,9 +1112,7 @@ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
       ** is required by pragma table_info.
       */
       sqlite3ExprDelete(db, pCol->pDflt);
-      pCol->pDflt = sqlite3ExprDup(
-          db, pExpr, EXPRDUP_REDUCE|EXPRDUP_DISTINCTSPAN
-      );
+      pCol->pDflt = sqlite3ExprDup(db, pExpr, EXPRDUP_REDUCE|EXPRDUP_SPAN);
     }
   }
   sqlite3ExprDelete(db, pExpr);
index 663af1b12a89558c1017d79d6bf7a3c1813f4b63..35a585377b77e3b1e00d4f36e792ac9099223d64 100644 (file)
@@ -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.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"
 
@@ -629,15 +629,18 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
 */
 void sqlite3ExprClear(sqlite3 *db, Expr *p){
   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( 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->pRight ) sqlite3ExprClear(db, p->pRight);
     }else{
+      /* Subtrees are separate allocations when EP_Reduced is clear */
       sqlite3ExprDelete(db, p->pLeft);
       sqlite3ExprDelete(db, p->pRight);
     }
+    /* x.pSelect and x.pList are always separately allocated */
     if( ExprHasProperty(p, EP_xIsSelect) ){
       sqlite3SelectDelete(db, p->x.pSelect);
     }else{
@@ -674,7 +677,7 @@ void sqlite3DequoteExpr(Expr *p){
 */
 static int exprStructSize(Expr *p){
   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;
   return EXPR_FULLSIZE;
 }
@@ -691,8 +694,8 @@ static int dupedExprStructSize(Expr *p, int flags){
     nSize = EXPR_FULLSIZE;
   }else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
     nSize = EXPR_REDUCEDSIZE;
-  }else if( flags&(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN) ){
-    nSize = EXPR_SPANONLYSIZE;
+  }else if( flags&EXPRDUP_SPAN ){
+    nSize = EXPR_SPANTOKENSIZE;
   }else{
     nSize = EXPR_TOKENONLYSIZE;
   }
@@ -708,8 +711,8 @@ static int dupedExprStructSize(Expr *p, int flags){
 */
 static int dupedExprNodeSize(Expr *p, int flags){
   int nByte = dupedExprStructSize(p, flags) + (p->token.z ? p->token.n + 1 : 0);
-  if( (flags&EXPRDUP_DISTINCTSPAN)
-   || (flags&EXPRDUP_SPAN && (p->token.z!=p->span.z || p->token.n!=p->span.n)) 
+  if( (flags&EXPRDUP_SPAN)!=0
+   && (p->token.z!=p->span.z || p->token.n!=p->span.n)
   ){
     nByte += p->span.n;
   }
@@ -736,7 +739,7 @@ static int dupedExprSize(Expr *p, int flags){
   if( p ){
     nByte = dupedExprNodeSize(p, flags);
     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);
     }
   }
@@ -754,8 +757,7 @@ static int dupedExprSize(Expr *p, int flags){
 static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
   Expr *pNew = 0;                      /* Value to return */
   if( p ){
-    const int isRequireDistinctSpan = (flags&EXPRDUP_DISTINCTSPAN);
-    const int isRequireSpan = (flags&(EXPRDUP_SPAN|EXPRDUP_DISTINCTSPAN));
+    const int isRequireSpan = (flags&EXPRDUP_SPAN);
     const int isReduced = (flags&EXPRDUP_REDUCE);
     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. */
-      pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanOnly);
+      pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanToken);
       switch( nNewSize ){
         case EXPR_REDUCEDSIZE:   pNew->flags |= EP_Reduced; 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. */
@@ -806,9 +808,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
       if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
         /* Fill in the pNew->span token, if required. */
         if( isRequireSpan ){
-          if( isRequireDistinctSpan 
-           || p->token.z!=p->span.z || p->token.n!=p->span.n
-          ){
+          if( p->token.z!=p->span.z || p->token.n!=p->span.n ){
             pNew->span.z = &zAlloc[nNewSize+nToken];
             memcpy((char *)pNew->span.z, p->span.z, p->span.n);
             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. */
         if( ExprHasProperty(p, EP_xIsSelect) ){
           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. */
-      if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanOnly) ){
+      if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanToken) ){
         zAlloc += dupedExprNodeSize(p, flags);
         if( ExprHasProperty(pNew, EP_Reduced) ){
           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 ){
           *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->pRight = sqlite3ExprDup(db, p->pRight, 0);
       }
@@ -2205,31 +2205,34 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
     }
     case TK_CONST_FUNC:
     case TK_FUNCTION: {
-      ExprList *pList = (
-        ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanOnly) ? 0 : pExpr->x.pList
-      );
-      int nExpr = pList ? pList->nExpr : 0;
-      FuncDef *pDef;
-      int nId;
-      const char *zId;
-      int constMask = 0;
-      int i;
-      u8 enc = ENC(db);
-      CollSeq *pColl = 0;
+      ExprList *pFarg;       /* List of function arguments */
+      int nFarg;             /* Number of function arguments */
+      FuncDef *pDef;         /* The function definition object */
+      int nId;               /* Length of the function name in bytes */
+      const char *zId;       /* The function name */
+      int constMask = 0;     /* Mask of function arguments that are constant */
+      int i;                 /* Loop counter */
+      u8 enc = ENC(db);      /* The text encoding used by this database */
+      CollSeq *pColl = 0;    /* A collating sequence */
 
       assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
       testcase( op==TK_CONST_FUNC );
       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;
       nId = pExpr->token.n;
-      pDef = sqlite3FindFunction(db, zId, nId, nExpr, enc, 0);
+      pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
       assert( pDef!=0 );
-      if( pList ){
-        nExpr = pList->nExpr;
-        r1 = sqlite3GetTempRange(pParse, nExpr);
-        sqlite3ExprCodeExprList(pParse, pList, r1, 1);
+      if( pFarg ){
+        r1 = sqlite3GetTempRange(pParse, nFarg);
+        sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
       }else{
-        nExpr = r1 = 0;
+        r1 = 0;
       }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
       /* 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
       ** for function overloading.  But we use the B term in "glob(B,A)".
       */
-      if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){
-        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[1].pExpr);
-      }else if( nExpr>0 ){
-        pDef = sqlite3VtabOverloadFunction(db, pDef, nExpr, pList->a[0].pExpr);
+      if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
+        pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
+      }else if( nFarg>0 ){
+        pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
       }
 #endif
-      for(i=0; i<nExpr && i<32; i++){
-        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
+      for(i=0; i<nFarg && i<32; i++){
+        if( sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
           constMask |= (1<<i);
         }
         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 ){
@@ -2264,11 +2267,11 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
       }
       sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
                         (char*)pDef, P4_FUNCDEF);
-      sqlite3VdbeChangeP5(v, (u8)nExpr);
-      if( nExpr ){
-        sqlite3ReleaseTempRange(pParse, r1, nExpr);
+      sqlite3VdbeChangeP5(v, (u8)nFarg);
+      if( nFarg ){
+        sqlite3ReleaseTempRange(pParse, r1, nFarg);
       }
-      sqlite3ExprCacheAffinityChange(pParse, r1, nExpr);
+      sqlite3ExprCacheAffinityChange(pParse, r1, nFarg);
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
index a66bb3a4f539768c503a7c8a06749ba6400f958b..a74b30a4125fa2cc38a17fb5ee81e068183e6c20 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** 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_
 #define _SQLITEINT_H_
@@ -1452,19 +1452,18 @@ struct AggInfo {
 **
 ** ALLOCATION NOTES:
 **
-** Expr structures may be stored as part of the in-memory database schema,
-** for example as part of trigger, view or table definitions. In this case,
-** the amount of memory consumed by complex expressions may be significant.
-** For this reason, less than sizeof(Expr) bytes may be allocated for some 
-** Expr structs stored as part of the in-memory database schema.
+** Expr objects can use a lot of memory space in database schema.  To
+** help reduce memory requirements, sometimes an Expr object will be
+** truncated.  And to reduce the number of memory allocations, sometimes
+** two or more Expr objects will be stored in a single memory allocation,
+** together with Expr.token and/or Expr.span strings.
 **
-** If the EP_Reduced flag is set in Expr.flags, then only EXPR_REDUCEDSIZE
-** bytes of space are allocated for the expression structure. This is enough
-** space to store all fields up to and including the "Token span;" field.
-**
-** If the EP_TokenOnly flag is set in Expr.flags, then only EXPR_TOKENONLYSIZE
-** bytes of space are allocated for the expression structure. This is enough
-** space to store all fields up to and including the "Token token;" field.
+** If the EP_Reduced, EP_SpanToken, and EP_TokenOnly flags are set when
+** an Expr object is truncated.  When EP_Reduced is set, then all
+** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
+** are contained within the same memory allocation.  Note, however, that
+** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
+** allocated, regardless of whether or not EP_Reduced is set.
 */
 struct Expr {
   u8 op;                 /* Operation performed by this node */
@@ -1480,7 +1479,7 @@ struct Expr {
 
   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
   ** 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_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.
@@ -1553,18 +1552,17 @@ struct Expr {
 ** struct, an Expr struct with the EP_Reduced flag set in Expr.flags 
 ** and an Expr struct with the EP_TokenOnly flag set.
 */
-#define EXPR_FULLSIZE           sizeof(Expr)
-#define EXPR_REDUCEDSIZE        offsetof(Expr,iTable)
-#define EXPR_TOKENONLYSIZE      offsetof(Expr,span)
-#define EXPR_SPANONLYSIZE       offsetof(Expr,pLeft)
+#define EXPR_FULLSIZE           sizeof(Expr)           /* Full size */
+#define EXPR_REDUCEDSIZE        offsetof(Expr,iTable)  /* Common features */
+#define EXPR_SPANTOKENSIZE      offsetof(Expr,pLeft)   /* Fewer features */
+#define EXPR_TOKENONLYSIZE      offsetof(Expr,span)    /* Smallest possible */
 
 /*
 ** Flags passed to the sqlite3ExprDup() function. See the header comment 
 ** above sqlite3ExprDup() for details.
 */
-#define EXPRDUP_REDUCE         0x0001
-#define EXPRDUP_SPAN           0x0002
-#define EXPRDUP_DISTINCTSPAN   0x0004
+#define EXPRDUP_REDUCE         0x0001  /* Used reduced-size Expr nodes */
+#define EXPRDUP_SPAN           0x0002  /* Make a copy of Expr.span */
 
 /*
 ** A list of expressions.  Each expression may optionally have a
index 58f6a16ccc314cb6fb5a97830f78c914cf2e7432..19fb4e0351e3bf883c28186dd3d6a0483e94e84b 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for walking the parser tree for
 ** 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 <stdlib.h>
@@ -42,10 +42,11 @@ int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
   int rc;
   if( pExpr==0 ) return WRC_Continue;
   testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
-  testcase( ExprHasProperty(pExpr, EP_SpanOnly) );
+  testcase( ExprHasProperty(pExpr, EP_SpanToken) );
   testcase( ExprHasProperty(pExpr, EP_Reduced) );
   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->pRight) ) return WRC_Abort;
     if( ExprHasProperty(pExpr, EP_xIsSelect) ){