diff options
author | dan <dan@noemail.net> | 2015-11-07 18:07:15 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2015-11-07 18:07:15 +0000 |
commit | cc033054734028fa582afe17521afce3da433df5 (patch) | |
tree | 1c92d9e981db7cb3ef9a659a8c0d5021e4630368 /src/treeview.c | |
parent | d6b7946c32ec1cf4b77f51ab82db553cf466c488 (diff) | |
parent | fe88fbfc828594d00999649ab6a8dcff5db64821 (diff) | |
download | sqlite-cc033054734028fa582afe17521afce3da433df5.tar.gz sqlite-cc033054734028fa582afe17521afce3da433df5.zip |
Fix a bug in CTE handling discovered by LibFuzzer that can cause an infinite loop in the query planner.
FossilOrigin-Name: 088009efdd56160bb4eee0fbd829a529b141274e
Diffstat (limited to 'src/treeview.c')
-rw-r--r-- | src/treeview.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/treeview.c b/src/treeview.c index 971de4e8b..a26e9e2b9 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -79,6 +79,45 @@ static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ sqlite3TreeViewLine(p, "%s", zLabel); } +/* +** Generate a human-readable description of a WITH clause. +*/ +void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ + int i; + if( pWith==0 ) return; + if( pWith->nCte==0 ) return; + if( pWith->pOuter ){ + sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter); + }else{ + sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); + } + if( pWith->nCte>0 ){ + pView = sqlite3TreeViewPush(pView, 1); + for(i=0; i<pWith->nCte; i++){ + StrAccum x; + char zLine[1000]; + const struct Cte *pCte = &pWith->a[i]; + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + sqlite3XPrintf(&x, 0, "%s", pCte->zName); + if( pCte->pCols && pCte->pCols->nExpr>0 ){ + char cSep = '('; + int j; + for(j=0; j<pCte->pCols->nExpr; j++){ + sqlite3XPrintf(&x, 0, "%c%s", cSep, pCte->pCols->a[j].zName); + cSep = ','; + } + sqlite3XPrintf(&x, 0, ")"); + } + sqlite3XPrintf(&x, 0, " AS"); + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1); + sqlite3TreeViewSelect(pView, pCte->pSelect, 0); + sqlite3TreeViewPop(pView); + } + sqlite3TreeViewPop(pView); + } +} + /* ** Generate a human-readable description of a the Select object. @@ -87,6 +126,11 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ int n = 0; int cnt = 0; pView = sqlite3TreeViewPush(pView, moreToFollow); + if( p->pWith ){ + sqlite3TreeViewWith(pView, p->pWith, 1); + cnt = 1; + sqlite3TreeViewPush(pView, 1); + } do{ sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x", ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), |