Compare commits

...

3 Commits

Author SHA1 Message Date
dan 6ec7af206e Ensure that the "push-down" optimization does not push constraints down into compound queries if any of the component queries uses window functions.
FossilOrigin-Name: 2011e83213284b9b5d88a084b35febf026b2276ac9e5f4d439cc22771064444a
2020-06-05 14:53:15 +00:00
drh e801270356 ALWAYS() and NEVER() macros added due to unreachable branches arising
from the previous check-in.

FossilOrigin-Name: 13ffedab9bd22c6e5a3fd54dd44a7a3e6d5375f1a14fed67638c541c0edc51dd
2020-06-05 14:25:45 +00:00
drh 2b72b5df07 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
2020-06-05 14:10:23 +00:00
10 changed files with 98 additions and 54 deletions
+14 -14
View File
@@ -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 Ensure\sthat\sthe\s"push-down"\soptimization\sdoes\snot\spush\sconstraints\sdown\sinto\scompound\squeries\sif\sany\sof\sthe\scomponent\squeries\suses\swindow\sfunctions.
D 2020-06-05T14:53:15.658
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 2c5582c50443b689dbd94644e7d12257ba0d8c73da4f9ad384906b320ab2ae90
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 66f149f309e67d6563374e284bb8439057cb970e47f23058d9e5270208d274be
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 39a00a8bc89596dfb37c16afcbb1d33de5085b9963564b58aafe1566d08c0881
F src/select.c 1708c0ef6bc6c9b24ba74193a90e4aab11e90a1fe7287f0da5f7b5c072afbdb4
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
@@ -1727,7 +1727,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 502a3e72fce895aaaa633bbe709f6de3c24eed3ecb8098ab9fb8b47584b4452c
F test/window1.test 7383659a950375a9d3e73f4369862b4c5ccf3f16f325afb59047b983d9f80ebf
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
@@ -1866,7 +1866,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 2827c0a186596299e43eb3e7378eea462d2b060b2c3388ce5cb2bc8e0b43999e
R ee30fc3f51275fe44c86656d5c06c7d7
U drh
Z bb7b42e3c07b2ab8975730fed03b093c
P 13ffedab9bd22c6e5a3fd54dd44a7a3e6d5375f1a14fed67638c541c0edc51dd
R 347278490fe2ccfd884b60a933a708ab
U dan
Z 64101dcaa00515d1f908e96884ac10c0
+1 -1
View File
@@ -1 +1 @@
c1c8937a30feff6aa4385b0c264fd8e70d54422a0629c2ce38082d85d3334a57
2011e83213284b9b5d88a084b35febf026b2276ac9e5f4d439cc22771064444a
+3 -7
View 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;
@@ -5657,13 +5659,7 @@ struct SrcCount {
** Count the number of references to columns.
*/
static int exprSrcCount(Walker *pWalker, Expr *pExpr){
/* There was once a NEVER() on the second term on the grounds that
** sqlite3FunctionUsesThisSrc() was always called before
** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
** been converted into TK_AGG_COLUMN. But this is no longer true due
** to window functions - sqlite3WindowRewrite() may now indirectly call
** FunctionUsesThisSrc() when creating a new sub-select. */
if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){
int i;
struct SrcCount *p = pWalker->u.pSrcCount;
SrcList *pSrc = p->pSrc;
+5
View 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
+8
View File
@@ -1715,6 +1715,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
return WRC_Abort;
}
}
}else if( p->pWin && ALWAYS( (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
+16 -29
View File
@@ -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
@@ -4425,11 +4411,14 @@ static int pushDownWhereTerms(
){
Expr *pNew;
int nChng = 0;
Select *pSel;
if( pWhere==0 ) return 0;
if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSubq->pWin ) return 0; /* restriction (6) */
for(pSel=pSubq; pSel; pSel=pSel->pPrior){
if( pSel->pWin ) return 0; /* restriction (6) */
}
#endif
#ifdef SQLITE_DEBUG
@@ -5765,6 +5754,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 +5795,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));
@@ -6143,7 +6122,7 @@ int sqlite3Select(
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
&& sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
#ifndef SQLITE_OMIT_WINDOWFUNC
&& p->pWin==0
&& ALWAYS(p->pWin==0)
#endif
){
p->selFlags &= ~SF_Distinct;
@@ -6790,6 +6769,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"));
+22 -1
View 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
+1 -1
View 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++){
+1 -1
View 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 */
+27
View File
@@ -1743,5 +1743,32 @@ do_execsql_test 53.0 {
WHERE a.c);
} {4 4 4 4}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 54.1 {
CREATE TABLE t1(a VARCHAR(20), b FLOAT);
INSERT INTO t1 VALUES('1',10.0);
}
do_execsql_test 54.2 {
SELECT * FROM (
SELECT sum(b) OVER() AS c FROM t1
UNION
SELECT b AS c FROM t1
) WHERE c>10;
}
do_execsql_test 54.3 {
INSERT INTO t1 VALUES('2',5.0);
INSERT INTO t1 VALUES('3',15.0);
}
do_execsql_test 54.4 {
SELECT * FROM (
SELECT sum(b) OVER() AS c FROM t1
UNION
SELECT b AS c FROM t1
) WHERE c>10;
} {15.0 30.0}
finish_test