]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Reduce the size of Expr to 64-bytes. This works somewhat, but there are expr-simplify
authordrh <drh@noemail.net>
Wed, 19 Sep 2018 20:14:48 +0000 (20:14 +0000)
committerdrh <drh@noemail.net>
Wed, 19 Sep 2018 20:14:48 +0000 (20:14 +0000)
test failures.  More importantly, the size reduction from 80- to 64-bytes has
not lowered the schema memory usage, but it has made the code a little bigger
and a little slower.  So the initial evidence is that this Expr refactoring
experiment is not working...

FossilOrigin-Name: 24b0f66ac611e26f55ffeaff459b0d7ab53e6fa8d72765bea77c3b50634357e8

12 files changed:
manifest
manifest.uuid
src/alter.c
src/expr.c
src/fkey.c
src/parse.y
src/resolve.c
src/select.c
src/sqliteInt.h
src/vtab.c
src/wherecode.c
src/whereexpr.c

index fb194d27c992a209e637035f76e1e3e461f8ed11..47b3ca9887d858a209312ac6b3f6af9a4e23603f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\sissue\sin\svirtual\stable\shandling\sassociated\swith\sthe\snew\sExpr.x.pRight\nfield.
-D 2018-09-19T17:24:00.188
+C Reduce\sthe\ssize\sof\sExpr\sto\s64-bytes.\s\sThis\sworks\ssomewhat,\sbut\sthere\sare\ntest\sfailures.\s\sMore\simportantly,\sthe\ssize\sreduction\sfrom\s80-\sto\s64-bytes\shas\nnot\slowered\sthe\sschema\smemory\susage,\sbut\sit\shas\smade\sthe\scode\sa\slittle\sbigger\nand\sa\slittle\sslower.\s\sSo\sthe\sinitial\sevidence\sis\sthat\sthis\sExpr\srefactoring\nexperiment\sis\snot\sworking...
+D 2018-09-19T20:14:48.730
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 01e95208a78b57d056131382c493c963518f36da4c42b12a97eb324401b3a334
@@ -436,7 +436,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c 2269dd2f37ba963fde4c51e9e83542f126c86a8e10357c17f48137c6bee5299b
+F src/alter.c 3a859149c15cc78a446e0d632a1a9d24786e230ed1de53d8b88ca2c96f90ace0
 F src/analyze.c 3dc6b98cf007b005af89df165c966baaa48e8124f38c87b4d2b276fe7f0b9eb9
 F src/attach.c d06bf7ab9efceb7c679ba8beaeeb3082ce3defde482f54de50ac175469f7c4ca
 F src/auth.c 32a5bbe3b755169ab6c66311c5225a3cd4f75a46c041f7fb117e0cbb68055114
@@ -454,9 +454,9 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
 F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3
 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
 F src/delete.c 07a7ecf18a64478be7241cbb332bc26321586384c750e47fb566f678c5aee512
-F src/expr.c 539140adf9eb182aafda4344a1697e136379924760e6a552a5e40b85f4004205
+F src/expr.c 5814b4b5d4b9e615faba427a554de5152c972cc0132f6968a13250c07b709372
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
-F src/fkey.c f59253c0be4b1e9dfcb073b6d6d6ab83090ae50c08b5c113b76013c4b157cd6a
+F src/fkey.c 234d4e9fb2a35a11d6ee831dbc19e74fb8bfaf5e09b310ce3cffbf37d6eb57e0
 F src/func.c 82aeef69505b67197a476836d44cc16c1a434ee53481f23cffb70a75a1bcbc7a
 F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128
 F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
@@ -491,7 +491,7 @@ F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c a0d8f686ef64549ad5b356fd30429bd9ee7a06dd42b4d6faa096352ff26b1c5b
 F src/pager.h ecc554a55bc55d1c4ba5e17137b72e238e00bd81e72ff2662d8b9c8c10ae3963
-F src/parse.y cea885dd89f7c2963aee930b93c8ba14a7a9eb2bb31ba146777a7bbbc5b8a121
+F src/parse.y 96a86b76766af46ac9e64afc1576ea7cb0f7219d2f3a7b6c03bb07043017bdf5
 F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
 F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
