Change the OP_Rowid opcode so that a deferred OP_Seek is pending, it simply
pulls the rowid from the deferred seek target and does not actually move
the cursor or do a seek.  Other where.c cleanups. (CVS 6536)

FossilOrigin-Name: 1c508a99822caa383e7e24b5d09a9bddd2ee3a00
diff --git a/src/rowset.c b/src/rowset.c
index 4e27676..edfde11 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 @@
   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 @@
   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 5a61ea5..66a22de 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 a5312fc..be6cd4f 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 @@
   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 8d16b87..4bf8426 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 @@
     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 15c3e73..6b81c36 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 @@
 /*
 ** 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 @@
 }
 
 /*
-** 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 @@
   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 @@
   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 @@
     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 @@
           ** 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 @@
       }
     }
     
-    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);