]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Changes directed toward optimizing IS NULL terms in WHERE clauses. (CVS 3492)
authordrh <drh@noemail.net>
Fri, 27 Oct 2006 14:06:57 +0000 (14:06 +0000)
committerdrh <drh@noemail.net>
Fri, 27 Oct 2006 14:06:57 +0000 (14:06 +0000)
FossilOrigin-Name: 4d336e9ef5f65b95959e7d01cd0357d46e9b1fa5

manifest
manifest.uuid
src/vdbe.c
src/vdbeaux.c
src/where.c

index 5535fbce0257e969668f26040e7b950cb4f00b31..74832707f29089cd6fdf1e3a42eb7f0ef56517ce 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Bring\sCVS\soutput\sinto\smore\scommonly\saccepted\spractice.\s\sTickets\s#2030,\s#1573.\nAdd\scommand-line\soptions\s-bail\sand\s".bail"\scommands.\s\sDefault\sbehavior\sis\nto\scontinue\safter\sencountering\san\serror.\s\sTicket\s#2045.\s(CVS\s3491)
-D 2006-10-26T18:15:42
+C Changes\sdirected\stoward\soptimizing\sIS\sNULL\sterms\sin\sWHERE\sclauses.\s(CVS\s3492)
+D 2006-10-27T14:06:58
 F Makefile.in 4379c909d46b38b8c5db3533084601621d4f14b2
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -121,15 +121,15 @@ F src/update.c 951f95ef044cf6d28557c48dc35cb0711a0b9129
 F src/utf.c 67ecb1032bc0b42c105e88d65ef9d9f626eb0e1f
 F src/util.c 91d4cb189476906639ae611927d939691d1365f6
 F src/vacuum.c f6a7943f1f1002cb82ef2ea026cb1975a5b687cb
-F src/vdbe.c 84a9c0b0dd037c064ffed651977e20dd9d2bc1d1
+F src/vdbe.c 1d64351d52e06d55788ad342e1caf6d6a89901fe
 F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
 F src/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b
 F src/vdbeapi.c f1858a5edc3a5e32d038514dd9e7e9091400a782
-F src/vdbeaux.c 6fcc47988bdd563755193c922695032f9d5e5e2b
+F src/vdbeaux.c 78c744f127df03ea63098ebb7dd7fe3eb303e284
 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
 F src/vdbemem.c 26623176bf1c616aa478da958fac49502491a921
 F src/vtab.c aa30e940058ea56a1b7a9a7019ec21d307316fb4
-F src/where.c 49a0e7cc1cd4b80b7070a86bbee78db8409e762d
+F src/where.c 65a19a70c94ba78eb201d84084e8e127fbc40331
 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/all.test 5df90d015ca63fcef2a4b62c24f7316b66c4bfd4
@@ -419,7 +419,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 3baa04cfb91039e27f642f6f78ef761b5770cb08
-R 5125f3c39d1102ce299e6d679578cc74
+P 517712d6fbc5ba5299942a54852298030f4d3381
+R 2570cb898b2d843f2301500c34c71dda
 U drh
