]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When using an index to scan a database table, read column data from the index in...
authordanielk1977 <danielk1977@noemail.net>
Thu, 29 Nov 2007 17:43:27 +0000 (17:43 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Thu, 29 Nov 2007 17:43:27 +0000 (17:43 +0000)
FossilOrigin-Name: 061608c72ac0a96eacf3b64d638235e4739f96ba

manifest
manifest.uuid
src/where.c
test/intpkey.test
test/where.test

index 6b48852469934207aadf237e66902e3cbfdb31f2..951efb8f45efc98a00a252e5b04390c4440cce73 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Optimisations\sfor\sexpressions\sof\sthe\sform\s"<value>\sIN\s(SELECT\s<column>\sFROM\s<table>)".\s(CVS\s4579)
-D 2007-11-29T17:05:18
+C When\susing\san\sindex\sto\sscan\sa\sdatabase\stable,\sread\scolumn\sdata\sfrom\sthe\sindex\sin\spreference\sto\sthe\stable.\sThis\sincreases\sthe\slikelihood\sthat\sthe\stable\swill\snot\sbe\srequired\sat\sall.\s(CVS\s4580)
+D 2007-11-29T17:43:28
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 35396fd58890420b29edcf27b6c0e2d054862a6b
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -176,7 +176,7 @@ F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
 F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
 F src/vtab.c f819d55ef638d45e09ce00009d435da8bf16f528
-F src/where.c a03cd9da865f9ae9d750b01b45ad0bd82bd456f1
+F src/where.c 7ec7c7a5b3a534d5ccbe9d73690b8969ee6b3f08
 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba
@@ -336,7 +336,7 @@ F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677
 F test/insert4.test 6919ddacd79c2cfeb9785b0f84217f9cb14853b5
 F test/insert5.test e8d5ba31283db5b0315ada9774dd99b6e9fe2122
 F test/interrupt.test 81555fb0f8179bb2d0dc7151fd75428223f93cf2
-F test/intpkey.test af4fd826c4784ec5c93b444de07adea0254d0d30
+F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
 F test/io.test 80a7a7f1a2792e037d447b03e8c22ee1f6eaf339
 F test/ioerr.test ae429185a3a11a318aa7ec64e2188e6119e43bca
 F test/ioerr2.test e3d52c40f43f9b61da9b38951a737e7b84ebae96
@@ -509,7 +509,7 @@ F test/vtabA.test 9cb6b1afead6fdd91bbdf1ca65c44ccfd9b10936
 F test/vtab_alter.test b0c0f61a9588b509c2ba20dedc2db04999da6656
 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
 F test/vtab_shared.test d631d1f820c38c18939d53aab1fc35db5f0a8094
-F test/where.test 1bcde8984c63747ac6d6bafcacd20fd6e8a223de
+F test/where.test 5ff4a1bda6352b73354faf1a97706bbfa0d47dfe
 F test/where2.test 9bbf1cc675730954047d663e4c0dc5d4c9669ca4
 F test/where3.test 0a30fe9808b0fa01c46d0fcf4fac0bf6cf75bb30
 F test/where4.test 1b1cd72d5f205ce34d5a31f3c4918f833e5e6a63
@@ -594,7 +594,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 221aee72be040769e8026b91648f03c6366a8821
-R 17bc1550023a2d1b2bcf36adaf1ceda3
+P 56d0e32677744df8570b519fae1c04da4ea4984d
+R 36e691e0ba7fd3d68c366765c689ffb2
 U danielk1977
-Z 90a3ecb3d9566cd903183cf31905697c
+Z 64a9f02b9181db1b1e3b35c33464441d
index 9c13383ea243b738d379437c520a710dc46b21eb..6cdf0ba1b7d314c71460ca991ffbf7c8ae630484 100644 (file)
@@ -1 +1 @@
-56d0e32677744df8570b519fae1c04da4ea4984d
\ No newline at end of file
+061608c72ac0a96eacf3b64d638235e4739f96ba
\ No newline at end of file
index 853af403ff4baf9bd53eea0d7352b2b64c0fedd7..2e39b0313745a08f4e8a20331a149e655f0f022b 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.264 2007/11/29 17:05:18 danielk1977 Exp $
+** $Id: where.c,v 1.265 2007/11/29 17:43:28 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -2215,10 +2215,6 @@ WhereInfo *sqlite3WhereBegin(
       VdbeComment((v, "# %s", pIx->zName));
       sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
                      (char*)pKey, P3_KEYINFO_HANDOFF);
-    }
-    if( (pLevel->flags & (WHERE_IDX_ONLY|WHERE_COLUMN_RANGE))!=0 ){
-      /* Only call OP_SetNumColumns on the index if we might later use
-      ** OP_Column on the index. */
       sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
     }
     sqlite3CodeVerifySchema(pParse, iDb);
@@ -2742,8 +2738,12 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
       sqlite3VdbeAddOp(v, OP_Close, pLevel->iIdxCur, 0);
     }
 
