From: drh Date: Fri, 5 Jun 2020 14:10:23 +0000 (+0000) Subject: Move the parse tree rewrite for window functions earlier in the process, X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b72b5df0775d19631af357af2163feae2171380;p=thirdparty%2Fsqlite.git Move the parse tree rewrite for window functions earlier in the process, 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 --- diff --git a/manifest b/manifest index ca4608031d..7e12f2a5e8 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 5c9bd2c32c..a8cdf8b1a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1c8937a30feff6aa4385b0c264fd8e70d54422a0629c2ce38082d85d3334a57 \ No newline at end of file +fe702aa08c3b93a5ea6cb383ff6794c841d96eac4ce324e1ecc14dcb624c5be6 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 496177a5c7..414558bd87 100644 --- a/src/expr.c +++ b/src/expr.c @@ -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->iAggnColumn ); 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; diff --git a/src/global.c b/src/global.c index aeddada6f2..c6bdbad1bd 100644 --- a/src/global.c +++ b/src/global.c @@ -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 diff --git a/src/resolve.c b/src/resolve.c index aff6dbeadb..f5e68ab524 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -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 diff --git a/src/select.c b/src/select.c index 7ff2b5d347..747ed1ea11 100644 --- a/src/select.c +++ b/src/select.c @@ -14,20 +14,6 @@ */ #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; ipAggInfo==&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")); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e37ed673af..c2f09aaf52 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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 diff --git a/src/test1.c b/src/test1.c index 29207d51ac..46cc8b1acd 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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; ipWin && 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 */