]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
New optimizations to bring performance up to parity with the code before
authordrh <>
Fri, 3 Jul 2026 10:15:36 +0000 (10:15 +0000)
committerdrh <>
Fri, 3 Jul 2026 10:15:36 +0000 (10:15 +0000)
adding EXCLUDE.  Raise an error if an EXCLUDE term is not a column.

FossilOrigin-Name: 40bd447c4bd5412f8babafa405a3d0dc739107e6b450ca23da4659eeb964e8b9

manifest
manifest.uuid
src/parse.y
src/select.c
src/treeview.c
src/trigger.c

index c9f7bec7d08ac2f27fa9841705d3f2fcd341755a..0c7aaaeafff0cfbec72b0161db688f5a690e6c6f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\sperformance\soptimization\s-\sonly\suse\ssqlite3ExprAttachSubtrees()\nin\sone\splace,\sso\sthat\scompilers\swill\sin-line\sit.
-D 2026-07-03T09:15:50.130
+C New\soptimizations\sto\sbring\sperformance\sup\sto\sparity\swith\sthe\scode\sbefore\nadding\sEXCLUDE.\s\sRaise\san\serror\sif\san\sEXCLUDE\sterm\sis\snot\sa\scolumn.
+D 2026-07-03T10:15:36.936
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -729,7 +729,7 @@ F src/os_win.c 1227a3e962b017d676d985a8aec0d64f273991931ea0a0b99773651102f62df4
 F src/os_win.h c06ccc3a090cf54202ea58981c298817f3309d4c9e4d52ad0a02927346493721
 F src/pager.c 678ee3b68638ee427cc1b071b11181d0f2a827f6cb4d6ec7c12d5fa5f6a752d0
 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
-F src/parse.y 7e664cf58cd7b6aef13c308d6ad8e4cfaa5656ff2a4e8c946367853383813dd1
+F src/parse.y 70d0a993d4646c26e0d7e79b2661476ba296d2eacc4001845be302cbff18c725
 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
 F src/pcache.h 092b758d2c5e4dabb30eae46d8dfad77c0f70b16bf3ff1943f7a232b0fe0d4ba
 F src/pcache1.c d7ee0f95992501a65379f620b3de1430b64e52e397769938668a9fd9dd1c8145
@@ -739,7 +739,7 @@ F src/printf.c b480176bd0aaed9d64e804cfa3ca27fc585f65a73e7c7ca2fe9b9016db2cf6d5
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c d0724113da9f5c0430d2052808ce59519f51ae7c4fbb1f5ef21fe3a832956086
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 485421e23a9ee3c46252a3b5c76273a134540be4c40f0ca6c141dcc3ecdc1be9
+F src/select.c 362fffc28c029477bd5abd198b442fd3dfa65372058f61b82e093ede2b4d24cf
 F src/shell.c.in a4e83895cfa336065ad7f7a7dea8fc2a19d050f7ce7466621c67208acaac9e44
 F src/sqlite.h.in d9ec41feb4cd804e68b174328b43beb3f1f71bba13e1c7a439efb826d301cccc
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
@@ -799,8 +799,8 @@ F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 85d8b9f05f78211c61e3739ab5db761d7118766d1916ae7f2764735106bc4e13
 F src/tokenize.c e9d52d9f7374d82dadcd11726bea8a597d43709d6672704f3f0375bf1d726912
-F src/treeview.c d4949e9bb73b5ee6d850213225a30d4f8f2988582d4f7166080644aadcc3e94c
-F src/trigger.c 5028874dd1f4fd3085bacd55c30114b5ad651525508656f65af09adf227181d5
+F src/treeview.c 71150fd27dd554a1ea58b12b19dab0d181fdcf99a237503625a145aa9f7ba3a8
+F src/trigger.c 6029c1336adff008bbefd275aaa94d393506a451c1caa8afccc17d5fbca7d11e
 F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
 F src/upsert.c dd9f0fcccbfb4f20e1026a21a7254ba3f2c08e9cfa92affaff5b5ec3b00ea549
 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