@@ -500,14 +500,14 @@ F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
 F src/prepare.c f8e260d940a0e08494c0f30744521b2f832d7263eca9d02b050cea0ba144b097
 F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c 1f8444d1155b4711cbe2fc1fcd40ecace3f71faa1cf593472581e17b9b39e6af
+F src/resolve.c adfb08e3e31243433ed60613bd244ba0bef63c80ca0f2fee754db02a831b5811
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
-F src/select.c 45d01474cfb359b7ac12fbdf0fed6bdff53e63bd88eaef65e2001b52a4676a93
+F src/select.c 6bacf10a3a65b692586e80ffda8114ce485d47b0bc1fe18a001f39c5c054db81
 F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1f
 F src/sqlite.h.in 4b4c2f2daeeed4412ba9d81bc78092c69831fe6eda4f0ae5bf951da51a8dccec
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 305adca1b5da4a33ce2db5bd236935768e951d5651bfe5560ed55cfcdbce6a63
-F src/sqliteInt.h b8a598f500ce81be682730b30b5d0dbdc4c1ec70a8ef640b7893d0edcadb5bdd
+F src/sqliteInt.h 5cf4c8f1687b8a2042da2259ee8a5a14bf8aa7914a124afa2010afd2c759ccb2
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -582,15 +582,15 @@ F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c9419
 F src/vdbemem.c 81329ab760e4ec0162119d9cd10193e0303c45c5935bb20c7ae9139d44dd6641
 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
-F src/vtab.c 8665561f244c137a2d17b5c3e5910d7303054fe841c5d510e53f23beb0089594
+F src/vtab.c 0d613164d56f43aca041de072ceba541f35fc29eeb7085e69f84829249d7fc46
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c 3f4f653daf234fe713edbcbca3fec2350417d159d28801feabc702a22c4e213f
 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
 F src/walker.c 4ba292cadd145b8b77e8b2128a363beff0bd87c7f9abfe090c0948eb0330d727
 F src/where.c 33a546a918b0439e3e174351ca00c9158f26d73c5a8bb54c6c3cf5bae20b7499
 F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
-F src/wherecode.c 3b944b6dc50b99d3b93c3568c60bd37d019bb15234d4812182790295f3550bf7
-F src/whereexpr.c ba56a077649e8b0f4453eabfe57f3077c85bc6c9b7b3884bf2223c04f57fbca5
+F src/wherecode.c ab5992174e31e30f4624fbd57ddffce63db69c861c09811871e0cbab739a2a91
+F src/whereexpr.c c88f2047c493c36a11116b524c0c9b621253f512930386e81ea96309d7740fd6
 F src/window.c 4b503da928dace3e845b891381a4d98eeb8c5744313ae3643df8d8d21fdcca65
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -1767,7 +1767,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P e4129cd3a04bff314d2318f33d7ca02c05de35d35f6c650dddb5cabc7c430017
-R f6952b4cde3c10b13f753093be397fbc
+P 8487f84af00a8afde4ae24c4925e0f8ac9f38e86ea8b453dccedb3ee10f7f667
+R dc50e2519bfa1235f8e5a29ec2577516
 U drh
-Z f6992efeb3fbe71816f5a55ca6da8105
+Z a9cd90cadb1b1e1e79d944ecc746eecf
index 38fb46c1262974fb9f3011bfba717c35ad85cda0..81dcf5479ade8e386fe3d4b09e981276691e44fe 100644 (file)
@@ -1 +1 @@
-8487f84af00a8afde4ae24c4925e0f8ac9f38e86ea8b453dccedb3ee10f7f667
\ No newline at end of file
+24b0f66ac611e26f55ffeaff459b0d7ab53e6fa8d72765bea77c3b50634357e8
\ No newline at end of file
index 08745ccee2f5e50800751362b3a7dab279a5fb7d..e0e9ae85078f4229b497ae53bd33df16bf801cdf 100644 (file)
@@ -803,7 +803,8 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
     renameTokenFind(pWalker->pParse, p, (void*)pExpr);
   }else if( pExpr->op==TK_COLUMN 
    && pExpr->iColumn==p->iCol 
-   && p->pTab==pExpr->pTab
+   && ALWAYS(pExpr->eX==EX_Tab)
+   && p->pTab==pExpr->x.pTab
   ){
     renameTokenFind(pWalker->pParse, p, (void*)pExpr);
   }
