]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Move the parse tree rewrite for window functions earlier in the process,
authordrh <drh@noemail.net>
Fri, 5 Jun 2020 14:10:23 +0000 (14:10 +0000)
committerdrh <drh@noemail.net>
Fri, 5 Jun 2020 14:10:23 +0000 (14:10 +0000)
before sqlite3ExprAnalyzeAggregates() has run.  Add new assert()s to verify
that aggregate analysis always remains valid until the end of SELECT
processing.

FossilOrigin-Name: fe702aa08c3b93a5ea6cb383ff6794c841d96eac4ce324e1ecc14dcb624c5be6

manifest
manifest.uuid
src/expr.c
src/global.c
src/resolve.c
src/select.c
src/sqliteInt.h
src/test1.c
src/window.c

index ca4608031d36bf912cac0875ea4e3d3ce52e1959..7e12f2a5e827d37bb9a50dc36cafa04d4bf78940 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C In\sthe\sdebugging\streeview\soutput,\schange\sthe\sname\sof\s"SELECT-expr"\sexpression\nnodes\sto\sbe\s"subquery-expr",\sso\sas\sto\snot\sconfuse\sthem\swith\sactual\sSELECT\nnodes.
-D 2020-06-05T04:01:50.831
+C Move\sthe\sparse\stree\srewrite\sfor\swindow\sfunctions\searlier\sin\sthe\sprocess,\nbefore\ssqlite3ExprAnalyzeAggregates()\shas\srun.\s\sAdd\snew\sassert()s\sto\sverify\nthat\saggregate\sanalysis\salways\sremains\svalid\suntil\sthe\send\sof\sSELECT\nprocessing.
+D 2020-06-05T14:10:23.063
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -485,11 +485,11 @@ F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384
 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
 F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f
 F src/delete.c 88047c8e59878c920fce14582bc1dde4d81157d1ca5ffdf36c2907e6d41996c4
-F src/expr.c 4750c6b63419eefb24c8a6158b9287dea2a9714b4e6e297e25805505c9f73b6c
+F src/expr.c ab412878f35cd561aa42fd8022fbf87654fe4181c9a1b14a8abb1018a9253349
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
 F src/func.c 2333eb4277f55a5efdc12ef754e7d7ec9105d257b2fd00301d23ce1e8fa67dc0
-F src/global.c 79a988b56b06ce2d08ebefe1d35da9aa25b3851faa47ea5233361c4827185a64
+F src/global.c 0409ae635839e0bef26a69b68be64126ab6cba62ac19bd7694f1652e591c4c17
 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
@@ -531,19 +531,19 @@ F src/pragma.h 8168e588536bffd95319451f34e9a754dc37d205ebe433031a7813c5b286beae
 F src/prepare.c aeb3ba661e2666dab15c4b5c55f6eb816f01d20e35fa860bb807e4a3b36e1e27
 F src/printf.c 94b5419ad0a17269f76a9e968ca19cf9fa37617abed2e246fc48844e511b6bc6
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c c2008519a0654f1e7490e9281ed0397d0f14bb840d81f0b96946248afcbdb25d
+F src/resolve.c ab7add324c929f6192cecb3ca8090520200b505b7eb3e8accb8a73d41c4e4a6e
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 39a00a8bc89596dfb37c16afcbb1d33de5085b9963564b58aafe1566d08c0881
+F src/select.c 1204f18a116dbb8058a2f2d9e5930011b3e56ddf3f896cb1d0b3c52dd3adde1a
 F src/shell.c.in c6e26593f2738eefded08a39204bf6b48db135cdfaa458c26ffe57055b4fe365
 F src/sqlite.h.in 74342b41e9d68ff9e56b192009046f8dd0aa2bd76ce1a588f330de614ba61de7
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 2d1af80082edffd71c6f96f70ad1ce6a4fb46615ad10291fc77fe0dea9ff0197
-F src/sqliteInt.h f5e422635c089adf60260e1947ecfaf68dd333bda20c2afdd60323357d8540a0
+F src/sqliteInt.h c8e3e65ac0af3e958ce23542ce3861ec717b01abd418702cd05e0d28c9279150
 F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71
-F src/test1.c 5e8b8cc54e8c88906ea8a084387aa79bad245e539f4cee73149e5c0527e1db16
+F src/test1.c e9f68f157f8fd027ee4c32c4b427f4eed274749bfb745427e2d954fa89d95ad3
 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
@@ -624,7 +624,7 @@ F src/where.c 7bcc07ff56d03d73308245135d96de46d2faeaee628bd4badf0bae60ae6a31fe
 F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c
 F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d
 F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