@@ -2210,8 +2210,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P faa3a3fc27039635c10f8e5baa25944bff360f3e1a400e50f226a111ef140fe4
-R 251b904df42892dfd675ec11582ed36a
+P 8b050ed8075f17e3da4022f429c6a772079b9d24426e316d428824951ec11c01
+R 731e90565987a3e60a336af228a967b7
 U drh
-Z 3e1148d9838c583d8ac2847794b11822
+Z 846f7fedf62f477816791a88c1b91b59
 # Remove this line to create a well-formed Fossil manifest.
index 09e34386620541dcd8f7bd7a0d31eddb181cac50..27e40b3cd8c22925a3f75cd75b3cd4f3dbdbf121 100644 (file)
@@ -1 +1 @@
-8b050ed8075f17e3da4022f429c6a772079b9d24426e316d428824951ec11c01
+40bd447c4bd5412f8babafa405a3d0dc739107e6b450ca23da4659eeb964e8b9
index fbf87a7583546757457fce40501106c9a6402730..b50c4d954aa8e0aa51e9b1d5bc62fd22655523ee 100644 (file)
@@ -736,12 +736,12 @@ selcollist(A) ::= sclp(A) scanpt STAR(X) colexcl(E). {
   A = sqlite3ExprListAppend(pParse, A, p);
 }
 selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR(Y) colexcl(E). {
-  Expr *pRight, *pLeft, *pDot;
-  pRight = parserWildcardExpr(pParse->db, E);
-  sqlite3ExprSetErrorOffset(pRight, (int)(Y.z - pParse->zTail));
-  pLeft = tokenExpr(pParse, TK_ID, X);
-  pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
-  A = sqlite3ExprListAppend(pParse,A, pDot);
+  Expr *p = parserWildcardExpr(pParse->db, E);
+  sqlite3ExprSetErrorOffset(p, (int)(Y.z - pParse->zTail));
+  if( p ){
+    p->pLeft = tokenExpr(pParse, TK_ID, X);
+  }
+  A = sqlite3ExprListAppend(pParse, A, p);
 }
 
 // The colexcl nonterminal represents the EXCLUDE clause that can
