aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-11-07 17:48:21 +0000
committerdrh <drh@noemail.net>2015-11-07 17:48:21 +0000
commit6e7722669ec0080c1fec7d315460b77aecbd9e4f (patch)
tree49e35d43c3863527944dc4557ceeb1ab115f8006 /src
parent2476a6f2cb071b4ea17a99b1ddc05111cd1422f4 (diff)
downloadsqlite-6e7722669ec0080c1fec7d315460b77aecbd9e4f.tar.gz
sqlite-6e7722669ec0080c1fec7d315460b77aecbd9e4f.zip
Proposed fix for an infinite loop bug in the WITH clause semantic analysis
logic. FossilOrigin-Name: 028475cb17a4b50baf0e9aba9bd3403d0a5d03b0
Diffstat (limited to 'src')
-rw-r--r--src/select.c5
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/tokenize.c2
3 files changed, 5 insertions, 4 deletions
diff --git a/src/select.c b/src/select.c
index 456271365..bd732e5bc 100644
--- a/src/select.c
+++ b/src/select.c
@@ -4003,12 +4003,12 @@ static struct Cte *searchWith(
** statement with which it is associated.
*/
void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
- assert( bFree==0 || pParse->pWith==0 );
+ assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) );
if( pWith ){
assert( pParse->pWith!=pWith );
pWith->pOuter = pParse->pWith;
pParse->pWith = pWith;
- pParse->bFreeWith = bFree;
+ if( bFree ) pParse->pWithToFree = pWith;
}
}
@@ -4101,6 +4101,7 @@ static int withExpand(
pSavedWith = pParse->pWith;
pParse->pWith = pWith;
sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel);
+ pParse->pWith = pWith;
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
pEList = pLeft->pEList;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 8956c43b0..c65e0f205 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2754,7 +2754,6 @@ struct Parse {
int nVar; /* Number of '?' variables seen in the SQL so far */
int nzVar; /* Number of available slots in azVar[] */
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
- u8 bFreeWith; /* True if pWith should be freed with parser */
u8 explain; /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
@@ -2781,6 +2780,7 @@ struct Parse {
Table *pZombieTab; /* List of Table objects to delete after code gen */
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
With *pWith; /* Current WITH clause, or NULL */
+ With *pWithToFree; /* Free this WITH object at the end of the parse */
};
/*
diff --git a/src/tokenize.c b/src/tokenize.c
index 9c1403bb2..f2b63b5cf 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -510,7 +510,7 @@ abort_parse:
sqlite3DeleteTable(db, pParse->pNewTable);
}
- if( pParse->bFreeWith ) sqlite3WithDelete(db, pParse->pWith);
+ sqlite3WithDelete(db, pParse->pWithToFree);
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
sqlite3DbFree(db, pParse->azVar);