@@ -1341,8 +1342,11 @@ renameColumnFunc_done:
 */
 static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
   RenameCtx *p = pWalker->u.pRename;
-  if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
-    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
+  if( pExpr->op==TK_COLUMN 
+   && ALWAYS(pExpr->eX==EX_Tab)
+   && p->pTab==pExpr->x.pTab
+  ){
+    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->x.pTab);
   }
   return WRC_Continue;
 }
index e85bf853afce17ede2f1c8bc40f718c328d779c3..0b9c236b66eb0dda29bcb98d19eac83ab2cfc94a 100644 (file)
@@ -58,8 +58,9 @@ char sqlite3ExprAffinity(Expr *pExpr){
     return sqlite3AffinityType(pExpr->u.zToken, 0);
   }
 #endif
-  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
-    return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+  if( (op==TK_AGG_COLUMN || op==TK_COLUMN)
+   && ALWAYS(pExpr->eX==EX_Tab) && pExpr->x.pTab ){
+    return sqlite3TableColumnAffinity(pExpr->x.pTab, pExpr->iColumn);
   }
   if( op==TK_SELECT_COLUMN ){
     assert( pExpr->pLeft->eX==EX_Select );
@@ -143,13 +144,14 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
     if( p->flags & EP_Generic ) break;
     if( (op==TK_AGG_COLUMN || op==TK_COLUMN
           || op==TK_REGISTER || op==TK_TRIGGER)
-     && p->pTab!=0
+     && p->eX==EX_Tab
+     && p->x.pTab!=0
     ){
       /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
       ** a TK_COLUMN but was previously evaluated and cached in a register */
       int j = p->iColumn;
       if( j>=0 ){
-        const char *zColl = p->pTab->aCol[j].zColl;
+        const char *zColl = p->x.pTab->aCol[j].zColl;
         pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
       }
       break;
@@ -1099,16 +1101,14 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
 #ifdef SQLITE_DEBUG
   if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
     assert( p->pLeft==0 );
-    assert( p->eX==EX_None );
+    assert( p->eX==EX_None || p->eX==EX_Tab );
   }
   if( !ExprHasProperty(p, EP_TokenOnly) ){
     assert( p->op!=TK_FUNCTION || p->pLeft==0 );
   }
   if( !ExprHasProperty(p, (EP_TokenOnly|EP_Reduced)) ){
     assert( p->pWin==0 || p->pLeft==0 );
-    assert( p->pWin==0 || p->pTab==0 );
     assert( p->pWin==0 || p->op==TK_FUNCTION );
-    assert( p->pTab==0 || p->eX==EX_None );
   }
 #endif
   if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
@@ -1140,6 +1140,29 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
   if( p ) sqlite3ExprDeleteNN(db, p);
 }
 
+void sqlite3ExprClearXUnion(sqlite3 *db, Expr *p){
+  switch( p->eX ){
+    case EX_Select: {
+      sqlite3SelectDelete(db, p->x.pSelect);
+      break;
+    }
+    case EX_List: {
+      sqlite3ExprListDelete(db, p->x.pList);
+      break;
+    }
+    case EX_Right: {
+      sqlite3ExprDelete(db, p->x.pRight);
+      break;
+    }
+  }
+  p->eX = EX_None;
+}
+void sqlite3ExprAddTab(sqlite3 *db, Expr *pExpr, Table *pTab){
+  sqlite3ExprClearXUnion(db, pExpr);
+  pExpr->eX = EX_Tab;
+  pExpr->x.pTab = pTab;
+}
+
 /*
 ** Return the number of bytes allocated for the expression structure 
 ** passed as the first argument. This is always one of EXPR_FULLSIZE,
@@ -2162,9 +2185,10 @@ int sqlite3ExprCanBeNull(const Expr *p){
     case TK_BLOB:
       return 0;
     case TK_COLUMN:
+      assert( p->eX==EX_Tab );
       return ExprHasProperty(p, EP_CanBeNull) ||
-             p->pTab==0 ||  /* Reference to column of index on expression */
-             (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
+             p->x.pTab==0 ||  /* Reference to column of index on expression */
+             (p->iColumn>=0 && p->x.pTab->aCol[p->iColumn].notNull==0);
     default:
       return 1;
   }
