diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/delete.c | 3 | ||||
-rw-r--r-- | src/expr.c | 3 | ||||
-rw-r--r-- | src/resolve.c | 20 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/update.c | 3 | ||||
-rw-r--r-- | src/where.c | 27 |
6 files changed, 41 insertions, 18 deletions
diff --git a/src/delete.c b/src/delete.c index 5ad732755..b70352c87 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.193 2009/02/20 10:58:42 danielk1977 Exp $ +** $Id: delete.c,v 1.194 2009/02/23 17:33:50 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -395,6 +395,7 @@ void sqlite3DeleteFrom( /* Collect rowids of every row to be deleted. */ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); + pTabList->a[0].usesRowid = 1; pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, WHERE_FILL_ROWSET, iRowSet); if( pWInfo==0 ) goto delete_from_cleanup; diff --git a/src/expr.c b/src/expr.c index af9938220..4b92d6c0f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.414 2009/02/20 10:58:42 danielk1977 Exp $ +** $Id: expr.c,v 1.415 2009/02/23 17:33:50 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -931,6 +931,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); pNewItem->colUsed = pOldItem->colUsed; + pNewItem->usesRowid = pOldItem->usesRowid; } return pNew; } diff --git a/src/resolve.c b/src/resolve.c index af44730ef..29f1f2b92 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -14,7 +14,7 @@ ** resolve all identifiers by associating them with a particular ** table and column. ** -** $Id: resolve.c,v 1.16 2009/02/19 14:39:25 danielk1977 Exp $ +** $Id: resolve.c,v 1.17 2009/02/23 17:33:50 danielk1977 Exp $ */ #include "sqliteInt.h" #include <stdlib.h> @@ -347,14 +347,18 @@ static int lookupName( ** column number is greater than the number of bits in the bitmask ** then set the high-order bit of the bitmask. */ - if( pExpr->iColumn>=0 && pMatch!=0 ){ - int n = pExpr->iColumn; - testcase( n==BMS-1 ); - if( n>=BMS ){ - n = BMS-1; + if( pMatch ){ + if( pExpr->iColumn>=0 ){ + int n = pExpr->iColumn; + testcase( n==BMS-1 ); + if( n>=BMS ){ + n = BMS-1; + } + assert( pMatch->iCursor==pExpr->iTable ); + pMatch->colUsed |= ((Bitmask)1)<<n; + }else{ + pMatch->usesRowid = 1; } - assert( pMatch->iCursor==pExpr->iTable ); - pMatch->colUsed |= ((Bitmask)1)<<n; } lookupname_end: diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 98c3e364f..7c5a05bb5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.835 2009/02/23 16:52:08 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.836 2009/02/23 17:33:50 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1601,6 +1601,7 @@ struct SrcList { u8 isPopulated; /* Temporary table associated with SELECT is populated */ u8 jointype; /* Type of join between this able and the previous */ u8 notIndexed; /* True if there is a NOT INDEXED clause */ + u8 usesRowid; /* True if the rowid field is read */ int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ IdList *pUsing; /* The USING clause of a join */ diff --git a/src/update.c b/src/update.c index bd40e26e6..8cfbf3a98 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.193 2009/02/20 10:58:42 danielk1977 Exp $ +** $Id: update.c,v 1.194 2009/02/23 17:33:50 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -343,6 +343,7 @@ void sqlite3Update( /* Begin the database scan */ sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); + pTabList->a[0].usesRowid = 1; pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, WHERE_ONEPASS_DESIRED, 0); if( pWInfo==0 ) goto update_cleanup; diff --git a/src/where.c b/src/where.c index ea6e00a80..e76fc11cb 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.371 2009/02/23 16:52:08 drh Exp $ +** $Id: where.c,v 1.372 2009/02/23 17:33:50 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -1715,15 +1715,15 @@ static double bestVirtualIndex( ** * Whether or not there must be separate lookups in the ** index and in the main table. ** -** If there was an INDEXED BY clause attached to the table in the SELECT -** statement, then this function only considers plans using the +** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in +** the SQL statement, then this function only considers plans using the ** named index. If one cannot be found, then the returned cost is ** SQLITE_BIG_DBL. If a plan can be found that uses the named index, ** then the cost is calculated in the usual way. ** -** If a NOT INDEXED clause was attached to the table in the SELECT -** statement, then no indexes are considered. However, the selected -** plan may still take advantage of the tables built-in rowid +** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table +** in the SELECT statement, then no indexes are considered. However, the +** selected plan may still take advantage of the tables built-in rowid ** index. */ static void bestIndex( @@ -2035,6 +2035,21 @@ static void bestIndex( } } + if( pCost->plan.wsFlags==0 && pSrc->colUsed==0 && pSrc->usesRowid==0 ){ + Index *pSmallest = 0; + assert( pSrc->pIndex==0 ); + for(pProbe=pSrc->pTab->pIndex; pProbe; pProbe=pProbe->pNext){ + if( !pSmallest || pProbe->nColumn<pSmallest->nColumn ){ + pSmallest = pProbe; + } + } + if( pSmallest && pSmallest->nColumn<pSrc->pTab->nCol ){ + assert( pCost->plan.nEq==0 ); + pCost->plan.u.pIdx = pSmallest; + pCost->plan.wsFlags = WHERE_COLUMN_RANGE|WHERE_IDX_ONLY; + } + } + /* Report the best result */ pCost->plan.wsFlags |= eqTermMask; |