-F src/window.c 66c5fd1e48af7581cf90b97700268294f4da4037f120f367715f912e1148d3f9
+F src/window.c a3846ac6d00b6315eebda9a8e85e80bca4b9a465e3c52395c1ad3a3901ec7500
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1866,7 +1866,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 2827c0a186596299e43eb3e7378eea462d2b060b2c3388ce5cb2bc8e0b43999e
-R ee30fc3f51275fe44c86656d5c06c7d7
+P c1c8937a30feff6aa4385b0c264fd8e70d54422a0629c2ce38082d85d3334a57
+R ed5f5dced79cdaba8115cb0cef493592
+T *branch * early-winfunc-rewrite
+T *sym-early-winfunc-rewrite *
+T -sym-trunk *
 U drh
-Z bb7b42e3c07b2ab8975730fed03b093c
+Z 5123be131a9e9f976e9dd48d4565f135
index 5c9bd2c32c453116d5495077251c9e956074d3c8..a8cdf8b1a584ba8c39851a153023475d49492a2c 100644 (file)
@@ -1 +1 @@
-c1c8937a30feff6aa4385b0c264fd8e70d54422a0629c2ce38082d85d3334a57
\ No newline at end of file
+fe702aa08c3b93a5ea6cb383ff6794c841d96eac4ce324e1ecc14dcb624c5be6
\ No newline at end of file
index 496177a5c71c7a0a9b20d51ba14e058c646a20d4..414558bd87411513e06f93624e877e52fd6d8952 100644 (file)
@@ -3811,6 +3811,7 @@ expr_code_doover:
       AggInfo *pAggInfo = pExpr->pAggInfo;
       struct AggInfo_col *pCol;
       assert( pAggInfo!=0 );
+      assert( AggInfoValid(pAggInfo) );
       assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
       pCol = &pAggInfo->aCol[pExpr->iAgg];
       if( !pAggInfo->directMode ){
@@ -4119,6 +4120,7 @@ expr_code_doover:
         assert( !ExprHasProperty(pExpr, EP_IntValue) );
         sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
       }else{
+        assert( AggInfoValid(pInfo) );
         return pInfo->aFunc[pExpr->iAgg].iMem;
       }
       break;
index aeddada6f217f34e5fa847f921ef59c34f9e1c87..c6bdbad1bdb63f63f95525f9f7abb6cc57a909ef 100644 (file)
@@ -300,6 +300,11 @@ sqlite3_uint64 sqlite3NProfileCnt = 0;
 int sqlite3PendingByte = 0x40000000;
 #endif
 
+/*
+** Flags for select tracing and the ".selecttrace" macro of the CLI
+*/
+/**/ u32 sqlite3SelectTrace = 0;
+
 #include "opcodes.h"
 /*
 ** Properties of opcodes.  The OPFLG_INITIALIZER macro is
index aff6dbeadb77dd00c1c3e49bd9d2687d29ac41ab..f5e68ab524da77dfc2d44eb0eb25eed665709fbd 100644 (file)
@@ -1715,6 +1715,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
           return WRC_Abort;
         }
       }
+    }else if( p->pWin && (p->selFlags & SF_WinRewrite)==0 ){
+      sqlite3WindowRewrite(pParse, p);
+#if SELECTTRACE_ENABLED
+      if( (sqlite3SelectTrace & 0x108)!=0 ){
+        SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
+        sqlite3TreeViewSelect(0, p, 0);
+      }
+#endif
     }
 #endif
 
index 7ff2b5d347483f5344b603f11eacd8efee641d09..747ed1ea11f9ec8823acd6f7c60ff8f4a2999ab1 100644 (file)
 */
 #include "sqliteInt.h"
 
-/*
-** Trace output macros
-*/
-#if SELECTTRACE_ENABLED
-/***/ int sqlite3SelectTrace = 0;
-# define SELECTTRACE(K,P,S,X)  \
-  if(sqlite3SelectTrace&(K))   \
-    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
-    sqlite3DebugPrintf X
-#else
-# define SELECTTRACE(K,P,S,X)
-#endif
-
-
 /*
 ** An instance of the following object is used to record information about
 ** how to process the DISTINCT keyword, to simplify passing that information
@@ -5765,6 +5751,9 @@ int sqlite3Select(
   }
   if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
   memset(&sAggInfo, 0, sizeof(sAggInfo));
+#ifdef SQLITE_DEBUG
+  sAggInfo.iAggMagic = SQLITE_AGGMAGIC_VALID;
+#endif
 #if SELECTTRACE_ENABLED
   SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
   if( sqlite3SelectTrace & 0x100 ){
@@ -5803,19 +5792,6 @@ int sqlite3Select(
     generateColumnNames(pParse, p);
   }
 
-#ifndef SQLITE_OMIT_WINDOWFUNC
-  rc = sqlite3WindowRewrite(pParse, p);
-  if( rc ){
-    assert( db->mallocFailed || pParse->nErr>0 );
-    goto select_end;
-  }
-#if SELECTTRACE_ENABLED
-  if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
-    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
-    sqlite3TreeViewSelect(0, p, 0);
-  }
-#endif
-#endif /* SQLITE_OMIT_WINDOWFUNC */
   pTabList = p->pSrc;
   isAgg = (p->selFlags & SF_Aggregate)!=0;
   memset(&sSort, 0, sizeof(sSort));
