00001 /* 00002 ** 2008 August 16 00003 ** 00004 ** The author disclaims copyright to this source code. In place of 00005 ** a legal notice, here is a blessing: 00006 ** 00007 ** May you do good and not evil. 00008 ** May you find forgiveness for yourself and forgive others. 00009 ** May you share freely, never taking more than you give. 00010 ** 00011 ************************************************************************* 00012 ** This file contains routines used for walking the parser tree for 00013 ** an SQL statement. 00014 ** 00015 ** $Id: walker.c,v 1.1 2008/08/20 16:35:10 drh Exp $ 00016 */ 00017 #include "sqliteInt.h" 00018 #include <stdlib.h> 00019 #include <string.h> 00020 00021 00022 /* 00023 ** Walk an expression tree. Invoke the callback once for each node 00024 ** of the expression, while decending. (In other words, the callback 00025 ** is invoked before visiting children.) 00026 ** 00027 ** The return value from the callback should be one of the WRC_* 00028 ** constants to specify how to proceed with the walk. 00029 ** 00030 ** WRC_Continue Continue descending down the tree. 00031 ** 00032 ** WRC_Prune Do not descend into child nodes. But allow 00033 ** the walk to continue with sibling nodes. 00034 ** 00035 ** WRC_Abort Do no more callbacks. Unwind the stack and 00036 ** return the top-level walk call. 00037 ** 00038 ** The return value from this routine is WRC_Abort to abandon the tree walk 00039 ** and WRC_Continue to continue. 00040 */ 00041 int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ 00042 int rc; 00043 if( pExpr==0 ) return WRC_Continue; 00044 rc = pWalker->xExprCallback(pWalker, pExpr); 00045 if( rc==WRC_Continue ){ 00046 if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; 00047 if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; 00048 if( sqlite3WalkExprList(pWalker, pExpr->pList) ) return WRC_Abort; 00049 if( sqlite3WalkSelect(pWalker, pExpr->pSelect) ){ 00050 return WRC_Abort; 00051 } 00052 } 00053 return rc & WRC_Abort; 00054 } 00055 00056 /* 00057 ** Call sqlite3WalkExpr() for every expression in list p or until 00058 ** an abort request is seen. 00059 */ 00060 int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ 00061 int i, rc = WRC_Continue; 00062 struct ExprList_item *pItem; 00063 if( p ){ 00064 for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ 00065 if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; 00066 } 00067 } 00068 return rc & WRC_Continue; 00069 } 00070 00071 /* 00072 ** Walk all expressions associated with SELECT statement p. Do 00073 ** not invoke the SELECT callback on p, but do (of course) invoke 00074 ** any expr callbacks and SELECT callbacks that come from subqueries. 00075 ** Return WRC_Abort or WRC_Continue. 00076 */ 00077 int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ 00078 if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; 00079 if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; 00080 if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; 00081 if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; 00082 if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; 00083 if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; 00084 if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort; 00085 return WRC_Continue; 00086 } 00087 00088 /* 00089 ** Walk the parse trees associated with all subqueries in the 00090 ** FROM clause of SELECT statement p. Do not invoke the select 00091 ** callback on p, but do invoke it on each FROM clause subquery 00092 ** and on any subqueries further down in the tree. Return 00093 ** WRC_Abort or WRC_Continue; 00094 */ 00095 int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ 00096 SrcList *pSrc; 00097 int i; 00098 struct SrcList_item *pItem; 00099 00100 pSrc = p->pSrc; 00101 if( pSrc ){ 00102 for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ 00103 if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){ 00104 return WRC_Abort; 00105 } 00106 } 00107 } 00108 return WRC_Continue; 00109 } 00110 00111 /* 00112 ** Call sqlite3WalkExpr() for every expression in Select statement p. 00113 ** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and 00114 ** on the compound select chain, p->pPrior. 00115 ** 00116 ** Return WRC_Continue under normal conditions. Return WRC_Abort if 00117 ** there is an abort request. 00118 ** 00119 ** If the Walker does not have an xSelectCallback() then this routine 00120 ** is a no-op returning WRC_Continue. 00121 */ 00122 int sqlite3WalkSelect(Walker *pWalker, Select *p){ 00123 int rc; 00124 if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue; 00125 rc = WRC_Continue; 00126 while( p ){ 00127 rc = pWalker->xSelectCallback(pWalker, p); 00128 if( rc ) break; 00129 if( sqlite3WalkSelectExpr(pWalker, p) ) return WRC_Abort; 00130 if( sqlite3WalkSelectFrom(pWalker, p) ) return WRC_Abort; 00131 p = p->pPrior; 00132 } 00133 return rc & WRC_Abort; 00134 }
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:57 2011 by Doxygen 1.6.1