]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the OP_Rowid opcode so that a deferred OP_Seek is pending, it simply
authordrh <drh@noemail.net>
Wed, 22 Apr 2009 15:32:59 +0000 (15:32 +0000)
committerdrh <drh@noemail.net>
Wed, 22 Apr 2009 15:32:59 +0000 (15:32 +0000)
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

manifest
manifest.uuid
src/rowset.c
src/sqliteInt.h
src/vdbe.c
src/vdbeaux.c
src/where.c

index 6d41c9a92e3c5ba7ecdeb80d3b7828fed902743e..74420c53a2aa8ee10ce46676e68ffe67806156bf 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sthe\srowhash\sobject\sfrom\sthe\scode.\s\sRowset\snow\sfills\sits\srole.\s(CVS\s6535)
-D 2009-04-22T02:15:48
+C Change\sthe\sOP_Rowid\sopcode\sso\sthat\sa\sdeferred\sOP_Seek\sis\spending,\sit\ssimply\npulls\sthe\srowid\sfrom\sthe\sdeferred\sseek\starget\sand\sdoes\snot\sactually\smove\nthe\scursor\sor\sdo\sa\sseek.\s\sOther\swhere.c\scleanups.\s(CVS\s6536)
+D 2009-04-22T15:32:59
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -154,12 +154,12 @@ F src/prepare.c 72d74e6d3b9c8eb0663b33ec6438aa718096ac79
 F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384
 F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
 F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d
-F src/rowset.c ee0f774f20bf3fd27470603d2d56d1767bbe1013
+F src/rowset.c 14d12b5e81b5907b87d511f6f4219805f96a4b55
 F src/select.c 35225756c247484f473678e5bd191d70a6e4dba0
 F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
 F src/sqlite.h.in 8e0e256079bac2319380bdfebf403fcbe630510f
 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
-F src/sqliteInt.h dc64bc8198a2ad3532a996fcecda71ff89a578f0
+F src/sqliteInt.h b663bb04bc2d71d8f156f559ff267045de64787a
 F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
 F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
@@ -200,16 +200,16 @@ F src/update.c 8ededddcde6f7b6da981dd0429a5d34518a475b7
 F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
 F src/util.c 828c552a22a1d5b650b8a5ea0009546715c45d93
 F src/vacuum.c 07121a727beeee88f27d704a00313ad6a7c9bef0
-F src/vdbe.c 13f976672cd9d7fce04f9847d74da8c3b869a013
+F src/vdbe.c ff8870fd2a4a5a3f7f8d24e5d0f4e73c22402c4f
 F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
 F src/vdbeInt.h 8726f7b4e3b55c8acf6d304a5b5f727ac1b6c5ab
 F src/vdbeapi.c 015c9d0fb7047657a13a7bb6aa886f75e43db02d
-F src/vdbeaux.c fdad66c73adb1c6ca6a0cd7a0f9517e5df758122
+F src/vdbeaux.c 34524d499fc6081e97771dcfdf6c2523d5877ef5
 F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
 F src/vdbemem.c 111d8193859d16aefd5d3cb57472808584ea5503
 F src/vtab.c 6118d71c5137e20a7ac51fb5d9beb0361fbedb89
 F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
-F src/where.c 48f711d293486b43bf87ab3d1eeeebae50cb6839
+F src/where.c 576a21f6e0bb6651f3354b5cee7ecc67b935b2a5
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
@@ -720,7 +720,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P b101cf70b75c9772aaf50e0eadd0cfa37c84d193
-R 4b293c104cb64e8cb94e481dce760f86
+P e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47
+R 1585578003f3d07014cf9b3e3edcfb74
 U drh
-Z 77e80e656a1a39cdd643ee53416f4c84
+Z e0df7c75ae1c0bc5ef9879b2922e6098
index 371a0e4cdf0d4e17ef3f7a368b5b9480c9959728..87a0fdbb5c045dc851e4f468480648f5ec89e67e 100644 (file)
@@ -1 +1 @@
-e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47
\ No newline at end of file
+1c508a99822caa383e7e24b5d09a9bddd2ee3a00
\ No newline at end of file
index 4e27676cb47d3c8cfd26d35e64454cdb8fe39809..edfde11e932c7b8fffa8ebf8c85e732d88ebec90 100644 (file)
@@ -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;
index 5a61ea5b49055fdd02deae66f2a55e518d4dcae2..66a22ded16316812ae5f35fac54a5dcdd6c26ce8 100644 (file)
@@ -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_
 # define TESTONLY(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
+
 /*
 ** The ALWAYS and NEVER macros surround boolean expressions which 
 ** are intended to always be true or false, respectively.  Such
 # 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"
index a5312fc834e4b0d48cf60a2d5a1f961ee8235f8d..be6cd4fffa0caef23af23d8ad75c221d66c3bfda 100644 (file)
@@ -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);
index 8d16b875c955288d25b7644760f1c819d5c87b7d..4bf8426724a297fea1b4df4a3498969c780d0b25 100644 (file)
@@ -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;
     }
index 15c3e73650b504472cf58c4dfc7d1cb613fb6839..6b81c363ffb8cfd6bc0d782d80e33f034736dd4b 100644 (file)
@@ -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);