From: drh Date: Fri, 27 Oct 2006 14:06:57 +0000 (+0000) Subject: Changes directed toward optimizing IS NULL terms in WHERE clauses. (CVS 3492) X-Git-Tag: version-3.6.10~2676 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0660e26efe82e92d31c1c9d3dca900fa504826ea;p=thirdparty%2Fsqlite.git Changes directed toward optimizing IS NULL terms in WHERE clauses. (CVS 3492) FossilOrigin-Name: 4d336e9ef5f65b95959e7d01cd0357d46e9b1fa5 --- diff --git a/manifest b/manifest index 5535fbce02..74832707f2 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 7176466aac..e4c5adf84c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -517712d6fbc5ba5299942a54852298030f4d3381 \ No newline at end of file +4d336e9ef5f65b95959e7d01cd0357d46e9b1fa5 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5b1b9798e9..a02d2eddb1 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.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; iflags & 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; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 15483f3a85..f0f3b7097d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -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, iaColl[i] : 0); if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1); if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2); diff --git a/src/where.c b/src/where.c index 558b82e5a5..24d7c63109 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.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); }