@@ -3454,8 +3478,10 @@ expr_code_doover:
         ** datatype by applying the Affinity of the table column to the
         ** constant.
         */
+        int aff;
         int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
-        int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+        assert( pExpr->eX==EX_Tab );
+        aff = sqlite3TableColumnAffinity(pExpr->x.pTab, pExpr->iColumn);
         if( aff!=SQLITE_AFF_BLOB ){
           static const char zAff[] = "B\000C\000D\000E";
           assert( SQLITE_AFF_BLOB=='A' );
@@ -3479,7 +3505,8 @@ expr_code_doover:
           iTab = pParse->iSelfTab - 1;
         }
       }
-      return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+      assert( pExpr->eX==EX_Tab );
+      return sqlite3ExprCodeGetColumn(pParse, pExpr->x.pTab,
                                pExpr->iColumn, iTab, target,
                                pExpr->op2);
     }
@@ -3941,7 +3968,9 @@ expr_code_doover:
       **   p1==1   ->    old.a         p1==4   ->    new.a
       **   p1==2   ->    old.b         p1==5   ->    new.b       
       */
-      Table *pTab = pExpr->pTab;
+      Table *pTab;
+      assert( pExpr->eX==EX_Tab );
+      pTab = pExpr->x.pTab;
       int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
 
       assert( pExpr->iTable==0 || pExpr->iTable==1 );
@@ -3950,9 +3979,10 @@ expr_code_doover:
       assert( p1>=0 && p1<(pTab->nCol*2+2) );
 
       sqlite3VdbeAddOp2(v, OP_Param, p1, target);
+      assert( pExpr->eX==EX_Tab );
       VdbeComment((v, "r[%d]=%s.%s", target,
         (pExpr->iTable ? "new" : "old"),
-        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
+        (pExpr->iColumn<0 ? "rowid" : pExpr->x.pTab->aCol[pExpr->iColumn].zName)
       ));
 
 #ifndef SQLITE_OMIT_FLOATING_POINT
@@ -4998,8 +5028,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
       testcase( pExpr->op==TK_GT );
       testcase( pExpr->op==TK_GE );
       assert( pExpr->eX==EX_Right );
-      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
-       || (pExpr->x.pRight->op==TK_COLUMN && IsVirtual(pExpr->x.pRight->pTab))
+      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->x.pTab))
+       || (pExpr->x.pRight->op==TK_COLUMN && IsVirtual(pExpr->x.pRight->x.pTab))
       ){
        return WRC_Prune;
       }
@@ -5230,7 +5260,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
              && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 
             ){
               pCol = &pAggInfo->aCol[k];
-              pCol->pTab = pExpr->pTab;
+              assert( pExpr->eX==EX_Tab );
+              pCol->pTab = pExpr->x.pTab;
               pCol->iTable = pExpr->iTable;
               pCol->iColumn = pExpr->iColumn;
               pCol->iMem = ++pParse->nMem;
index 0f5248fea2da9fb0caf291e33872c843ce44e815..aebde67532e00600c1024b234e2e15e6d1ef1e9a 100644 (file)
@@ -502,7 +502,11 @@ static Expr *exprTableColumn(
 ){
   Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
   if( pExpr ){
-    pExpr->pTab = pTab;
+    assert( pExpr->eX==EX_None );
+    if( pTab ){
+      pExpr->x.pTab = pTab;
+      pExpr->eX = EX_Tab;
+    }
     pExpr->iTable = iCursor;
     pExpr->iColumn = iCol;
   }
index c489c7e393126e8c12ded1b23b35426d73254316..acf68899e63ecd884a19c2e57e7fe54dd4b16f4c 100644 (file)
@@ -941,7 +941,6 @@ idlist(A) ::= nm(Y).
       p->iAgg = -1;
       p->pLeft = 0;
       p->pAggInfo = 0;
-      p->pTab = 0;
       p->op2 = 0;
       p->iTable = 0;
       p->iColumn = 0;
index 53bd8165a8201ec15f3d5301cce80bf5947cce0f..f98e91ccf5211b3c240f478d390ccb6b784e25f8 100644 (file)
@@ -203,7 +203,6 @@ static int lookupName(
 
   /* Initialize the node to no-match */
   pExpr->iTable = -1;
-  pExpr->pTab = 0;
   ExprSetVVAProperty(pExpr, EP_NoReduce);
 
   /* Translate the schema name in zDb into a pointer to the corresponding
@@ -265,7 +264,7 @@ static int lookupName(
             continue;
           }
           if( IN_RENAME_OBJECT && pItem->zAlias ){
-            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
+            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->x.pTab);
           }
         }
         if( 0==(cntTab++) ){
@@ -291,13 +290,13 @@ static int lookupName(
       }
       if( pMatch ){
         pExpr->iTable = pMatch->iCursor;
-        pExpr->pTab = pMatch->pTab;
+        sqlite3ExprAddTab(db, pExpr, pMatch->pTab);
         /* RIGHT JOIN not (yet) supported */
         assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
         if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
           ExprSetProperty(pExpr, EP_CanBeNull);
         }
-        pSchema = pExpr->pTab->pSchema;
+        pSchema = pExpr->x.pTab->pSchema;
       }
     } /* if( pSrcList ) */
 