@@ -6790,6 +6766,14 @@ int sqlite3Select(
 select_end:
   sqlite3ExprListDelete(db, pMinMaxOrderBy);
   sqlite3DbFree(db, sAggInfo.aCol);
+#ifdef SQLITE_DEBUG
+  for(i=0; i<sAggInfo.nFunc; i++){
+    assert( sAggInfo.aFunc[i].pExpr!=0 );
+    assert( sAggInfo.aFunc[i].pExpr->pAggInfo==&sAggInfo );
+    sAggInfo.aFunc[i].pExpr->pAggInfo = 0;
+  }
+  sAggInfo.iAggMagic = 0;
+#endif
   sqlite3DbFree(db, sAggInfo.aFunc);
 #if SELECTTRACE_ENABLED
   SELECTTRACE(0x1,pParse,p,("end processing\n"));
index e37ed673afab80a9272a2a15eb36a58f7369da46..c2f09aaf52f54fb40210f8637ff9c1e2ef6cc090 100644 (file)
@@ -976,7 +976,12 @@ typedef INT16_TYPE LogEst;
 */
 #if defined(SQLITE_ENABLE_SELECTTRACE)
 # define SELECTTRACE_ENABLED 1
+# define SELECTTRACE(K,P,S,X)  \
+  if(sqlite3SelectTrace&(K))   \
+    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
+    sqlite3DebugPrintf X
 #else
+# define SELECTTRACE(K,P,S,X)
 # define SELECTTRACE_ENABLED 0
 #endif
 
@@ -2523,8 +2528,23 @@ struct AggInfo {
     int iDistinct;           /* Ephemeral table used to enforce DISTINCT */
   } *aFunc;
   int nFunc;              /* Number of entries in aFunc[] */
+#ifdef SQLITE_DEBUG
+  u32 iAggMagic;          /* Sanity checking constant */
+#endif
 };
 
+/*
+** Allowed values for AggInfo.iAggMagic
+*/
+#define SQLITE_AGGMAGIC_VALID  0x05cadade
+
+/*
+** True if the AggInfo object is valid.  Used inside of assert() only.
+*/
+#ifdef SQLITE_DEBUG
+#  define AggInfoValid(P) ((P)->iAggMagic==SQLITE_AGGMAGIC_VALID)
+#endif
+
 /*
 ** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
 ** Usually it is 16-bits.  But if SQLITE_MAX_VARIABLE_NUMBER is greater
@@ -4546,10 +4566,11 @@ extern const unsigned char sqlite3UpperToLower[];
 extern const unsigned char sqlite3CtypeMap[];
 extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
 extern FuncDefHash sqlite3BuiltinFunctions;
+extern u32 sqlite3SelectTrace;
 #ifndef SQLITE_OMIT_WSD
 extern int sqlite3PendingByte;
 #endif
-#endif
+#endif /* !defined(SQLITE_AMALGAMATION) */
 #ifdef VDBE_PROFILE
 extern sqlite3_uint64 sqlite3NProfileCnt;
 #endif
index 29207d51acdd753c5d5d0393c5fc591a355f47c1..46cc8b1acd77ed69b6f3cf32fddd06bb1bf98314 100644 (file)
@@ -8164,7 +8164,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 #endif
 #endif
 #if defined(SQLITE_ENABLE_SELECTTRACE)
-  extern int sqlite3SelectTrace;
+  extern u32 sqlite3SelectTrace;
 #endif
 
   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
index 77ec8a02e0a94582d3fc135d4f8a5267c51dca84..86108b4cfb57cec05fe6057a9885e652edc30de8 100644 (file)
@@ -942,7 +942,7 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
 */
 int sqlite3WindowRewrite(Parse *pParse, Select *p){
   int rc = SQLITE_OK;
-  if( p->pWin && p->pPrior==0 && (p->selFlags & SF_WinRewrite)==0 ){
+  if( ALWAYS(p->pWin && (p->selFlags & SF_WinRewrite)==0) ){
     Vdbe *v = sqlite3GetVdbe(pParse);
     sqlite3 *db = pParse->db;
     Select *pSub = 0;             /* The subquery */