diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rowset.c | 10 | ||||
-rw-r--r-- | src/sqliteInt.h | 30 | ||||
-rw-r--r-- | src/vdbe.c | 30 | ||||
-rw-r--r-- | src/vdbeaux.c | 6 | ||||
-rw-r--r-- | src/where.c | 37 |
5 files changed, 54 insertions, 59 deletions
diff --git a/src/rowset.c b/src/rowset.c index 4e27676cb..edfde11e9 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -60,7 +60,7 @@ ** There is an added cost of O(N) when switching between TEST and ** SMALLEST primitives. ** -** $Id: rowset.c,v 1.5 2009/04/22 00:47:01 drh Exp $ +** $Id: rowset.c,v 1.6 2009/04/22 15:32:59 drh Exp $ */ #include "sqliteInt.h" @@ -277,9 +277,7 @@ static void rowSetTreeToList( struct RowSetEntry **ppFirst, /* Write head of the output list here */ struct RowSetEntry **ppLast /* Write tail of the output list here */ ){ - if( pIn==0 ){ - *ppFirst = *ppLast = 0; - } + assert( pIn!=0 ); if( pIn->pLeft ){ struct RowSetEntry *p; rowSetTreeToList(pIn->pLeft, ppFirst, &p); @@ -344,9 +342,7 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ struct RowSetEntry *p; /* Current tree root */ struct RowSetEntry *pLeft; /* Left subtree */ - if( pList==0 ){ - return 0; - } + assert( pList!=0 ); p = pList; pList = p->pRight; p->pLeft = p->pRight = 0; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5a61ea5b4..66a22ded1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.858 2009/04/22 02:15:48 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.859 2009/04/22 15:32:59 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -220,6 +220,20 @@ #endif /* +** Sometimes we need a small amount of code such as a variable initialization +** to setup for a later assert() statement. We do not want this code to +** appear when assert() is disabled. The following macro is therefore +** used to contain that setup code. The "VVA" acronym stands for +** "Verification, Validation, and Accreditation". In other words, the +** code within VVA_ONLY() will only run during verification processes. +*/ +#ifndef NDEBUG +# define VVA_ONLY(X) X +#else +# define VVA_ONLY(X) +#endif + +/* ** The ALWAYS and NEVER macros surround boolean expressions which ** are intended to always be true or false, respectively. Such ** expressions could be omitted from the code completely. But they @@ -260,20 +274,6 @@ # define unlikely(X) !!(X) #endif -/* -** Sometimes we need a small amount of code such as a variable initialization -** to setup for a later assert() statement. We do not want this code to -** appear when assert() is disabled. The following macro is therefore -** used to contain that setup code. The "VVA" acronym stands for -** "Verification, Validation, and Accreditation". In other words, the -** code within VVA_ONLY() will only run during verification processes. -*/ -#ifndef NDEBUG -# define VVA_ONLY(X) X -#else -# define VVA_ONLY(X) -#endif - #include "sqlite3.h" #include "hash.h" #include "parse.h" diff --git a/src/vdbe.c b/src/vdbe.c index a5312fc83..be6cd4fff 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.837 2009/04/22 02:15:48 drh Exp $ +** $Id: vdbe.c,v 1.838 2009/04/22 15:32:59 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -3905,19 +3905,23 @@ case OP_Rowid: { /* out2-prerelease */ assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); - rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; - if( pC->rowidIsValid ){ - v = pC->lastRowid; - }else if( pC->pseudoTable ){ - v = keyToInt(pC->iKey); - }else if( pC->nullRow ){ - /* Leave the rowid set to a NULL */ - break; + if( pC->deferredMoveto ){ + v = pC->movetoTarget; }else{ - assert( pC->pCursor!=0 ); - sqlite3BtreeKeySize(pC->pCursor, &v); - v = keyToInt(v); + rc = sqlite3VdbeCursorMoveto(pC); + if( rc ) goto abort_due_to_error; + if( pC->rowidIsValid ){ + v = pC->lastRowid; + }else if( pC->pseudoTable ){ + v = keyToInt(pC->iKey); + }else if( pC->nullRow ){ + /* Leave the rowid set to a NULL */ + break; + }else{ + assert( pC->pCursor!=0 ); + sqlite3BtreeKeySize(pC->pCursor, &v); + v = keyToInt(v); + } } pOut->u.i = v; MemSetTypeFlag(pOut, MEM_Int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8d16b875c..4bf842672 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.453 2009/04/22 02:15:48 drh Exp $ +** $Id: vdbeaux.c,v 1.454 2009/04/22 15:32:59 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -2002,8 +2002,8 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){ rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; p->lastRowid = keyToInt(p->movetoTarget); - p->rowidIsValid = res==0 ?1:0; - if( res<0 ){ + p->rowidIsValid = ALWAYS(res==0) ?1:0; + if( NEVER(res<0) ){ rc = sqlite3BtreeNext(p->pCursor, &res); if( rc ) return rc; } diff --git a/src/where.c b/src/where.c index 15c3e7365..6b81c363f 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.385 2009/04/22 02:15:49 drh Exp $ +** $Id: where.c,v 1.386 2009/04/22 15:32:59 drh Exp $ */ #include "sqliteInt.h" @@ -43,10 +43,8 @@ typedef struct WhereCost WhereCost; /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE -** clause subexpression is separated from the others by AND operators. -** (Note: the same data structure is also reused to hold a group of terms -** separated by OR operators. But at the top-level, everything is AND -** separated.) +** clause subexpression is separated from the others by AND operators, +** usually, or sometimes subexpressions separated by OR. ** ** All WhereTerms are collected into a single WhereClause structure. ** The following identity holds: @@ -375,7 +373,7 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){ } /* -** Initialize an expression mask set +** Initialize an expression mask set (a WhereMaskSet object) */ #define initMaskSet(P) memset(P, 0, sizeof(*P)) @@ -2406,25 +2404,22 @@ static Bitmask codeOneLoopStart( int addrBrk; /* Jump here to break out of the loop */ int addrCont; /* Jump here to continue with next cycle */ int regRowSet; /* Write rowids to this RowSet if non-negative */ - int codeRowSetEarly; /* True if index fully constrains the search */ /* Sometimes, this function is required to generate code to do - ** something with the rowid of each row scanned. Specifically: - ** - ** 1) If pWInfo->regRowSet is non-zero, then the rowid must be inserted - ** into the RowSet object stored in register pWInfo->regRowSet. + ** something with the rowid of each row scanned. Specifically, + ** If pWInfo->regRowSet is non-zero, then the rowid must be inserted + ** into the RowSet object stored in register pWInfo->regRowSet. ** ** Extracting a rowid value from a VDBE cursor is not always a cheap ** operation, especially if the rowid is being extracted from an index ** cursor. If the rowid value is available as a by-product of the code ** generated to create the top of the scan loop, then it can be reused - ** without extracting - ** it from a cursor. The following two variables are used to communicate - ** the availability of the rowid value to the C-code at the end of this - ** function that generates the rowid-handling VDBE code. + ** without extracting it from a cursor. The following two variables are + ** used to communicate the availability of the rowid value to the C-code + ** at the end of this function that generates the rowid-handling VDBE code. */ - int iRowidReg = 0; /* Rowid is stored in this register */ - int iReleaseReg = 0; /* Temp register to free before returning */ + int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ + int iReleaseReg = 0; /* Temp register to free before returning */ pParse = pWInfo->pParse; v = pParse->pVdbe; @@ -2436,7 +2431,6 @@ static Bitmask codeOneLoopStart( omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 && (wctrlFlags & WHERE_FILL_ROWTEST)==0; regRowSet = pWInfo->regRowSet; - codeRowSetEarly = 0; /* Create labels for the "break" and "continue" instructions ** for the current loop. Jump to addrBrk to break out of a loop. @@ -2877,7 +2871,6 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); - /* iReleaseReg = iRowidReg = sqlite3GetTempReg(pParse); */ for(ii=0; ii<pOrWc->nTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){ @@ -2895,6 +2888,7 @@ static Bitmask codeOneLoopStart( ** loop is not executed. */ int iRowSet = pSubWInfo->iRowidHandler; + assert( iRowSet>0 || pWInfo->pParse->db->mallocFailed ); sqlite3VdbeChangeP2(v, iRowSet, sqlite3VdbeCurrentAddr(v) + 1); sqlite3VdbeChangeP4(v, iRowSet, (char *)iSet, P4_INT32); sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); @@ -2991,12 +2985,13 @@ static Bitmask codeOneLoopStart( } } - pWInfo->iRowidHandler = sqlite3VdbeCurrentAddr(v); if( pWInfo->wctrlFlags&WHERE_FILL_ROWSET ){ sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, iRowidReg); + VVA_ONLY( pWInfo->iRowidHandler = 0; ) }else{ assert( pWInfo->wctrlFlags&WHERE_FILL_ROWTEST ); - sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg); + pWInfo->iRowidHandler = + sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg); } } sqlite3ReleaseTempReg(pParse, iReleaseReg); |