@@ -354,7 +353,7 @@ static int lookupName(
             testcase( iCol==(-1) );
             if( IN_RENAME_OBJECT ){
               pExpr->iColumn = iCol;
-              pExpr->pTab = pTab;
+              sqlite3ExprAddTab(db, pExpr, pTab);
               eNewExprOp = TK_COLUMN;
             }else{
               pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
@@ -376,7 +375,7 @@ static int lookupName(
               testcase( iCol==32 );
               pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
             }
-            pExpr->pTab = pTab;
+            sqlite3ExprAddTab(db, pExpr, pTab);
             pExpr->iColumn = (i16)iCol;
             eNewExprOp = TK_TRIGGER;
 #endif /* SQLITE_OMIT_TRIGGER */
@@ -430,7 +429,6 @@ static int lookupName(
         if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
           Expr *pOrig;
           assert( pExpr->pLeft==0 );
-          assert( pExpr->eX==EX_None );
           pOrig = pEList->a[j].pExpr;
           if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
             sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
@@ -475,7 +473,6 @@ static int lookupName(
     assert( pExpr->op==TK_ID );
     if( ExprHasProperty(pExpr,EP_DblQuoted) ){
       pExpr->op = TK_STRING;
-      pExpr->pTab = 0;
       return WRC_Prune;
     }
     if( sqlite3ExprIdToTrueFalse(pExpr) ){
@@ -556,9 +553,9 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
   Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
   if( p ){
     struct SrcList_item *pItem = &pSrc->a[iSrc];
-    p->pTab = pItem->pTab;
+    sqlite3ExprAddTab(db, p, pItem->pTab);
     p->iTable = pItem->iCursor;
-    if( p->pTab->iPKey==iCol ){
+    if( p->x.pTab->iPKey==iCol ){
       p->iColumn = -1;
     }else{
       p->iColumn = (ynVar)iCol;
@@ -694,9 +691,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
         zColumn = pRight->u.zToken;
         if( IN_RENAME_OBJECT ){
           sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
-        }
-        if( IN_RENAME_OBJECT ){
-          sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
+          if( pExpr->eX==EX_Tab ){
+            sqlite3RenameTokenRemap(pParse, (void*)&pExpr->x.pTab,(void*)pLeft);
+          }
         }
       }
       return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
index ec0765f6a575a5b30db1daf6fca86284459f2cf5..5ca3b38498b46a59d1ce1ab151c3dd042d35e726 100644 (file)
@@ -803,8 +803,12 @@ static void selectExprDefer(
     struct ExprList_item *pItem = &pEList->a[i];
     if( pItem->u.x.iOrderByCol==0 ){
       Expr *pExpr = pItem->pExpr;
-      Table *pTab = pExpr->pTab;
-      if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
+      Table *pTab;
+      if( pExpr->op==TK_COLUMN
+       && pExpr->iColumn>=0
+       && ALWAYS(pExpr->eX==EX_Tab)
+       && (pTab = pExpr->x.pTab)!=0
+       && !IsVirtual(pTab)
        && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
       ){
         int j;
@@ -822,16 +826,18 @@ static void selectExprDefer(
               pPk = sqlite3PrimaryKeyIndex(pTab);
               nKey = pPk->nKeyCol;
             }
+            assert( pExpr->eX==EX_Tab );
             for(k=0; k<nKey; k++){
               Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
               if( pNew ){
                 pNew->iTable = pExpr->iTable;
-                pNew->pTab = pExpr->pTab;
+                pNew->eX = EX_Tab;
+                pNew->x.pTab = pExpr->x.pTab;
                 pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
                 pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
               }
             }
-            pSort->aDefer[nDefer].pTab = pExpr->pTab;
+            pSort->aDefer[nDefer].pTab = pExpr->x.pTab;
             pSort->aDefer[nDefer].iCsr = pExpr->iTable;
             pSort->aDefer[nDefer].nKey = nKey;
             nDefer++;
@@ -1680,7 +1686,7 @@ static const char *columnTypeImpl(
         break;
       }
 
-      assert( pTab && pExpr->pTab==pTab );
+      assert( pTab && pExpr->eX==EX_Tab && pExpr->x.pTab==pTab );
       if( pS ){
         /* The "table" is actually a sub-select or a view in the FROM clause
         ** of the SELECT statement. Return the declaration type and origin
@@ -1865,7 +1871,8 @@ static void generateColumnNames(
 
     assert( p!=0 );
     assert( p->op!=TK_AGG_COLUMN );  /* Agg processing has not run yet */
-    assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
+    /* Covering idx not yet coded: */
+    assert( p->op!=TK_COLUMN || (p->eX==EX_Tab && p->x.pTab!=0) );
     if( pEList->a[i].zName ){
       /* An AS clause always takes first priority */
       char *zName = pEList->a[i].zName;
@@ -1873,7 +1880,8 @@ static void generateColumnNames(
     }else if( srcName && p->op==TK_COLUMN ){
       char *zCol;
       int iCol = p->iColumn;
-      pTab = p->pTab;
+      assert( p->eX==EX_Tab );
+      pTab = p->x.pTab;
       assert( pTab!=0 );
       if( iCol<0 ) iCol = pTab->iPKey;
       assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
@@ -1965,7 +1973,9 @@ int sqlite3ColumnsFromExprList(
       if( pColExpr->op==TK_COLUMN ){
         /* For columns use the column name name */
         int iCol = pColExpr->iColumn;
-        Table *pTab = pColExpr->pTab;
+        Table *pTab;
+        assert( pColExpr->eX==EX_Tab );
+        pTab = pColExpr->x.pTab;
         assert( pTab!=0 );
         if( iCol<0 ) iCol = pTab->iPKey;
         zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
index 0efbecf8445a55076605f6a2abe285420525962f..ce8ff782cfa576cc6ddbf5eb203bc58feb3431b1 100644 (file)
@@ -2437,6 +2437,8 @@ struct Expr {
     Expr *pRight;        /* Right subnode */
     ExprList *pList;     /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
     Select *pSelect;     /* EP_xIsSelect and op = IN, EXISTS, SELECT */
+    Table *pTab;         /* Table for TK_COLUMN expressions. Can be NULL
+                         ** for a column of an index on an expression */
   } x;
 
   /* If the EP_Reduced flag is set in the Expr.flags mask, then no
@@ -2461,8 +2463,6 @@ struct Expr {
                          ** TK_COLUMN: the value of p5 for OP_Column
                          ** TK_AGG_FUNCTION: nesting depth */
   AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
-  Table *pTab;           /* Table for TK_COLUMN expressions.  Can be NULL
-                         ** for a column of an index on an expression */
 #ifndef SQLITE_OMIT_WINDOWFUNC
   Window *pWin;          /* Window definition for window functions */
 #endif
@@ -3811,10 +3811,12 @@ void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
 Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
 void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
 void sqlite3PExprAddExprList(Parse*, Expr*, ExprList*);
+void sqlite3ExprAddTab(sqlite3*, Expr*, Table*);
 Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
 Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
 void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
 void sqlite3ExprDelete(sqlite3*, Expr*);
+void sqlite3ExprClearXUnion(sqlite3*,Expr*);
 ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
 ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
 void sqlite3ExprListSetSortOrder(ExprList*,int);
index 7b459be7b6d06705b86e06f507a73eb16adf9fd2..47e390fc6985cbd9a3a826541a1ed8b919c34297 100644 (file)
@@ -1053,8 +1053,7 @@ FuncDef *sqlite3VtabOverloadFunction(
   /* Check to see the left operand is a column in a virtual table */
   if( NEVER(pExpr==0) ) return pDef;
   if( pExpr->op!=TK_COLUMN ) return pDef;
-  pTab = pExpr->pTab;
-  if( pTab==0 ) return pDef;
+  if( pExpr->eX!=EX_Tab || (pTab = pExpr->x.pTab)==0 ) return pDef;
   if( !IsVirtual(pTab) ) return pDef;
   pVtab = sqlite3GetVTable(db, pTab)->pVtab;
   assert( pVtab!=0 );
index 86b4ad903610531b442b92cbcf5dffdb33f6d064..0bb44153770eb444ad5de537906e3b4dafdcca30 100644 (file)
@@ -1122,7 +1122,7 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
     pExpr->op = TK_COLUMN;
     pExpr->iTable = pX->iIdxCur;
     pExpr->iColumn = pX->iIdxCol;
-    pExpr->pTab = 0;
+    /* pExpr->pTab = 0; */
     return WRC_Prune;
   }else{
     return WRC_Continue;
index b609521f7d2bafdcd53f3e0b1ebbdf45edf9b62d..cc5fad4fd6801b3a13ac35a1fa671a402725f1d7 100644 (file)
@@ -282,8 +282,9 @@ static int isLikeOrGlob(
          || (zNew[0]+1=='0' && iTo==1)
         ){
           if( pLeft->op!=TK_COLUMN 
-           || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
-           || IsVirtual(pLeft->pTab)  /* Value might be numeric */
+           || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+           || NEVER(pLeft->eX!=EX_Tab)
+           || IsVirtual(pLeft->x.pTab)  /* Value might be numeric */
           ){
             sqlite3ExprDelete(db, pPrefix);
             sqlite3ValueFree(pVal);
@@ -384,7 +385,7 @@ static int isAuxiliaryVtabOperator(
     **       MATCH(expression,vtab_column)
     */
     pCol = pList->a[1].pExpr;
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+    if( pCol->op==TK_COLUMN && pCol->eX==EX_Tab && IsVirtual(pCol->x.pTab) ){
       for(i=0; i<ArraySize(aOp); i++){
         if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
           *peOp2 = aOp[i].eOp2;
@@ -406,12 +407,12 @@ static int isAuxiliaryVtabOperator(
     ** with function names in an arbitrary case.
     */
     pCol = pList->a[0].pExpr;
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+    if( pCol->op==TK_COLUMN && pCol->eX==EX_Tab && IsVirtual(pCol->x.pTab) ){
       sqlite3_vtab *pVtab;
       sqlite3_module *pMod;
       void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
       void *pNotUsed;
-      pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
+      pVtab = sqlite3GetVTable(db, pCol->x.pTab)->pVtab;
       assert( pVtab!=0 );
       assert( pVtab->pModule!=0 );
       pMod = (sqlite3_module *)pVtab->pModule;
@@ -428,11 +429,12 @@ static int isAuxiliaryVtabOperator(
   }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
     int res = 0;
     Expr *pLeft = pExpr->pLeft;
-    Expr *pRight = pExpr->x.pRight;
-    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
+    Expr *pRight = 0;
+    if( pLeft->op==TK_COLUMN && pLeft->eX==EX_Tab && IsVirtual(pLeft->x.pTab) ){
       res++;
     }
-    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
+    if( pExpr->eX==EX_Right && (pRight = pExpr->x.pRight)->op==TK_COLUMN
+     && pRight->eX==EX_Tab && IsVirtual(pRight->x.pTab) ){
       res++;
       SWAP(Expr*, pLeft, pRight);
     }
@@ -1616,7 +1618,8 @@ void sqlite3WhereTabFuncArgs(
     if( pColRef==0 ) return;
     pColRef->iTable = pItem->iCursor;
     pColRef->iColumn = k++;
-    pColRef->pTab = pTab;
+    pColRef->x.pTab = pTab;
+    pColRef->eX = EX_Tab;
     pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
                          sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
     whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);