index 89b64e19c442fd596f6c714cab25a88eab461bda..a1bc5da61f4c07691b2c44c99bede550cc398a2d 100644 (file)
@@ -5964,24 +5964,25 @@ static int inAnyUsingClause(
 **
 */
 static int selectExpander(Walker *pWalker, Select *p){
-  Parse *pParse = pWalker->pParse;
+  Parse *pParse;
+  sqlite3 *db;
   int i, j, k, rc;
   SrcList *pTabList;
   ExprList *pEList;
   SrcItem *pFrom;
-  sqlite3 *db = pParse->db;
   Expr *pE, *pRight, *pExpr;
-  u16 selFlags = p->selFlags;
   u32 elistFlags = 0;
 
+  if( p->selFlags & SF_Expanded ){
+    return WRC_Prune;
+  }
   p->selFlags |= SF_Expanded;
+  pParse = pWalker->pParse;
+  db = pParse->db;
   if( db->mallocFailed  ){
     return WRC_Abort;
   }
   assert( p->pSrc!=0 );
-  if( (selFlags & SF_Expanded)!=0 ){
-    return WRC_Prune;
-  }
   if( pWalker->eCode ){
     /* Renumber selId because it has been copied from a view */
     p->selId = ++pParse->nSelect;
@@ -6110,9 +6111,6 @@ static int selectExpander(Walker *pWalker, Select *p){
   for(k=0; k<pEList->nExpr; k++){
     pE = pEList->a[k].pExpr;
     if( pE->op==TK_ASTERISK ) break;
-    assert( pE->op!=TK_DOT || pE->pRight!=0 );
-    assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
-    if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
     elistFlags |= pE->flags;
   }
   if( k<pEList->nExpr ){
@@ -6132,9 +6130,7 @@ static int selectExpander(Walker *pWalker, Select *p){
       elistFlags |= pE->flags;
       pRight = pE->pRight;
       assert( pE->op!=TK_DOT || pRight!=0 );
-      if( pE->op!=TK_ASTERISK
-       && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
-      ){
+      if( pE->op!=TK_ASTERISK ){
         /* This particular expression does not need to be expanded.
         */
         pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
@@ -6151,21 +6147,25 @@ static int selectExpander(Walker *pWalker, Select *p){
         char *zTName = 0;       /* text of name of TABLE */
         int iErrOfst;
         ExprList *pExclude;     /* The EXCLUDE clause, or NULL */
-        if( pE->op==TK_DOT ){
-          assert( (selFlags & SF_NestedFrom)==0 );
-          assert( pE->pLeft!=0 );
-          assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
-          zTName = pE->pLeft->u.zToken;
-          assert( ExprUseWOfst(pE->pLeft) );
-          iErrOfst = pE->pRight->w.iOfst;
-          assert( ExprUseXList(pE->pRight) );
-          pExclude = pE->pRight->x.pList;
-        }else{
-          assert( ExprUseWOfst(pE) );
-          iErrOfst = pE->w.iOfst;
-          assert( ExprUseXList(pE) );
-          pExclude = pE->x.pList;
+        assert( ExprUseWOfst(pE) );
+        iErrOfst = pE->w.iOfst;
+        assert( ExprUseXList(pE) );
+        pExclude = pE->x.pList;
+        assert( pE->pLeft==0 || pE->pLeft->op==TK_ID );
+        assert( pE->pLeft==0 || !ExprHasProperty(pE->pLeft, EP_IntValue) );
+        zTName = pE->pLeft ? pE->pLeft->u.zToken : 0;
+
+#ifdef SQLITE_DEBUG
+        /* If there is an EXCLUDE clause, make sure fg.done is initialized
+        ** to zero, which should have occurred in the parser */
+        if( pExclude ){
+          int kk;
+          for(kk=0; kk<pExclude->nExpr; kk++){
+            assert( pExclude->a[kk].fg.done==0 );
+          }
         }
+#endif
+
         for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
           int nAdd;                    /* Number of cols including rowid */
           Table *pTab = pFrom->pSTab;  /* Table for this data source */
@@ -6197,7 +6197,7 @@ static int selectExpander(Walker *pWalker, Select *p){
           }
           if( i+1<pTabList->nSrc
            && pFrom[1].fg.isUsing
-           && (selFlags & SF_NestedFrom)!=0
+           && (p->selFlags & SF_NestedFrom)!=0
           ){
             int ii;
             pUsing = pFrom[1].u3.pUsing;
@@ -6219,7 +6219,7 @@ static int selectExpander(Walker *pWalker, Select *p){
           }
 
           nAdd = pTab->nCol;
-          if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++;
+          if( VisibleRowid(pTab) && (p->selFlags & SF_NestedFrom)!=0 ) nAdd++;
           for(j=0; j<nAdd; j++){
             const char *zName;
             struct ExprList_item *pEx; /* Matching pExclude term */
@@ -6255,7 +6255,7 @@ static int selectExpander(Walker *pWalker, Select *p){
               }
               if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0
                && zTName==0
-               && (selFlags & (SF_NestedFrom))==0
+               && (p->selFlags & (SF_NestedFrom))==0
               ){
                 continue;
               }
@@ -6267,6 +6267,7 @@ static int selectExpander(Walker *pWalker, Select *p){
                 for(kk=0; kk<pExclude->nExpr; kk++){
                   if( sqlite3_stricmp(pExclude->a[kk].zEName,zName)==0 ){
                     pEx = &pExclude->a[kk];
+                    pEx->fg.done = 1;
                     break;
                   }
                 }
@@ -6276,7 +6277,7 @@ static int selectExpander(Walker *pWalker, Select *p){
             assert( zName );
             tableSeen = 1;
 
-            if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){
+            if( i>0 && zTName==0 && (p->selFlags & SF_NestedFrom)==0 ){
               if( pFrom->fg.isUsing
                && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0
               ){
@@ -6291,7 +6292,7 @@ static int selectExpander(Walker *pWalker, Select *p){
               pRight = sqlite3Expr(db, TK_ID, zName);
               if( (pTabList->nSrc>1
                    && (  (pFrom->fg.jointype & JT_LTORJ)==0
-                       || (selFlags & SF_NestedFrom)!=0
+                       || (p->selFlags & SF_NestedFrom)!=0
                        || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1)
                       )
                   )
@@ -6318,7 +6319,7 @@ static int selectExpander(Walker *pWalker, Select *p){
             }
             pX = &pNew->a[pNew->nExpr-1];
             assert( pX->zEName==0 );
-            if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
+            if( (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
               if( pNestedFrom && (!ViewCanHaveRowid || j<pNestedFrom->nExpr) ){
                 assert( j<pNestedFrom->nExpr );
                 pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName);
@@ -6347,6 +6348,16 @@ static int selectExpander(Walker *pWalker, Select *p){
             }
           }
         }
+        if( pExclude ){
+          int kk;
+          for(kk=0; kk<pExclude->nExpr; kk++){
+            if( pExclude->a[kk].fg.done==0 ){
+              sqlite3ErrorMsg(pParse, "no column named \"%s\"",
+                              pExclude->a[kk].zEName);
+              break;
+            }
+          }
+        }
         if( !tableSeen ){
           if( zTName ){
             sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
@@ -6377,6 +6388,7 @@ static int selectExpander(Walker *pWalker, Select *p){
   return WRC_Continue;
 }
 
+
 #if SQLITE_DEBUG
 /*
 ** Always assert.  This xSelectCallback2 implementation proves that the
index 81c7254f31cc4fefbc781dc5199eef06872657f7..9d939a2eb58e8aa2dc6eb146fed0f2aa46583bc9 100644 (file)
@@ -883,7 +883,13 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
       break;
     }
     case TK_ASTERISK: {
-      sqlite3TreeViewLine(pView, "ASTERISK");
+      if( pExpr->pLeft ){
+        assert( pExpr->pLeft->op==TK_ID );
+        assert( !ExprHasProperty(pExpr->pLeft, EP_IntValue) );
+        sqlite3TreeViewLine(pView, "\"%w\".ASTERISK", pExpr->pLeft->u.zToken);
+      }else{
+        sqlite3TreeViewLine(pView, "ASTERISK");
+      }
       if( pExpr->x.pList ){
         sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, "EXCLUDE");
       }
@@ -966,7 +972,9 @@ void sqlite3TreeViewBareExprList(
         fprintf(stdout, "\n");
         fflush(stdout);
       }
-      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
+      if( pList->a[i].fg.eEName!=ENAME_EXCLUDE ){
+        sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
+      }
       if( j || zName || sortFlags ){
         sqlite3TreeViewPop(&pView);
       }
index 6ac9c1ffdbf77aade44ee2b54d67563cb7740b92..991fa12914e0ebb17005ae76a6e1c0916be8378b 100644 (file)
@@ -893,12 +893,10 @@ static int isAsteriskTerm(
   Expr *pTerm         /* A term in the RETURNING clause */
 ){
   assert( pTerm!=0 );
-  if( pTerm->op==TK_ASTERISK ) return 1;
-  if( pTerm->op!=TK_DOT ) return 0;
-  assert( pTerm->pRight!=0 );
-  assert( pTerm->pLeft!=0 );
-  if( pTerm->pRight->op!=TK_ASTERISK ) return 0;
-  sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards");
+  if( pTerm->op!=TK_ASTERISK ) return 0;
+  if( pTerm->pLeft!=0 ){
+    sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards");
+  }
   return 1;
 }