Compare commits

...

1 Commits

Author SHA1 Message Date
drh 73e259b4a0 Add assert()s that verify that cursor numbers on subqueries are always
greater than outer cursor numbers.  Except, this is not always true in the
presence of query flattening.  We might need to relax that constraint.
This branch will probably become a dead-end.  For now it is saved for
reference.

FossilOrigin-Name: 6f4369666efb8eed84c3d60118baaf35d733ea906df983aeca2b0a475a6298a3
2021-11-08 16:38:08 +00:00
5 changed files with 76 additions and 10 deletions
+11 -8
View File
@@ -1,5 +1,5 @@
C Ensure\sthat\sthe\swindow\sfunction\srewrite\sdoes\snot\sleave\sthe\sparse\stree\nin\san\sinvalid\sstate\sthat\smight\scause\sproblems\sdownstream\sbefore\sthe\nerror\sis\srecognized\sand\sunwinds\sthe\sstack.\s\sAlso\stake\ssteps\ssuch\sthat\nan\sinvalid\sparse\stree\sdoes\snot\scause\sproblems\seven\sif\sit\sgoes\s\nunrecognized.\s\s\n[forum:/forumpost/398e9d5aa9|Forum\spost\s398e9d5aa9].
D 2021-11-07T23:33:01.004
C Add\sassert()s\sthat\sverify\sthat\scursor\snumbers\son\ssubqueries\sare\salways\ngreater\sthan\souter\scursor\snumbers.\s\sExcept,\sthis\sis\snot\salways\strue\sin\sthe\npresence\sof\squery\sflattening.\s\sWe\smight\sneed\sto\srelax\sthat\sconstraint.\nThis\sbranch\swill\sprobably\sbecome\sa\sdead-end.\s\sFor\snow\sit\sis\ssaved\sfor\nreference.
D 2021-11-08T16:38:08.067
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -502,7 +502,7 @@ F src/date.c fa928630fecf1d436cdc7a7a5c950c781709023ca782c21b7a43cc7361a9451e
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/delete.c 0c151975fa99560767d7747f9b60543d0093d9f8b89f13d2d6058e9c83ad19e7
F src/expr.c f96439c1c58fd8dbb42254ad45339b8487f7e2c0b59eb43b4652ffe458205bdb
F src/expr.c 2d06e9ee4faec27601bd536042fda2ec260c5b142cc3abfd2f6751eb8c605977
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 187b67af20c5795953a592832c5d985e4313fe503ebd8f95e3e9e9ad5a730bb5
F src/func.c 1cfb09d7ffca81238eccefdb0293e1f5b7cfebbd1816dfad5ec6024742a7496b
@@ -550,12 +550,12 @@ F src/printf.c 5901672228f305f7d493cbc4e7d76a61a5caecdbc1cd06b1f9ec42ea4265cf8d
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c ae65c88f5d0d4bc0052b203773d407efa2387c2bd6b202f87178006c7bb8632c
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c b4b3a0f32e70d93efbb357783846853dbd8b266ec0d7035aa0a245c33eecf72d
F src/select.c ac16dee42af39682bfd67539e127698838a2542601ee2eb6ce49196ba7265c74
F src/shell.c.in f8854bcb0d14707d661732698d5210d7f01694000c46e8014b323ad18f575be6
F src/sqlite.h.in 5cd209ac7dc4180f0e19292846f40440b8488015849ca0110c70b906b57d68f0
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 8ff2fd2c166150b2e48639f5e506fb44e29f1a3f65031710b9e89d1c126ac839
F src/sqliteInt.h c280f33f023f87864fa660925f5d5cb49ccfc82eea223fec4e37177c86a26b5a
F src/sqliteInt.h ab88d3f3d86dae6b2029539938fe742884811c9e64307d71ed0b991657262b38
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -1931,7 +1931,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 0dc963f63aebc42960125f96865029f16b3f6867126aab350da12882505edb82
R 3e89981cb2c8fbf47d84ee585ebde83e
P 0f9fc6b6073365d5159cd71e7fe08f8dadbc7b42abd324361e809502f4359155
R 4f74580fd63b4e2f86db712346f3cd4a
T *branch * well-ordered-cursors
T *sym-well-ordered-cursors *
T -sym-trunk *
U drh
Z 073fd661537b1ec07fc06b4c7f20875c
Z ae9ad8ca1734f1ca1c3ca8135a32d6c4
+1 -1
View File
@@ -1 +1 @@
0f9fc6b6073365d5159cd71e7fe08f8dadbc7b42abd324361e809502f4359155
6f4369666efb8eed84c3d60118baaf35d733ea906df983aeca2b0a475a6298a3
+59 -1
View File
@@ -5878,6 +5878,62 @@ int sqlite3ExprCoveredByIndex(
return !w.eCode;
}
#ifdef SQLITE_DEBUG
/* Walker callback for recursion in sqlite3WellOrderedCursors()
*/
static int wellOrderedCursors(Walker *pWalker, Select *pSel){
pWalker->eCode =
sqlite3WellOrderedCursors(pWalker->pParse, pSel, pWalker->u.iCur);
return WRC_Abort;
}
/*
** Check every cursor number in pSelect. Return false (zero) if any cursor
** number is less than or equal to iLowerBound. Return true if all cursors
** number are greater than iLowerBound.
**
** Repeat this check recursively on subqueries.
**
** Use this routine inside of an assert() to verify that every subquery
** cursor number is greater than the cursor numbers in all outer queries.
** This cursor number invariant is required for scoping of aggregate
** functions. tag-20211108
*/
int sqlite3WellOrderedCursors(Parse *pParse, Select *pSelect, int iLowerBound){
Walker w;
SrcList *pSrc;
int i;
int mx = 0;
pSrc = pSelect->pSrc;
assert( pSrc!=0 );
for(i=0; i<pSrc->nSrc; i++){
int iThis = pSrc->a[i].iCursor;
if( iThis<=iLowerBound ){
SELECTTRACE(1,pParse,pSelect,
("Cursor %d less than cursor %d in outer query\n",iThis, iLowerBound));
return 0;
}
if( iThis>mx ){
mx = iThis;
}
}
memset(&w, 0, sizeof(w));
w.pParse = pParse;
w.xSelectCallback = wellOrderedCursors;
w.xExprCallback = sqlite3ExprWalkNoop;
w.eCode = 1;
w.u.iCur = mx;
while( w.eCode ){
sqlite3WalkSelectExpr(&w, pSelect);
if( w.eCode==0 ) break;
sqlite3WalkSelectFrom(&w, pSelect);
pSelect = pSelect->pPrior;
if( pSelect==0 ) break;
}
return w.eCode;
}
#endif /* SQLITE_DEBUG */
/*
** An instance of the following structure is used by the tree walker
@@ -5929,7 +5985,9 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
}else if( pExpr->iTable<p->iSrcInner ){
/* In a well-formed parse tree (no name resolution errors),
** TK_COLUMN nodes with smaller Expr.iTable values are in an
** outer context. Those are the only ones to count as "other" */
** outer context. Those are the only ones to count as "other"
** See tag-20211108
*/
p->nOther++;
}
}
+2
View File
@@ -6404,6 +6404,7 @@ int sqlite3Select(
sqlite3TreeViewSelect(0, p, 0);
}
#endif
assert( sqlite3WellOrderedCursors(pParse, p, -1) );
#endif /* SQLITE_OMIT_WINDOWFUNC */
pTabList = p->pSrc;
isAgg = (p->selFlags & SF_Aggregate)!=0;
@@ -6522,6 +6523,7 @@ int sqlite3Select(
if( pParse->nErr ) goto select_end;
/* This subquery can be absorbed into its parent. */
i = -1;
assert( sqlite3WellOrderedCursors(pParse, p, -1) );
}
pTabList = p->pSrc;
if( db->mallocFailed ) goto select_end;
+3
View File
@@ -4623,6 +4623,9 @@ void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
#ifdef SQLITE_DEBUG
int sqlite3WellOrderedCursors(Parse*,Select*,int);
#endif
int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
Vdbe *sqlite3GetVdbe(Parse*);
#ifndef SQLITE_UNTESTABLE