xref: /sqlite-3.40.0/src/walker.c (revision 2aee514b)
17d10d5a6Sdrh /*
27d10d5a6Sdrh ** 2008 August 16
37d10d5a6Sdrh **
47d10d5a6Sdrh ** The author disclaims copyright to this source code.  In place of
57d10d5a6Sdrh ** a legal notice, here is a blessing:
67d10d5a6Sdrh **
77d10d5a6Sdrh **    May you do good and not evil.
87d10d5a6Sdrh **    May you find forgiveness for yourself and forgive others.
97d10d5a6Sdrh **    May you share freely, never taking more than you give.
107d10d5a6Sdrh **
117d10d5a6Sdrh *************************************************************************
127d10d5a6Sdrh ** This file contains routines used for walking the parser tree for
137d10d5a6Sdrh ** an SQL statement.
147d10d5a6Sdrh */
157d10d5a6Sdrh #include "sqliteInt.h"
167d10d5a6Sdrh #include <stdlib.h>
177d10d5a6Sdrh #include <string.h>
187d10d5a6Sdrh 
197d10d5a6Sdrh 
20d9995031Sdan #if !defined(SQLITE_OMIT_WINDOWFUNC)
21d9995031Sdan /*
22d9995031Sdan ** Walk all expressions linked into the list of Window objects passed
23d9995031Sdan ** as the second argument.
24d9995031Sdan */
25d9995031Sdan static int walkWindowList(Walker *pWalker, Window *pList){
26d9995031Sdan   Window *pWin;
27d9995031Sdan   for(pWin=pList; pWin; pWin=pWin->pNextWin){
28c5cc870eSdrh     int rc;
29c5cc870eSdrh     rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy);
30c5cc870eSdrh     if( rc ) return WRC_Abort;
31c5cc870eSdrh     rc = sqlite3WalkExprList(pWalker, pWin->pPartition);
32c5cc870eSdrh     if( rc ) return WRC_Abort;
33c5cc870eSdrh     rc = sqlite3WalkExpr(pWalker, pWin->pFilter);
34c5cc870eSdrh     if( rc ) return WRC_Abort;
35c5cc870eSdrh 
36c5cc870eSdrh     /* The next two are purely for calls to sqlite3RenameExprUnmap()
37c5cc870eSdrh     ** within sqlite3WindowOffsetExpr().  Because of constraints imposed
38c5cc870eSdrh     ** by sqlite3WindowOffsetExpr(), they can never fail.  The results do
39c5cc870eSdrh     ** not matter anyhow. */
40c5cc870eSdrh     rc = sqlite3WalkExpr(pWalker, pWin->pStart);
41c5cc870eSdrh     if( NEVER(rc) ) return WRC_Abort;
42c5cc870eSdrh     rc = sqlite3WalkExpr(pWalker, pWin->pEnd);
43c5cc870eSdrh     if( NEVER(rc) ) return WRC_Abort;
44d9995031Sdan   }
45d9995031Sdan   return WRC_Continue;
46d9995031Sdan }
47d9995031Sdan #endif
48d9995031Sdan 
497d10d5a6Sdrh /*
507d10d5a6Sdrh ** Walk an expression tree.  Invoke the callback once for each node
5160ec914cSpeter.d.reid ** of the expression, while descending.  (In other words, the callback
527d10d5a6Sdrh ** is invoked before visiting children.)
537d10d5a6Sdrh **
547d10d5a6Sdrh ** The return value from the callback should be one of the WRC_*
557d10d5a6Sdrh ** constants to specify how to proceed with the walk.
567d10d5a6Sdrh **
577d10d5a6Sdrh **    WRC_Continue      Continue descending down the tree.
587d10d5a6Sdrh **
59567bd449Sdrh **    WRC_Prune         Do not descend into child nodes, but allow
607d10d5a6Sdrh **                      the walk to continue with sibling nodes.
617d10d5a6Sdrh **
627d10d5a6Sdrh **    WRC_Abort         Do no more callbacks.  Unwind the stack and
63567bd449Sdrh **                      return from the top-level walk call.
647d10d5a6Sdrh **
657d10d5a6Sdrh ** The return value from this routine is WRC_Abort to abandon the tree walk
667d10d5a6Sdrh ** and WRC_Continue to continue.
677d10d5a6Sdrh */
6850922cfcSdrh static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
697d10d5a6Sdrh   int rc;
700a9aa225Sdrh   testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
710a9aa225Sdrh   testcase( ExprHasProperty(pExpr, EP_Reduced) );
72dceed86dSdrh   while(1){
737d10d5a6Sdrh     rc = pWalker->xExprCallback(pWalker, pExpr);
74c2d14a9aSdrh     if( rc ) return rc & WRC_Abort;
75c2d14a9aSdrh     if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
76d1086679Sdrh       assert( pExpr->x.pList==0 || pExpr->pRight==0 );
77ec123e13Sdrh       if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
78d1086679Sdrh       if( pExpr->pRight ){
794f9adee2Sdan         assert( !ExprHasProperty(pExpr, EP_WinFunc) );
80dceed86dSdrh         pExpr = pExpr->pRight;
81dceed86dSdrh         continue;
82d1086679Sdrh       }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
834f9adee2Sdan         assert( !ExprHasProperty(pExpr, EP_WinFunc) );
846ab3a2ecSdanielk1977         if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
858117f113Sdan       }else{
868117f113Sdan         if( pExpr->x.pList ){
876ab3a2ecSdanielk1977           if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
887d10d5a6Sdrh         }
89867be212Sdan #ifndef SQLITE_OMIT_WINDOWFUNC
90eda079cdSdrh         if( ExprHasProperty(pExpr, EP_WinFunc) ){
91d9995031Sdan           if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
928117f113Sdan         }
93867be212Sdan #endif
94c2d14a9aSdrh       }
958117f113Sdan     }
96dceed86dSdrh     break;
97dceed86dSdrh   }
98922802c4Sdrh   return WRC_Continue;
997d10d5a6Sdrh }
10050922cfcSdrh int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
10150922cfcSdrh   return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;
10250922cfcSdrh }
1037d10d5a6Sdrh 
1047d10d5a6Sdrh /*
1057d10d5a6Sdrh ** Call sqlite3WalkExpr() for every expression in list p or until
1067d10d5a6Sdrh ** an abort request is seen.
1077d10d5a6Sdrh */
1087d10d5a6Sdrh int sqlite3WalkExprList(Walker *pWalker, ExprList *p){
109f7828b5cSdrh   int i;
1107d10d5a6Sdrh   struct ExprList_item *pItem;
1117d10d5a6Sdrh   if( p ){
1127d10d5a6Sdrh     for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){
1137d10d5a6Sdrh       if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort;
1147d10d5a6Sdrh     }
1157d10d5a6Sdrh   }
116f7828b5cSdrh   return WRC_Continue;
1177d10d5a6Sdrh }
1187d10d5a6Sdrh 
1197d10d5a6Sdrh /*
1207d10d5a6Sdrh ** Walk all expressions associated with SELECT statement p.  Do
1217d10d5a6Sdrh ** not invoke the SELECT callback on p, but do (of course) invoke
1227d10d5a6Sdrh ** any expr callbacks and SELECT callbacks that come from subqueries.
1237d10d5a6Sdrh ** Return WRC_Abort or WRC_Continue.
1247d10d5a6Sdrh */
1257d10d5a6Sdrh int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
1267d10d5a6Sdrh   if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort;
1277d10d5a6Sdrh   if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort;
1287d10d5a6Sdrh   if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort;
1297d10d5a6Sdrh   if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
1307d10d5a6Sdrh   if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
1317d10d5a6Sdrh   if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
132d9995031Sdan #if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE)
133d9995031Sdan   {
134d9995031Sdan     Parse *pParse = pWalker->pParse;
135d9995031Sdan     if( pParse && IN_RENAME_OBJECT ){
136a1ac0359Sdan       /* The following may return WRC_Abort if there are unresolvable
137a1ac0359Sdan       ** symbols (e.g. a table that does not exist) in a window definition. */
1386a02f237Sdrh       int rc = walkWindowList(pWalker, p->pWinDefn);
1396a02f237Sdrh       return rc;
140d9995031Sdan     }
141d9995031Sdan   }
142d9995031Sdan #endif
1437d10d5a6Sdrh   return WRC_Continue;
1447d10d5a6Sdrh }
1457d10d5a6Sdrh 
1467d10d5a6Sdrh /*
1477d10d5a6Sdrh ** Walk the parse trees associated with all subqueries in the
1487d10d5a6Sdrh ** FROM clause of SELECT statement p.  Do not invoke the select
1497d10d5a6Sdrh ** callback on p, but do invoke it on each FROM clause subquery
1507d10d5a6Sdrh ** and on any subqueries further down in the tree.  Return
1517d10d5a6Sdrh ** WRC_Abort or WRC_Continue;
1527d10d5a6Sdrh */
1537d10d5a6Sdrh int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
1547d10d5a6Sdrh   SrcList *pSrc;
1557d10d5a6Sdrh   int i;
1567d10d5a6Sdrh   struct SrcList_item *pItem;
1577d10d5a6Sdrh 
1587d10d5a6Sdrh   pSrc = p->pSrc;
159*2aee514bSdrh   if( pSrc ){
1607d10d5a6Sdrh     for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
1613da70a61Sdrh       if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
1627d10d5a6Sdrh         return WRC_Abort;
1637d10d5a6Sdrh       }
16401d230ceSdrh       if( pItem->fg.isTabFunc
16501d230ceSdrh        && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
16601d230ceSdrh       ){
16701d230ceSdrh         return WRC_Abort;
16801d230ceSdrh       }
1697d10d5a6Sdrh     }
170*2aee514bSdrh   }
1717d10d5a6Sdrh   return WRC_Continue;
1727d10d5a6Sdrh }
1737d10d5a6Sdrh 
1747d10d5a6Sdrh /*
1757d10d5a6Sdrh ** Call sqlite3WalkExpr() for every expression in Select statement p.
1767d10d5a6Sdrh ** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and
177b290f117Sdan ** on the compound select chain, p->pPrior.
178b290f117Sdan **
179b290f117Sdan ** If it is not NULL, the xSelectCallback() callback is invoked before
180b290f117Sdan ** the walk of the expressions and FROM clause. The xSelectCallback2()
181979dd1beSdrh ** method is invoked following the walk of the expressions and FROM clause,
182979dd1beSdrh ** but only if both xSelectCallback and xSelectCallback2 are both non-NULL
183979dd1beSdrh ** and if the expressions and FROM clause both return WRC_Continue;
1847d10d5a6Sdrh **
1857d10d5a6Sdrh ** Return WRC_Continue under normal conditions.  Return WRC_Abort if
1867d10d5a6Sdrh ** there is an abort request.
1877d10d5a6Sdrh **
1887d10d5a6Sdrh ** If the Walker does not have an xSelectCallback() then this routine
1897d10d5a6Sdrh ** is a no-op returning WRC_Continue.
1907d10d5a6Sdrh */
1917d10d5a6Sdrh int sqlite3WalkSelect(Walker *pWalker, Select *p){
1927d10d5a6Sdrh   int rc;
1933da70a61Sdrh   if( p==0 ) return WRC_Continue;
1943da70a61Sdrh   if( pWalker->xSelectCallback==0 ) return WRC_Continue;
195979dd1beSdrh   do{
1967d10d5a6Sdrh     rc = pWalker->xSelectCallback(pWalker, p);
197979dd1beSdrh     if( rc ) return rc & WRC_Abort;
198ed551b95Sdrh     if( sqlite3WalkSelectExpr(pWalker, p)
199ed551b95Sdrh      || sqlite3WalkSelectFrom(pWalker, p)
200ed551b95Sdrh     ){
201ed551b95Sdrh       return WRC_Abort;
202ed551b95Sdrh     }
203b290f117Sdan     if( pWalker->xSelectCallback2 ){
204b290f117Sdan       pWalker->xSelectCallback2(pWalker, p);
205aa87f9a6Sdrh     }
2067d10d5a6Sdrh     p = p->pPrior;
207979dd1beSdrh   }while( p!=0 );
208979dd1beSdrh   return WRC_Continue;
2097d10d5a6Sdrh }
210