diff options
Diffstat (limited to 'src/select.c')
-rw-r--r-- | src/select.c | 192 |
1 files changed, 111 insertions, 81 deletions
diff --git a/src/select.c b/src/select.c index 8c29b57db..e9b1958bd 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.354 2007/07/18 18:17:12 drh Exp $ +** $Id: select.c,v 1.355 2007/08/16 04:30:40 drh Exp $ */ #include "sqliteInt.h" @@ -39,6 +39,7 @@ static void clearSelect(Select *p){ ** structure. */ Select *sqlite3SelectNew( + Parse *pParse, /* Parsing context */ ExprList *pEList, /* which columns to include in the result */ SrcList *pSrc, /* the FROM clause -- which tables to scan */ Expr *pWhere, /* the WHERE clause */ @@ -51,14 +52,15 @@ Select *sqlite3SelectNew( ){ Select *pNew; Select standin; - pNew = sqliteMalloc( sizeof(*pNew) ); + sqlite3 *db = pParse->db; + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */ if( pNew==0 ){ pNew = &standin; memset(pNew, 0, sizeof(*pNew)); } if( pEList==0 ){ - pEList = sqlite3ExprListAppend(0, sqlite3Expr(TK_ALL,0,0,0), 0); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(TK_ALL,0,0,0), 0); } pNew->pEList = pEList; pNew->pSrc = pSrc; @@ -89,7 +91,7 @@ Select *sqlite3SelectNew( void sqlite3SelectDelete(Select *p){ if( p ){ clearSelect(p); - sqliteFree(p); + sqlite3_free(p); } } @@ -202,10 +204,10 @@ static void setQuotedToken(Token *p, const char *z){ /* ** Create an expression node for an identifier with the name of zName */ -Expr *sqlite3CreateIdExpr(const char *zName){ +Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){ Token dummy; setToken(&dummy, zName); - return sqlite3Expr(TK_ID, 0, 0, &dummy); + return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy); } @@ -214,6 +216,7 @@ Expr *sqlite3CreateIdExpr(const char *zName){ ** zCol column to be equal in the two tables pTab1 and pTab2. */ static void addWhereTerm( + Parse *pParse, /* Parsing context */ const char *zCol, /* Name of the column */ const Table *pTab1, /* First table */ const char *zAlias1, /* Alias for first table. May be NULL */ @@ -226,24 +229,24 @@ static void addWhereTerm( Expr *pE2a, *pE2b, *pE2c; Expr *pE; - pE1a = sqlite3CreateIdExpr(zCol); - pE2a = sqlite3CreateIdExpr(zCol); + pE1a = sqlite3CreateIdExpr(pParse, zCol); + pE2a = sqlite3CreateIdExpr(pParse, zCol); if( zAlias1==0 ){ zAlias1 = pTab1->zName; } - pE1b = sqlite3CreateIdExpr(zAlias1); + pE1b = sqlite3CreateIdExpr(pParse, zAlias1); if( zAlias2==0 ){ zAlias2 = pTab2->zName; } - pE2b = sqlite3CreateIdExpr(zAlias2); - pE1c = sqlite3ExprOrFree(TK_DOT, pE1b, pE1a, 0); - pE2c = sqlite3ExprOrFree(TK_DOT, pE2b, pE2a, 0); - pE = sqlite3ExprOrFree(TK_EQ, pE1c, pE2c, 0); + pE2b = sqlite3CreateIdExpr(pParse, zAlias2); + pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0); + pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0); + pE = sqlite3DbExpr(pParse, TK_EQ, pE1c, pE2c, 0); if( pE ){ ExprSetProperty(pE, EP_FromJoin); pE->iRightJoinTable = iRightJoinTable; } - pE = sqlite3ExprAnd(*ppExpr, pE); + pE = sqlite3ExprAnd(pParse->db,*ppExpr, pE); if( pE ){ *ppExpr = pE; } @@ -346,7 +349,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ */ if( pRight->pOn ){ setJoinExpr(pRight->pOn, pRight->iCursor); - p->pWhere = sqlite3ExprAnd(p->pWhere, pRight->pOn); + p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); pRight->pOn = 0; } @@ -689,7 +692,7 @@ static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ int i; nExpr = pList->nExpr; - pInfo = sqliteMalloc( sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) ); + pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) ); if( pInfo ){ pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr]; pInfo->nField = nExpr; @@ -992,7 +995,7 @@ static void generateColumnNames( #endif assert( v!=0 ); - if( pParse->colNamesSet || v==0 || sqlite3MallocFailed() ) return; + if( pParse->colNamesSet || v==0 || db->mallocFailed ) return; pParse->colNamesSet = 1; fullNames = (db->flags & SQLITE_FullColNames)!=0; shortNames = (db->flags & SQLITE_ShortColNames)!=0; @@ -1076,6 +1079,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ int i, j; ExprList *pEList; Column *aCol, *pCol; + sqlite3 *db = pParse->db; while( pSelect->pPrior ) pSelect = pSelect->pPrior; if( prepSelectStmt(pParse, pSelect) ){ @@ -1084,16 +1088,16 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ if( sqlite3SelectResolve(pParse, pSelect, 0) ){ return 0; } - pTab = sqliteMalloc( sizeof(Table) ); + pTab = sqlite3DbMallocZero(db, sizeof(Table) ); if( pTab==0 ){ return 0; } pTab->nRef = 1; - pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0; + pTab->zName = zTabName ? sqlite3DbStrDup(db, zTabName) : 0; pEList = pSelect->pEList; pTab->nCol = pEList->nExpr; assert( pTab->nCol>0 ); - pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); + pTab->aCol = aCol = sqlite3DbMallocZero(db, sizeof(pTab->aCol[0])*pTab->nCol); for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){ Expr *p, *pR; char *zType; @@ -1109,21 +1113,21 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); if( (zName = pEList->a[i].zName)!=0 ){ /* If the column contains an "AS <name>" phrase, use <name> as the name */ - zName = sqliteStrDup(zName); + zName = sqlite3DbStrDup(db, zName); }else if( p->op==TK_DOT && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ /* For columns of the from A.B use B as the name */ - zName = sqlite3MPrintf("%T", &pR->token); + zName = sqlite3MPrintf(db, "%T", &pR->token); }else if( p->span.z && p->span.z[0] ){ /* Use the original text of the column expression as its name */ - zName = sqlite3MPrintf("%T", &p->span); + zName = sqlite3MPrintf(db, "%T", &p->span); }else{ /* If all else fails, make up a name */ - zName = sqlite3MPrintf("column%d", i+1); + zName = sqlite3MPrintf(db, "column%d", i+1); } sqlite3Dequote(zName); - if( sqlite3MallocFailed() ){ - sqliteFree(zName); + if( db->mallocFailed ){ + sqlite3_free(zName); sqlite3DeleteTable(pTab); return 0; } @@ -1147,12 +1151,12 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ */ memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSelect->pSrc; - zType = sqliteStrDup(columnType(&sNC, p, 0, 0, 0)); + zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0)); pCol->zType = zType; pCol->affinity = sqlite3ExprAffinity(p); pColl = sqlite3ExprCollSeq(pParse, p); if( pColl ){ - pCol->zColl = sqliteStrDup(pColl->zName); + pCol->zColl = sqlite3DbStrDup(db, pColl->zName); } } pTab->iPKey = -1; @@ -1190,8 +1194,9 @@ static int prepSelectStmt(Parse *pParse, Select *p){ SrcList *pTabList; ExprList *pEList; struct SrcList_item *pFrom; + sqlite3 *db = pParse->db; - if( p==0 || p->pSrc==0 || sqlite3MallocFailed() ){ + if( p==0 || p->pSrc==0 || db->mallocFailed ){ return 1; } pTabList = p->pSrc; @@ -1255,7 +1260,7 @@ static int prepSelectStmt(Parse *pParse, Select *p){ ** in the inner view. */ if( pFrom->pSelect==0 ){ - pFrom->pSelect = sqlite3SelectDup(pTab->pSelect); + pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect); } } #endif @@ -1301,7 +1306,7 @@ static int prepSelectStmt(Parse *pParse, Select *p){ (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){ /* This particular expression does not need to be expanded. */ - pNew = sqlite3ExprListAppend(pNew, a[k].pExpr, 0); + pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr, 0); if( pNew ){ pNew->a[pNew->nExpr-1].zName = a[k].zName; }else{ @@ -1315,7 +1320,7 @@ static int prepSelectStmt(Parse *pParse, Select *p){ int tableSeen = 0; /* Set to 1 when TABLE matches */ char *zTName; /* text of name of TABLE */ if( pE->op==TK_DOT && pE->pLeft ){ - zTName = sqlite3NameFromToken(&pE->pLeft->token); + zTName = sqlite3NameFromToken(db, &pE->pLeft->token); }else{ zTName = 0; } @@ -1376,9 +1381,9 @@ static int prepSelectStmt(Parse *pParse, Select *p){ pExpr->span.dyn = 0; } if( longNames ){ - pNew = sqlite3ExprListAppend(pNew, pExpr, &pExpr->span); + pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pExpr->span); }else{ - pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token); + pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pRight->token); } } } @@ -1390,7 +1395,7 @@ static int prepSelectStmt(Parse *pParse, Select *p){ } rc = 1; } - sqliteFree(zTName); + sqlite3_free(zTName); } } sqlite3ExprListDelete(pEList); @@ -1400,7 +1405,7 @@ static int prepSelectStmt(Parse *pParse, Select *p){ sqlite3ErrorMsg(pParse, "too many columns in result set"); rc = SQLITE_ERROR; } - if( sqlite3MallocFailed() ){ + if( db->mallocFailed ){ rc = SQLITE_NOMEM; } return rc; @@ -1430,6 +1435,7 @@ static int matchOrderbyToColumn( int nErr = 0; int i, j; ExprList *pEList; + sqlite3 *db = pParse->db; if( pSelect==0 || pOrderBy==0 ) return 1; if( mustComplete ){ @@ -1462,23 +1468,23 @@ static int matchOrderbyToColumn( if( !mustComplete ) continue; iCol--; } - if( iCol<0 && (zLabel = sqlite3NameFromToken(&pE->token))!=0 ){ + if( iCol<0 && (zLabel = sqlite3NameFromToken(db, &pE->token))!=0 ){ for(j=0, pItem=pEList->a; j<pEList->nExpr; j++, pItem++){ char *zName; int isMatch; if( pItem->zName ){ - zName = sqlite3StrDup(pItem->zName); + zName = sqlite3DbStrDup(db, pItem->zName); }else{ - zName = sqlite3NameFromToken(&pItem->pExpr->token); + zName = sqlite3NameFromToken(db, &pItem->pExpr->token); } isMatch = zName && sqlite3StrICmp(zName, zLabel)==0; - sqliteFree(zName); + sqlite3_free(zName); if( isMatch ){ iCol = j; break; } } - sqliteFree(zLabel); + sqlite3_free(zLabel); } if( iCol>=0 ){ pE->op = TK_COLUMN; @@ -1962,7 +1968,8 @@ static int multiSelect( assert( p->pRightmost==p ); nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0); - pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1)); + pKeyInfo = sqlite3DbMallocZero(pParse->db, + sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1)); if( !pKeyInfo ){ rc = SQLITE_NOMEM; goto multi_select_end; @@ -2037,7 +2044,7 @@ static int multiSelect( generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm); } - sqliteFree(pKeyInfo); + sqlite3_free(pKeyInfo); } multi_select_end: @@ -2046,6 +2053,10 @@ multi_select_end: #endif /* SQLITE_OMIT_COMPOUND_SELECT */ #ifndef SQLITE_OMIT_VIEW +/* Forward Declarations */ +static void substExprList(sqlite3*, ExprList*, int, ExprList*); +static void substSelect(sqlite3*, Select *, int, ExprList *); + /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th @@ -2059,9 +2070,12 @@ multi_select_end: ** changes to pExpr so that it refers directly to the source table ** of the subquery rather the result set of the subquery. */ -static void substExprList(ExprList*,int,ExprList*); /* Forward Decl */ -static void substSelect(Select *, int, ExprList *); /* Forward Decl */ -static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){ +static void substExpr( + sqlite3 *db, /* Report malloc errors to this connection */ + Expr *pExpr, /* Expr in which substitution occurs */ + int iTable, /* Table to be substituted */ + ExprList *pEList /* Substitute expressions */ +){ if( pExpr==0 ) return; if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ if( pExpr->iColumn<0 ){ @@ -2074,42 +2088,52 @@ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){ assert( pNew!=0 ); pExpr->op = pNew->op; assert( pExpr->pLeft==0 ); - pExpr->pLeft = sqlite3ExprDup(pNew->pLeft); + pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft); assert( pExpr->pRight==0 ); - pExpr->pRight = sqlite3ExprDup(pNew->pRight); + pExpr->pRight = sqlite3ExprDup(db, pNew->pRight); assert( pExpr->pList==0 ); - pExpr->pList = sqlite3ExprListDup(pNew->pList); + pExpr->pList = sqlite3ExprListDup(db, pNew->pList); pExpr->iTable = pNew->iTable; pExpr->pTab = pNew->pTab; pExpr->iColumn = pNew->iColumn; pExpr->iAgg = pNew->iAgg; - sqlite3TokenCopy(&pExpr->token, &pNew->token); - sqlite3TokenCopy(&pExpr->span, &pNew->span); - pExpr->pSelect = sqlite3SelectDup(pNew->pSelect); + sqlite3TokenCopy(db, &pExpr->token, &pNew->token); + sqlite3TokenCopy(db, &pExpr->span, &pNew->span); + pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect); pExpr->flags = pNew->flags; } }else{ - substExpr(pExpr->pLeft, iTable, pEList); - substExpr(pExpr->pRight, iTable, pEList); - substSelect(pExpr->pSelect, iTable, pEList); - substExprList(pExpr->pList, iTable, pEList); + substExpr(db, pExpr->pLeft, iTable, pEList); + substExpr(db, pExpr->pRight, iTable, pEList); + substSelect(db, pExpr->pSelect, iTable, pEList); + substExprList(db, pExpr->pList, iTable, pEList); } } -static void substExprList(ExprList *pList, int iTable, ExprList *pEList){ +static void substExprList( + sqlite3 *db, /* Report malloc errors here */ + ExprList *pList, /* List to scan and in which to make substitutes */ + int iTable, /* Table to be substituted */ + ExprList *pEList /* Substitute values */ +){ int i; if( pList==0 ) return; for(i=0; i<pList->nExpr; i++){ - substExpr(pList->a[i].pExpr, iTable, pEList); + substExpr(db, pList->a[i].pExpr, iTable, pEList); } } -static void substSelect(Select *p, int iTable, ExprList *pEList){ +static void substSelect( + sqlite3 *db, /* Report malloc errors here */ + Select *p, /* SELECT statement in which to make substitutions */ + int iTable, /* Table to be replaced */ + ExprList *pEList /* Substitute values */ +){ if( !p ) return; - substExprList(p->pEList, iTable, pEList); - substExprList(p->pGroupBy, iTable, pEList); - substExprList(p->pOrderBy, iTable, pEList); - substExpr(p->pHaving, iTable, pEList); - substExpr(p->pWhere, iTable, pEList); - substSelect(p->pPrior, iTable, pEList); + substExprList(db, p->pEList, iTable, pEList); + substExprList(db, p->pGroupBy, iTable, pEList); + substExprList(db, p->pOrderBy, iTable, pEList); + substExpr(db, p->pHaving, iTable, pEList); + substExpr(db, p->pWhere, iTable, pEList); + substSelect(db, p->pPrior, iTable, pEList); } #endif /* !defined(SQLITE_OMIT_VIEW) */ @@ -2192,6 +2216,7 @@ static void substSelect(Select *p, int iTable, ExprList *pEList){ ** the subquery before this routine runs. */ static int flattenSubquery( + sqlite3 *db, /* Database connection */ Select *p, /* The parent or outer SELECT statement */ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ int isAgg, /* True if outer SELECT uses aggregate functions */ @@ -2289,13 +2314,13 @@ static int flattenSubquery( int jointype = pSubitem->jointype; sqlite3DeleteTable(pSubitem->pTab); - sqliteFree(pSubitem->zDatabase); - sqliteFree(pSubitem->zName); - sqliteFree(pSubitem->zAlias); + sqlite3_free(pSubitem->zDatabase); + sqlite3_free(pSubitem->zName); + sqlite3_free(pSubitem->zAlias); if( nSubSrc>1 ){ int extra = nSubSrc - 1; for(i=1; i<nSubSrc; i++){ - pSrc = sqlite3SrcListAppend(pSrc, 0, 0); + pSrc = sqlite3SrcListAppend(db, pSrc, 0, 0); } p->pSrc = pSrc; for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){ @@ -2325,7 +2350,8 @@ static int flattenSubquery( for(i=0; i<pList->nExpr; i++){ Expr *pExpr; if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){ - pList->a[i].zName = sqliteStrNDup((char*)pExpr->span.z, pExpr->span.n); + pList->a[i].zName = + sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n); } } substExprList(p->pEList, iParent, pSub->pEList); @@ -2341,7 +2367,7 @@ static int flattenSubquery( substExprList(p->pOrderBy, iParent, pSub->pEList); } if( pSub->pWhere ){ - pWhere = sqlite3ExprDup(pSub->pWhere); + pWhere = sqlite3ExprDup(db, pSub->pWhere); }else{ pWhere = 0; } @@ -2350,12 +2376,13 @@ static int flattenSubquery( p->pHaving = p->pWhere; p->pWhere = pWhere; substExpr(p->pHaving, iParent, pSub->pEList); - p->pHaving = sqlite3ExprAnd(p->pHaving, sqlite3ExprDup(pSub->pHaving)); + p->pHaving = sqlite3ExprAnd(db, p->pHaving, + sqlite3ExprDup(db, pSub->pHaving)); assert( p->pGroupBy==0 ); - p->pGroupBy = sqlite3ExprListDup(pSub->pGroupBy); + p->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy); }else{ substExpr(p->pWhere, iParent, pSub->pEList); - p->pWhere = sqlite3ExprAnd(p->pWhere, pWhere); + p->pWhere = sqlite3ExprAnd(db, p->pWhere, pWhere); } /* The flattened query is distinct if either the inner or the @@ -2571,7 +2598,8 @@ static int processOrderGroupBy( CollSeq *pColl = pE->pColl; int flags = pE->flags & EP_ExpCollate; sqlite3ExprDelete(pE); - pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); + pE = sqlite3ExprDup(pParse->db, pEList->a[iCol-1].pExpr); + pOrderBy->a[i].pExpr = pE; if( pColl && flags ){ pE->pColl = pColl; pE->flags |= flags; @@ -2690,7 +2718,7 @@ int sqlite3SelectResolve( } } - if( sqlite3MallocFailed() ){ + if( db->mallocFailed ){ return SQLITE_NOMEM; } @@ -2897,8 +2925,10 @@ int sqlite3Select( int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ + sqlite3 *db; /* The database connection */ - if( p==0 || sqlite3MallocFailed() || pParse->nErr ){ + db = pParse->db; + if( p==0 || db->mallocFailed || pParse->nErr ){ return 1; } if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; @@ -3027,7 +3057,7 @@ int sqlite3Select( */ #ifndef SQLITE_OMIT_VIEW if( pParent && pParentAgg && - flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){ + flattenSubquery(db, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; goto select_end; } @@ -3154,7 +3184,7 @@ int sqlite3Select( goto select_end; } } - if( sqlite3MallocFailed() ) goto select_end; + if( db->mallocFailed ) goto select_end; /* Processing for aggregates with GROUP BY is very different and ** much more complex tha aggregates without a GROUP BY. @@ -3403,8 +3433,8 @@ select_end: generateColumnNames(pParse, pTabList, pEList); } - sqliteFree(sAggInfo.aCol); - sqliteFree(sAggInfo.aFunc); + sqlite3_free(sAggInfo.aCol); + sqlite3_free(sAggInfo.aFunc); return rc; } |