?? expr.c
字號:
void sqlite3TokenCopy(Token *pTo, Token *pFrom){ if( pTo->dyn ) sqliteFree((char*)pTo->z); if( pFrom->z ){ pTo->n = pFrom->n; pTo->z = sqliteStrNDup(pFrom->z, pFrom->n); pTo->dyn = 1; }else{ pTo->z = 0; }}ExprList *sqlite3ExprListDup(ExprList *p){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; if( p==0 ) return 0; pNew = sqliteMalloc( sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nExpr = pNew->nAlloc = p->nExpr; pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) ); if( pItem==0 ){ sqliteFree(pNew); return 0; } pOldItem = p->a; for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){ Expr *pNewExpr, *pOldExpr; pItem->pExpr = pNewExpr = sqlite3ExprDup(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(&pNewExpr->span, &pOldExpr->span); } assert( pNewExpr==0 || pNewExpr->span.z!=0 || pOldExpr->span.z==0 || sqlite3_malloc_failed ); pItem->zName = sqliteStrDup(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(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 = sqliteMallocRaw( 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 = sqliteStrDup(pOldItem->zDatabase); pNewItem->zName = sqliteStrDup(pOldItem->zName); pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nRef++; } pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect); pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn); pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing); pNewItem->colUsed = pOldItem->colUsed; } return pNew;}IdList *sqlite3IdListDup(IdList *p){ IdList *pNew; int i; if( p==0 ) return 0; pNew = sqliteMallocRaw( sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = pNew->nAlloc = p->nId; pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ sqliteFree(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 = sqliteStrDup(pOldItem->zName); pNewItem->idx = pOldItem->idx; } return pNew;}Select *sqlite3SelectDup(Select *p){ Select *pNew; if( p==0 ) return 0; pNew = sqliteMallocRaw( sizeof(*p) ); if( pNew==0 ) return 0; pNew->isDistinct = p->isDistinct; pNew->pEList = sqlite3ExprListDup(p->pEList); pNew->pSrc = sqlite3SrcListDup(p->pSrc); pNew->pWhere = sqlite3ExprDup(p->pWhere); pNew->pGroupBy = sqlite3ExprListDup(p->pGroupBy); pNew->pHaving = sqlite3ExprDup(p->pHaving); pNew->pOrderBy = sqlite3ExprListDup(p->pOrderBy); pNew->op = p->op; pNew->pPrior = sqlite3SelectDup(p->pPrior); pNew->pLimit = sqlite3ExprDup(p->pLimit); pNew->pOffset = sqlite3ExprDup(p->pOffset); pNew->iLimit = -1; pNew->iOffset = -1; pNew->ppOpenTemp = 0; pNew->isResolved = p->isResolved; pNew->isAgg = p->isAgg; return pNew;}#elseSelect *sqlite3SelectDup(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(ExprList *pList, Expr *pExpr, Token *pName){ if( pList==0 ){ pList = sqliteMalloc( 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 = sqliteRealloc(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(pName); pItem->pExpr = pExpr; } return pList;no_mem: /* Avoid leaking memory if malloc has failed. */ sqlite3ExprDelete(pExpr); sqlite3ExprListDelete(pList); return 0;}/*** 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); sqliteFree(pItem->zName); } sqliteFree(pList->a); sqliteFree(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.*/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;}/*** Call walkExprTree() for every expression in list p.*/static int walkExprList(ExprList *p, int (*xFunc)(void *, Expr*), void *pArg){ int i; struct ExprList_item *pItem; if( !p ) return 0; for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ if( walkExprTree(pItem->pExpr, xFunc, pArg) ) return 1; } return 0;}/*** Call walkExprTree() for every expression in Select p, not including** expressions that are part of sub-selects in any FROM clause or the LIMIT** or OFFSET expressions..*/static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){ walkExprList(p->pEList, xFunc, pArg); walkExprTree(p->pWhere, xFunc, pArg); walkExprList(p->pGroupBy, xFunc, pArg); walkExprTree(p->pHaving, xFunc, pArg); walkExprList(p->pOrderBy, xFunc, pArg); return 0;}/*** This routine is designed as an xFunc for walkExprTree().**** pArg is really a pointer to an integer. If we can tell by looking** at pExpr that the expression that contains pExpr is not a constant** expression, then set *pArg to 0 and return 2 to abandon the tree walk.** If pExpr does does not disqualify the expression from being a constant** then do nothing.**** After walking the whole tree, if no nodes are found that disqualify** the expression as constant, then we assume the whole expression** is constant. See sqlite3ExprIsConstant() for additional information.*/static int exprNodeIsConstant(void *pArg, Expr *pExpr){ switch( pExpr->op ){ case TK_ID: case TK_COLUMN: case TK_DOT: case TK_AGG_FUNCTION: case TK_FUNCTION:#ifndef SQLITE_OMIT_SUBQUERY case TK_SELECT: case TK_EXISTS:#endif *((int*)pArg) = 0; return 2; default: return 0; }}/*** Walk an expression tree. Return 1 if the expression is constant** and 0 if it involves variables.**** For the purposes of this function, a double-quoted string (ex: "abc")** is considered a variable but a single-quoted string (ex: 'abc') is** a constant.*/int sqlite3ExprIsConstant(Expr *p){ int isConst = 1; walkExprTree(p, exprNodeIsConstant, &isConst); return isConst;}/*** If the expression p codes a constant integer that is small enough** to fit in a 32-bit integer, return 1 and put the value of the integer** in *pValue. If the expression is not an integer or if it is too big** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.*/int sqlite3ExprIsInteger(Expr *p, int *pValue){ switch( p->op ){ case TK_INTEGER: { if( sqlite3GetInt32(p->token.z, pValue) ){ return 1; } break; } case TK_UPLUS: { return sqlite3ExprIsInteger(p->pLeft, pValue); } case TK_UMINUS: { int v; if( sqlite3ExprIsInteger(p->pLeft, &v) ){ *pValue = -v; return 1; } break; } default: break; } return 0;}/*** Return TRUE if the given string is a row-id column name.*/int sqlite3IsRowid(const char *z){ if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; if( sqlite3StrICmp(z, "OID")==0 ) return 1; return 0;}/*** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up** that name in the set of source tables in pSrcList and make the pExpr ** expression node refer back to that source column. The following changes** are made to pExpr:**** pExpr->iDb Set the index in db->aDb[] of the database holding** the table.** pExpr->iTable Set to the cursor number for the table obtained** from pSrcList.** pExpr->iColumn Set to the column number within the table.** pExpr->op Set to TK_COLUMN.** pExpr->pLeft Any expression this points to is deleted** pExpr->pRight Any expression this points to is deleted.**** The pDbToken is the name of the database (the "X"). This value may be** NULL meaning that name is of the form Y.Z or Z. Any available database** can be used. The pTableToken is the name of the table (the "Y"). This** value can be NULL if pDbToken is also NULL. If pTableToken is NULL it** means that the form of the name is Z and that columns from any table** can be used.**** If the name cannot be resolved unambiguously, leave an error message** in pParse and return non-zero. Return zero on success.*/static int lookupName( Parse *pParse, /* The parsing context */ Token *pDbToken, /* Name of the database containing table, or NULL */ Token *pTableToken, /* Name of table containing column, or NULL */ Token *pColumnToken, /* Name of the column. */ NameContext *pNC, /* The name context used to resolve the name */ Expr *pExpr /* Make this EXPR node point to the selected column */){ char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */ char *zTab = 0; /* Name of the table. The "Y" in X.Y.Z or Y.Z */ char *zCol = 0; /* Name of the column. The "Z" */ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); if( sqlite3_malloc_failed ){ goto lookupname_end; } pExpr->iTable = -1; while( pNC && cnt==0 ){ SrcList *pSrcList = pNC->pSrcList; ExprList *pEList = pNC->pEList; /* assert( zTab==0 || pEList==0 ); */ if( pSrcList ){ for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ Table *pTab = pItem->pTab; Column *pCol; if( pTab==0 ) continue; assert( pTab->nCol>0 ); if( zTab ){ if( pItem->zAlias ){ char *zTabName = pItem->zAlias; if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; }else{ char *zTabName = pTab->zName; if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ continue; } } } if( 0==(cntTab++) ){ pExpr->iTable = pItem->iCursor; pExpr->iDb = pTab->iDb; pMatch = pItem; } for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){ if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ IdList *pUsing; cnt++; pExpr->iTable = pItem->iCursor; pMatch = pItem; pExpr->iDb = pTab->iDb; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -