📄 expr.c
字号:
} }else{ /* Wildcards of the form ":aaa" or "$aaa". Reuse the same variable ** number as the prior appearance of the same name, or if the name ** has never appeared before, reuse the same variable number */ int i, n; n = pToken->n; for(i=0; i<pParse->nVarExpr; i++){ Expr *pE; if( (pE = pParse->apVarExpr[i])!=0 && pE->token.n==n && memcmp(pE->token.z, pToken->z, n)==0 ){ pExpr->iTable = pE->iTable; break; } } if( i>=pParse->nVarExpr ){ pExpr->iTable = ++pParse->nVar; if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; pParse->apVarExpr = sqlite3DbReallocOrFree( db, pParse->apVarExpr, pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) ); } if( !db->mallocFailed ){ assert( pParse->apVarExpr!=0 ); pParse->apVarExpr[pParse->nVarExpr++] = pExpr; } } } if( !pParse->nErr && pParse->nVar>SQLITE_MAX_VARIABLE_NUMBER ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); }}/*** Recursively delete an expression tree.*/void sqlite3ExprDelete(Expr *p){ if( p==0 ) return; if( p->span.dyn ) sqlite3_free((char*)p->span.z); if( p->token.dyn ) sqlite3_free((char*)p->token.z); sqlite3ExprDelete(p->pLeft); sqlite3ExprDelete(p->pRight); sqlite3ExprListDelete(p->pList); sqlite3SelectDelete(p->pSelect); sqlite3_free(p);}/*** The Expr.token field might be a string literal that is quoted.** If so, remove the quotation marks.*/void sqlite3DequoteExpr(sqlite3 *db, Expr *p){ if( ExprHasAnyProperty(p, EP_Dequoted) ){ return; } ExprSetProperty(p, EP_Dequoted); if( p->token.dyn==0 ){ sqlite3TokenCopy(db, &p->token, &p->token); } sqlite3Dequote((char*)p->token.z);}/*** The following group of routines make deep copies of expressions,** expression lists, ID lists, and select statements. The copies can** be deleted (by being passed to their respective ...Delete() routines)** without effecting the originals.**** The expression list, ID, and source lists return by sqlite3ExprListDup(),** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded ** by subsequent calls to sqlite*ListAppend() routines.**** Any tables that the SrcList might point to are not duplicated.*/Expr *sqlite3ExprDup(sqlite3 *db, Expr *p){ Expr *pNew; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); if( pNew==0 ) return 0; memcpy(pNew, p, sizeof(*pNew)); if( p->token.z!=0 ){ pNew->token.z = (u8*)sqlite3DbStrNDup(db, (char*)p->token.z, p->token.n); pNew->token.dyn = 1; }else{ assert( pNew->token.z==0 ); } pNew->span.z = 0; pNew->pLeft = sqlite3ExprDup(db, p->pLeft); pNew->pRight = sqlite3ExprDup(db, p->pRight); pNew->pList = sqlite3ExprListDup(db, p->pList); pNew->pSelect = sqlite3SelectDup(db, p->pSelect); return pNew;}void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){ if( pTo->dyn ) sqlite3_free((char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n); pTo->dyn = 1; }else{ pTo->z = 0; }}ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->iECursor = 0; pNew->nExpr = pNew->nAlloc = p->nExpr; pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) ); if( pItem==0 ){ sqlite3_free(pNew); return 0; } pOldItem = p->a; for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){ Expr *pNewExpr, *pOldExpr; pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr = pOldItem->pExpr); if( pOldExpr->span.z!=0 && pNewExpr ){ /* Always make a copy of the span for top-level expressions in the ** expression list. The logic in SELECT processing that determines ** the names of columns in the result set needs this information */ sqlite3TokenCopy(db, &pNewExpr->span, &pOldExpr->span); } assert( pNewExpr==0 || pNewExpr->span.z!=0 || pOldExpr->span.z==0 || db->mallocFailed ); pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->sortOrder = pOldItem->sortOrder; pItem->isAgg = pOldItem->isAgg; pItem->done = 0; } return pNew;}/*** If cursors, triggers, views and subqueries are all omitted from** the build, then none of the following routines, except for ** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes** called with a NULL argument.*/#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY)SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p){ SrcList *pNew; int i; int nByte; if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); pNew = sqlite3DbMallocRaw(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ struct SrcList_item *pNewItem = &pNew->a[i]; struct SrcList_item *pOldItem = &p->a[i]; Table *pTab; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; pNewItem->isPopulated = pOldItem->isPopulated; pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nRef++; } pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect); pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn); pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); pNewItem->colUsed = pOldItem->colUsed; } return pNew;}IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ IdList *pNew; int i; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = pNew->nAlloc = p->nId; pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ sqlite3_free(pNew); return 0; } for(i=0; i<p->nId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->idx = pOldItem->idx; } return pNew;}Select *sqlite3SelectDup(sqlite3 *db, Select *p){ Select *pNew; if( p==0 ) return 0; pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); if( pNew==0 ) return 0; pNew->isDistinct = p->isDistinct; pNew->pEList = sqlite3ExprListDup(db, p->pEList); pNew->pSrc = sqlite3SrcListDup(db, p->pSrc); pNew->pWhere = sqlite3ExprDup(db, p->pWhere); pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy); pNew->pHaving = sqlite3ExprDup(db, p->pHaving); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy); pNew->op = p->op; pNew->pPrior = sqlite3SelectDup(db, p->pPrior); pNew->pLimit = sqlite3ExprDup(db, p->pLimit); pNew->pOffset = sqlite3ExprDup(db, p->pOffset); pNew->iLimit = -1; pNew->iOffset = -1; pNew->isResolved = p->isResolved; pNew->isAgg = p->isAgg; pNew->usesEphm = 0; pNew->disallowOrderBy = 0; pNew->pRightmost = 0; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; return pNew;}#elseSelect *sqlite3SelectDup(sqlite3 *db, Select *p){ assert( p==0 ); return 0;}#endif/*** Add a new element to the end of an expression list. If pList is** initially NULL, then create a new expression list.*/ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr, /* Expression to be appended */ Token *pName /* AS keyword for the expression */){ sqlite3 *db = pParse->db; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } assert( pList->nAlloc==0 ); } if( pList->nAlloc<=pList->nExpr ){ struct ExprList_item *a; int n = pList->nAlloc*2 + 4; a = sqlite3DbRealloc(db, pList->a, n*sizeof(pList->a[0])); if( a==0 ){ goto no_mem; } pList->a = a; pList->nAlloc = n; } assert( pList->a!=0 ); if( pExpr || pName ){ struct ExprList_item *pItem = &pList->a[pList->nExpr++]; memset(pItem, 0, sizeof(*pItem)); pItem->zName = sqlite3NameFromToken(db, pName); pItem->pExpr = pExpr; } return pList;no_mem: /* Avoid leaking memory if malloc has failed. */ sqlite3ExprDelete(pExpr); sqlite3ExprListDelete(pList); return 0;}/*** If the expression list pEList contains more than iLimit elements,** leave an error message in pParse.*/void sqlite3ExprListCheckLength( Parse *pParse, ExprList *pEList, int iLimit, const char *zObject){ if( pEList && pEList->nExpr>iLimit ){ sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); }}#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0/* The following three functions, heightOfExpr(), heightOfExprList()** and heightOfSelect(), are used to determine the maximum height** of any expression tree referenced by the structure passed as the** first argument.**** If this maximum height is greater than the current value pointed** to by pnHeight, the second parameter, then set *pnHeight to that** value.*/static void heightOfExpr(Expr *p, int *pnHeight){ if( p ){ if( p->nHeight>*pnHeight ){ *pnHeight = p->nHeight; } }}static void heightOfExprList(ExprList *p, int *pnHeight){ if( p ){ int i; for(i=0; i<p->nExpr; i++){ heightOfExpr(p->a[i].pExpr, pnHeight); } }}static void heightOfSelect(Select *p, int *pnHeight){ if( p ){ heightOfExpr(p->pWhere, pnHeight); heightOfExpr(p->pHaving, pnHeight); heightOfExpr(p->pLimit, pnHeight); heightOfExpr(p->pOffset, pnHeight); heightOfExprList(p->pEList, pnHeight); heightOfExprList(p->pGroupBy, pnHeight); heightOfExprList(p->pOrderBy, pnHeight); heightOfSelect(p->pPrior, pnHeight); }}/*** Set the Expr.nHeight variable in the structure passed as an ** argument. An expression with no children, Expr.pList or ** Expr.pSelect member has a height of 1. Any other expression** has a height equal to the maximum height of any other ** referenced Expr plus one.*/void sqlite3ExprSetHeight(Expr *p){ int nHeight = 0; heightOfExpr(p->pLeft, &nHeight); heightOfExpr(p->pRight, &nHeight); heightOfExprList(p->pList, &nHeight); heightOfSelect(p->pSelect, &nHeight); p->nHeight = nHeight + 1;}/*** Return the maximum height of any expression tree referenced** by the select statement passed as an argument.*/int sqlite3SelectExprHeight(Select *p){ int nHeight = 0; heightOfSelect(p, &nHeight); return nHeight;}#endif/*** Delete an entire expression list.*/void sqlite3ExprListDelete(ExprList *pList){ int i; struct ExprList_item *pItem; if( pList==0 ) return; assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); assert( pList->nExpr<=pList->nAlloc ); for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){ sqlite3ExprDelete(pItem->pExpr); sqlite3_free(pItem->zName); } sqlite3_free(pList->a); sqlite3_free(pList);}/*** Walk an expression tree. Call xFunc for each node visited.**** The return value from xFunc determines whether the tree walk continues.** 0 means continue walking the tree. 1 means do not walk children** of the current node but continue with siblings. 2 means abandon** the tree walk completely.**** The return value from this routine is 1 to abandon the tree walk** and 0 to continue.**** NOTICE: This routine does *not* descend into subqueries.*/static int walkExprList(ExprList *, int (*)(void *, Expr*), void *);static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){ int rc; if( pExpr==0 ) return 0; rc = (*xFunc)(pArg, pExpr); if( rc==0 ){ if( walkExprTree(pExpr->pLeft, xFunc, pArg) ) return 1; if( walkExprTree(pExpr->pRight, xFunc, pArg) ) return 1; if( walkExprList(pExpr->pList, xFunc, pArg) ) return 1; } return rc>1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -