diff options
Diffstat (limited to 'src/where.c')
-rw-r--r-- | src/where.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/src/where.c b/src/where.c index 89e3f31e9..22b6e07ba 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.368 2009/02/04 03:59:25 shane Exp $ +** $Id: where.c,v 1.369 2009/02/19 14:39:25 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -431,8 +431,11 @@ static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){ } mask = exprTableUsage(pMaskSet, p->pRight); mask |= exprTableUsage(pMaskSet, p->pLeft); - mask |= exprListTableUsage(pMaskSet, p->pList); - mask |= exprSelectTableUsage(pMaskSet, p->pSelect); + if( ExprHasProperty(p, EP_xIsSelect) ){ + mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect); + }else{ + mask |= exprListTableUsage(pMaskSet, p->x.pList); + } return mask; } static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){ @@ -634,7 +637,7 @@ static int isLikeOrGlob( #ifdef SQLITE_EBCDIC if( *pnoCase ) return 0; #endif - pList = pExpr->pList; + pList = pExpr->x.pList; pRight = pList->a[0].pExpr; if( pRight->op!=TK_STRING ){ return 0; @@ -689,7 +692,7 @@ static int isMatchOfColumn( sqlite3StrNICmp((const char*)pExpr->token.z,"match",5)!=0 ){ return 0; } - pList = pExpr->pList; + pList = pExpr->x.pList; if( pList->nExpr!=2 ){ return 0; } @@ -953,17 +956,18 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->eOperator==WO_EQ ); assert( pOrTerm->leftCursor==iCursor ); assert( pOrTerm->u.leftColumn==iColumn ); - pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight); + pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0); pLeft = pOrTerm->pExpr->pLeft; } assert( pLeft!=0 ); - pDup = sqlite3ExprDup(db, pLeft); + pDup = sqlite3ExprDup(db, pLeft, 0); pNew = sqlite3Expr(db, TK_IN, pDup, 0, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); - pNew->pList = pList; + assert( !ExprHasProperty(pNew, EP_xIsSelect) ); + pNew->x.pList = pList; idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); exprAnalyze(pSrc, pWC, idxNew); @@ -1026,8 +1030,11 @@ static void exprAnalyze( op = pExpr->op; if( op==TK_IN ){ assert( pExpr->pRight==0 ); - pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList) - | exprSelectTableUsage(pMaskSet, pExpr->pSelect); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect); + }else{ + pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList); + } }else if( op==TK_ISNULL ){ pTerm->prereqRight = 0; }else{ @@ -1057,7 +1064,7 @@ static void exprAnalyze( Expr *pDup; if( pTerm->leftCursor>=0 ){ int idxNew; - pDup = sqlite3ExprDup(db, pExpr); + pDup = sqlite3ExprDup(db, pExpr, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDup); return; @@ -1100,7 +1107,7 @@ static void exprAnalyze( ** BETWEEN term is skipped. */ else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){ - ExprList *pList = pExpr->pList; + ExprList *pList = pExpr->x.pList; int i; static const u8 ops[] = {TK_GE, TK_LE}; assert( pList!=0 ); @@ -1108,8 +1115,8 @@ static void exprAnalyze( for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; - pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft), - sqlite3ExprDup(db, pList->a[i].pExpr), 0); + pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft, 0), + sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); exprAnalyze(pSrc, pWC, idxNew); @@ -1148,18 +1155,18 @@ static void exprAnalyze( Expr *pNewExpr1, *pNewExpr2; int idxNew1, idxNew2; - pLeft = pExpr->pList->a[1].pExpr; - pRight = pExpr->pList->a[0].pExpr; + pLeft = pExpr->x.pList->a[1].pExpr; + pRight = pExpr->x.pList->a[0].pExpr; pStr1 = sqlite3PExpr(pParse, TK_STRING, 0, 0, 0); if( pStr1 ){ sqlite3TokenCopy(db, &pStr1->token, &pRight->token); pStr1->token.n = nPattern; pStr1->flags = EP_Dequoted; } - pStr2 = sqlite3ExprDup(db, pStr1); + pStr2 = sqlite3ExprDup(db, pStr1, 0); if( !db->mallocFailed ){ u8 c, *pC; - assert( pStr2->token.dyn ); + /* assert( pStr2->token.dyn ); */ pC = (u8*)&pStr2->token.z[nPattern-1]; c = *pC; if( noCase ){ @@ -1168,11 +1175,11 @@ static void exprAnalyze( } *pC = c + 1; } - pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft), pStr1, 0); + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft,0),pStr1,0); idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew1==0 ); exprAnalyze(pSrc, pWC, idxNew1); - pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft), pStr2, 0); + pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprDup(db,pLeft,0),pStr2,0); idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew2==0 ); exprAnalyze(pSrc, pWC, idxNew2); @@ -1198,13 +1205,13 @@ static void exprAnalyze( WhereTerm *pNewTerm; Bitmask prereqColumn, prereqExpr; - pRight = pExpr->pList->a[0].pExpr; - pLeft = pExpr->pList->a[1].pExpr; + pRight = pExpr->x.pList->a[0].pExpr; + pLeft = pExpr->x.pList->a[1].pExpr; prereqExpr = exprTableUsage(pMaskSet, pRight); prereqColumn = exprTableUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; - pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight), 0); + pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight, 0), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); pNewTerm = &pWC->a[idxNew]; @@ -1776,10 +1783,12 @@ static void bestIndex( pCost->rCost = 0; pCost->nRow = 1; return; - }else if( (pExpr = pTerm->pExpr)->pList!=0 ){ + }else if( !ExprHasProperty((pExpr = pTerm->pExpr), EP_xIsSelect) + && pExpr->x.pList + ){ /* Rowid IN (LIST): cost is NlogN where N is the number of list ** elements. */ - pCost->rCost = pCost->nRow = pExpr->pList->nExpr; + pCost->rCost = pCost->nRow = pExpr->x.pList->nExpr; pCost->rCost *= estLog(pCost->rCost); }else{ /* Rowid IN (SELECT): cost is NlogN where N is the number of rows @@ -1925,10 +1934,10 @@ static void bestIndex( if( pTerm->eOperator & WO_IN ){ Expr *pExpr = pTerm->pExpr; wsFlags |= WHERE_COLUMN_IN; - if( pExpr->pSelect!=0 ){ + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ inMultiplier *= 25; - }else if( pExpr->pList ){ - inMultiplier *= pExpr->pList->nExpr + 1; + }else if( pExpr->x.pList ){ + inMultiplier *= pExpr->x.pList->nExpr + 1; } } } |