-Z e8dda10bb6ff8231cd4d006a2fdac63a
+Z 06856299b267f8815d78835b6fe3e33f
index 7176466aac70cb97c60f6684875d06ab8d7b9a2c..e4c5adf84c96694e201bf8a4321fa0573b84cfcc 100644 (file)
@@ -1 +1 @@
-517712d6fbc5ba5299942a54852298030f4d3381
\ No newline at end of file
+4d336e9ef5f65b95959e7d01cd0357d46e9b1fa5
\ No newline at end of file
index 5b1b9798e9314effdb491fc4a2d622533e41363f..a02d2eddb143ef3231587161528925e62d3dbda7 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.577 2006/09/23 20:36:02 drh Exp $
+** $Id: vdbe.c,v 1.578 2006/10/27 14:06:58 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -1812,32 +1812,31 @@ case OP_IfNot: {            /* no-push */
 
 /* Opcode: IsNull P1 P2 *
 **
-** If any of the top abs(P1) values on the stack are NULL, then jump
-** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
-** unchanged.
+** Check the top of the stack and jump to P2 if the top of the stack
+** is NULL.  If P1 is positive, then pop P1 elements from the stack
+** regardless of whether or not the jump is taken.  If P1 is negative,
+** pop -P1 elements from the stack only if the jump is taken and leave
+** the stack unchanged if the jump is not taken.
 */
 case OP_IsNull: {            /* same as TK_ISNULL, no-push */
-  int i, cnt;
-  Mem *pTerm;
-  cnt = pOp->p1;
-  if( cnt<0 ) cnt = -cnt;
-  pTerm = &pTos[1-cnt];
-  assert( pTerm>=p->aStack );
-  for(i=0; i<cnt; i++, pTerm++){
-    if( pTerm->flags & MEM_Null ){
-      pc = pOp->p2-1;
-      break;
+  if( pTos->flags & MEM_Null ){
+    pc = pOp->p2-1;
+    if( pOp->p1<0 ){
+      popStack(&pTos, -pOp->p1);
     }
   }
-  if( pOp->p1>0 ) popStack(&pTos, cnt);
+  if( pOp->p1>0 ){
+    popStack(&pTos, pOp->p1);
+  }
   break;
 }
 
 /* Opcode: NotNull P1 P2 *
 **
-** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
-** stack if P1 times if P1 is greater than zero.  If P1 is less than
-** zero then leave the stack unchanged.
+** Jump to P2 if the top abs(P1) values on the stack are all not NULL.  
+** Regardless of whether or not the jump is taken, pop the stack
+** P1 times if P1 is greater than zero.  But if P1 is negative,
+** leave the stack unchanged.
 */
 case OP_NotNull: {            /* same as TK_NOTNULL, no-push */
   int i, cnt;
index 15483f3a852f3aaedac117f5cd5d88a8ce0cd325..f0f3b7097d169d378f29244cdba26d95c876ce74 100644 (file)
@@ -1892,14 +1892,13 @@ int sqlite3VdbeRecordCompare(
     idx2 += GetVarint( aKey2+idx2, serial_type2 );
     if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
 
-    /* Assert that there is enough space left in each key for the blob of
-    ** data to go with the serial type just read. This assert may fail if
-    ** the file is corrupted.  Then read the value from each key into mem1
-    ** and mem2 respectively.
+    /* Extract the values to be compared.
     */
     d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
     d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
 
+    /* Do the comparison
+    */
     rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
     if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
     if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
index 558b82e5a5491dbad431ce97d3ab2fd2fe0b75cb..24d7c63109b63236fe543627b0b60c443eb00a75 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.229 2006/10/18 23:26:39 drh Exp $
+** $Id: where.c,v 1.230 2006/10/27 14:06:59 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -1495,11 +1495,11 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
 **
 */
 static void buildIndexProbe(
-  Vdbe *v, 
-  int nColumn, 
-  int nExtra, 
-  int brk, 
-  Index *pIdx
+  Vdbe *v,        /* Generate code into this VM */
+  int nColumn,    /* The number of columns to check for NULL */
+  int nExtra,     /* Number of extra values beyond nColumn */
+  int brk,        /* Jump to here if no match is possible */
+  Index *pIdx     /* Index that we will be searching */
 ){
   sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
   sqlite3VdbeAddOp(v, OP_Pop, nColumn+nExtra, 0);
@@ -1613,6 +1613,9 @@ static void codeAllEqualityTerms(
     if( pTerm==0 ) break;
     assert( (pTerm->flags & TERM_CODED)==0 );
     codeEqualityTerm(pParse, pTerm, brk, pLevel);
+#if 0  /* WORK IN PROGRESS */
+    sqlite3VdbeAddOp(v, OP_IsNull, termsInMem ? -1 : -(j+1), brk);
+#endif
     if( termsInMem ){
       sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1);
     }