-    /* Make cursor substitutions for cases where we want to use
-    ** just the index and never reference the table.
+    /* If this scan uses an index, make code substitutions to read data
+    ** from the index in preference to the table. Sometimes, this means
+    ** the table need never be read from. This is a performance boost,
+    ** as the vdbe level waits until the table is read before actually
+    ** seeking the table cursor to the record corresponding to the current
+    ** position in the index.
     ** 
     ** Calls to the code generator in between sqlite3WhereBegin and
     ** sqlite3WhereEnd will have created code that references the table
@@ -2751,10 +2751,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
     ** that reference the table and converts them into opcodes that
     ** reference the index.
     */
-    if( pLevel->flags & WHERE_IDX_ONLY ){
+    if( pLevel->pIdx ){
       int k, j, last;
       VdbeOp *pOp;
       Index *pIdx = pLevel->pIdx;
+      int useIndexOnly = pLevel->flags & WHERE_IDX_ONLY;
 
       assert( pIdx!=0 );
       pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
@@ -2762,17 +2763,18 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
       for(k=pWInfo->iTop; k<last; k++, pOp++){
         if( pOp->p1!=pLevel->iTabCur ) continue;
         if( pOp->opcode==OP_Column ){
-          pOp->p1 = pLevel->iIdxCur;
           for(j=0; j<pIdx->nColumn; j++){
             if( pOp->p2==pIdx->aiColumn[j] ){
               pOp->p2 = j;
+              pOp->p1 = pLevel->iIdxCur;
               break;
             }
           }
+          assert(!useIndexOnly || j<pIdx->nColumn);
         }else if( pOp->opcode==OP_Rowid ){
           pOp->p1 = pLevel->iIdxCur;
           pOp->opcode = OP_IdxRowid;
-        }else if( pOp->opcode==OP_NullRow ){
+        }else if( pOp->opcode==OP_NullRow && useIndexOnly ){
           pOp->opcode = OP_Noop;
         }
       }
index 168f1df5c5517d0f473180984b7200042eb41ba5..05b6cdf04ca9be22a594a65a0884f9b51fa1dce4 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for the special processing associated
 # with INTEGER PRIMARY KEY columns.
 #
-# $Id: intpkey.test,v 1.23 2005/07/21 03:48:20 drh Exp $
+# $Id: intpkey.test,v 1.24 2007/11/29 17:43:28 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -293,7 +293,7 @@ do_test intpkey-3.8 {
   count {
     SELECT * FROM t1 WHERE c=='world' AND a>7;
   }
-} {11 hello world 5}
+} {11 hello world 4}
 do_test intpkey-3.9 {
   count {
     SELECT * FROM t1 WHERE 7<a;
index b69e0063dea947816d8bcf2f02961a61f17056d7..56a36fdae2bebb99731f8d70aeff0a236a5591a4 100644 (file)
@@ -1,4 +1,4 @@
-# 2001 September 15
+# 2001 September 15
 #
 # The author disclaims copyright to this source code.  In place of
 # a legal notice, here is a blessing:
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the use of indices in WHERE clases.
 #
-# $Id: where.test,v 1.43 2007/06/25 16:29:34 danielk1977 Exp $
+# $Id: where.test,v 1.44 2007/11/29 17:43:28 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -184,7 +184,7 @@ do_test where-1.25 {
 
 do_test where-1.27 {
   count {SELECT w FROM t1 WHERE x=3 AND y+1==122}
-} {10 17}
+} {10 10}
 
 do_test where-1.28 {
   count {SELECT w FROM t1 WHERE x+1=4 AND y+1==122}
@@ -358,7 +358,7 @@ ifcapable subquery {
     count {
       SELECT * FROM t1 WHERE rowid+0 IN (1,2,3,1234) order by 1;
     }
-  } {1 0 4 2 1 9 3 1 16 199}
+  } {1 0 4 2 1 9 3 1 16 102}
   do_test where-5.3 {
     count {
       SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
@@ -368,7 +368,7 @@ ifcapable subquery {
     count {
       SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
     }
-  } {1 0 4 2 1 9 3 1 16 199}
+  } {1 0 4 2 1 9 3 1 16 102}
   do_test where-5.5 {
     count {
       SELECT * FROM t1 WHERE rowid IN 
@@ -382,7 +382,7 @@ ifcapable subquery {
          (select rowid from t1 where rowid IN (-1,2,4))
       ORDER BY 1;
     }
-  } {2 1 9 4 2 25 201}
+  } {2 1 9 4 2 25 103}
   do_test where-5.7 {
     count {
       SELECT * FROM t1 WHERE w IN 
@@ -396,7 +396,7 @@ ifcapable subquery {
          (select rowid from t1 where rowid IN (-1,2,4))
       ORDER BY 1;
     }
-  } {2 1 9 4 2 25 201}
+  } {2 1 9 4 2 25 103}
   do_test where-5.9 {
     count {
       SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1;