aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rowset.c10
-rw-r--r--src/sqliteInt.h30
-rw-r--r--src/vdbe.c30
-rw-r--r--src/vdbeaux.c6
-rw-r--r--src/where.c37
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);