1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Bug fixes in where.c. The where.test test works again. (CVS 1406)

FossilOrigin-Name: 7c31e257e2d109bfedf63dc307b422e1abd46d0e
This commit is contained in:
drh
2004-05-19 13:13:08 +00:00
parent 09e490ce3c
commit 772ae62a82
6 changed files with 75 additions and 42 deletions

View File

@@ -1,5 +1,5 @@
C Really\sremove\sthe\sOP_StrEq\sopcode\sthis\stime\s-\sappearently\sI\sdidn't\ssave\sthe\nfile\sout\sof\sthe\seditor\sbefore\sdoing\sthe\scheck-in\s(1397).\s(CVS\s1405) C Bug\sfixes\sin\swhere.c.\s\sThe\swhere.test\stest\sworks\sagain.\s(CVS\s1406)
D 2004-05-19T11:31:13 D 2004-05-19T13:13:08
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -63,11 +63,11 @@ F src/update.c 0cc7291dd0e0f82cf93085e49c973e8ef9e51fd5
F src/utf.c 48c537bf7990ce32a36b051401874d024ec2a07b F src/utf.c 48c537bf7990ce32a36b051401874d024ec2a07b
F src/util.c b72f775a6c3fa404d70250382f63d708e17bc332 F src/util.c b72f775a6c3fa404d70250382f63d708e17bc332
F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476 F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476
F src/vdbe.c 415b3b195e71c7771f9ea9303ee45427e0295c2c F src/vdbe.c b64632880456575000b369f11ffe118965184dce
F src/vdbe.h 314e9c07db73a42a6ba91ab7539e27652fc88870 F src/vdbe.h 314e9c07db73a42a6ba91ab7539e27652fc88870
F src/vdbeInt.h 3f76e27be527f4848dc2aae898f2d8709eb1b32c F src/vdbeInt.h 3f76e27be527f4848dc2aae898f2d8709eb1b32c
F src/vdbeaux.c 5743e15988d1cbe2db055c1cb6faaa062c1ec601 F src/vdbeaux.c 5743e15988d1cbe2db055c1cb6faaa062c1ec601
F src/where.c 5f480219a943b0fed1f6922d2fdbfba8616a9148 F src/where.c 67bbdef0ce7fcd661cbf02f3fd91ff8cdb7a4a44
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
F test/attach2.test 7c388dee63a4c1997695c3d41957f32ce784ac56 F test/attach2.test 7c388dee63a4c1997695c3d41957f32ce784ac56
@@ -120,7 +120,7 @@ F test/pager2.test 7ff175a28484fd324df9315dfe35f6fb159910ec
F test/pragma.test 06c4e51998dd68115ef7a60abeeff7accf198f83 F test/pragma.test 06c4e51998dd68115ef7a60abeeff7accf198f83
F test/printf.test 46b3d07d59d871d0831b4a657f6dfcafe0574850 F test/printf.test 46b3d07d59d871d0831b4a657f6dfcafe0574850
F test/progress.test 701b6115c2613128ececdfe1398a1bd0e1a4cfb3 x F test/progress.test 701b6115c2613128ececdfe1398a1bd0e1a4cfb3 x
F test/quick.test 602cada4404580550bca5a7d233954e3da63a442 F test/quick.test 86f868f184dca1420304a32de650de40939a04d1
F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
F test/rowid.test 863e6e75878cccf03d166fe52023f20e09508683 F test/rowid.test 863e6e75878cccf03d166fe52023f20e09508683
F test/select1.test 3bfcccd2eadcddbb07f1f5da6550aee8484ea4fb F test/select1.test 3bfcccd2eadcddbb07f1f5da6550aee8484ea4fb
@@ -152,7 +152,7 @@ F test/vacuum.test a2a44544df719666efb51afbfeb6062fd59a672a
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/version.test 2ba212ba06380e65e476bdf2fcd390e8b05af5a0 F test/version.test 2ba212ba06380e65e476bdf2fcd390e8b05af5a0
F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53 F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53
F test/where.test cb3a2ed062ce4b5f08aff2d08027c6a46d68c47b F test/where.test 45a816fc3b055a8306a1482f98b7c0b2cf14581b
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/lemon.c f4fb7226c930435e994441a470ed60a7c540f518 F tool/lemon.c f4fb7226c930435e994441a470ed60a7c540f518
F tool/lempar.c 0b5e7a58634e0d448929b8e85f7981c2aa708d57 F tool/lempar.c 0b5e7a58634e0d448929b8e85f7981c2aa708d57
@@ -193,7 +193,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P 45169ce015da07da9a874b5b075ea6a05f59f162 P 821b0b297c11a5e8d08d73b5eff810652e5a0d27
R 1e0fe3ea2cd4710538f26552e9f58e44 R c82e653b769eb6c799477d31b330ecb3
U drh U drh
Z b0b27c4a71b1d00c6f553d0425414f30 Z 82230e305545f87ef38ec9ab9f82ee14

View File

@@ -1 +1 @@
821b0b297c11a5e8d08d73b5eff810652e5a0d27 7c31e257e2d109bfedf63dc307b422e1abd46d0e

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing ** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code. ** commenting and indentation practices when changing or adding code.
** **
** $Id: vdbe.c,v 1.302 2004/05/19 11:31:13 drh Exp $ ** $Id: vdbe.c,v 1.303 2004/05/19 13:13:08 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -2766,10 +2766,12 @@ case OP_Close: {
** If there are no records greater than the key and P2 is not zero, ** If there are no records greater than the key and P2 is not zero,
** then an immediate jump to P2 is made. ** then an immediate jump to P2 is made.
** **
** If P3 is not NULL, then the cursor is left pointing at the first ** If P3 is the "+" string (or any other non-NULL string) then the
** record that is greater than the key of which the key is not a prefix. ** index taken from the top of the stack is temporarily increased by
** This is the same effect that executing OP_IncrKey on the key value ** an epsilon prior to the move. This causes the P1 cursor to move
** before OP_MoveTo used to have. ** to the first entry which is greater than the index on the top of
** the stack rather than the first entry that is equal to the top of
** the stack.
** **
** See also: Found, NotFound, Distinct, MoveLt ** See also: Found, NotFound, Distinct, MoveLt
*/ */
@@ -2781,10 +2783,12 @@ case OP_Close: {
** If there are no records less than than the key and P2 ** If there are no records less than than the key and P2
** is not zero then an immediate jump to P2 is made. ** is not zero then an immediate jump to P2 is made.
** **
** If P3 is not NULL, and keys exist in the index of which the stack key ** If P3 is the "+" string (or any other non-NULL string) then the
** is a prefix, leave the cursor pointing at the largest of these. ** index taken from the top of the stack is temporarily increased by
** This is the same effect that executing OP_IncrKey on the key value ** an epsilon prior to the move. This causes the P1 cursor to move
** before OP_MoveLt used to have. ** to the smallest entry that is greater than or equal to the top of
** the stack rather than the largest entry that is less than the top
** of the stack.
** **
** See also: MoveTo ** See also: MoveTo
*/ */
@@ -3798,30 +3802,42 @@ case OP_IdxRecno: {
break; break;
} }
/* Opcode: IdxGT P1 P2 * /* Opcode: IdxGT P1 P2 P3
** **
** Compare the top of the stack against the key on the index entry that ** Compare the top of the stack against the key on the index entry that
** cursor P1 is currently pointing to. Ignore the last 4 bytes of the ** cursor P1 is currently pointing to. Ignore the ROWID of the
** index entry. If the index entry is greater than the top of the stack ** index entry. If the index entry is greater than the top of the stack
** then jump to P2. Otherwise fall through to the next instruction. ** then jump to P2. Otherwise fall through to the next instruction.
** In either case, the stack is popped once. ** In either case, the stack is popped once.
**
** If P3 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.
*/ */
/* Opcode: IdxGE P1 P2 * /* Opcode: IdxGE P1 P2 *
** **
** Compare the top of the stack against the key on the index entry that ** Compare the top of the stack against the key on the index entry that
** cursor P1 is currently pointing to. Ignore the last 4 bytes of the ** cursor P1 is currently pointing to. Ignore the ROWID of the
** index entry. If the index entry is greater than or equal to ** index entry. If the index entry is greater than or equal to
** the top of the stack ** the top of the stack
** then jump to P2. Otherwise fall through to the next instruction. ** then jump to P2. Otherwise fall through to the next instruction.
** In either case, the stack is popped once. ** In either case, the stack is popped once.
**
** If P3 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.
*/ */
/* Opcode: IdxLT P1 P2 * /* Opcode: IdxLT P1 P2 *
** **
** Compare the top of the stack against the key on the index entry that ** Compare the top of the stack against the key on the index entry that
** cursor P1 is currently pointing to. Ignore the last 4 bytes of the ** cursor P1 is currently pointing to. Ignore the ROWID of the
** index entry. If the index entry is less than the top of the stack ** index entry. If the index entry is less than the top of the stack
** then jump to P2. Otherwise fall through to the next instruction. ** then jump to P2. Otherwise fall through to the next instruction.
** In either case, the stack is popped once. ** In either case, the stack is popped once.
**
** If P3 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.
*/ */
case OP_IdxLT: case OP_IdxLT:
case OP_IdxGT: case OP_IdxGT:
@@ -5092,7 +5108,7 @@ default: {
for(j=0; j<20 && j<pTos[i].n; j++){ for(j=0; j<20 && j<pTos[i].n; j++){
int c = pTos[i].z[j]; int c = pTos[i].z[j];
if( c==0 && j==pTos[i].n-1 ) break; if( c==0 && j==pTos[i].n-1 ) break;
if( isprint(c) && !isspace(c) ){ if( c>=0x20 && c<0x7f ){
zBuf[k++] = c; zBuf[k++] = c;
}else{ }else{
zBuf[k++] = '.'; zBuf[k++] = '.';

View File

@@ -12,7 +12,7 @@
** This module contains C code that generates VDBE code used to process ** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements. ** the WHERE clause of SQL statements.
** **
** $Id: where.c,v 1.96 2004/05/18 01:23:39 danielk1977 Exp $ ** $Id: where.c,v 1.97 2004/05/19 13:13:08 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -684,7 +684,7 @@ WhereInfo *sqlite3WhereBegin(
sqlite3CodeVerifySchema(pParse, pTab->iDb); sqlite3CodeVerifySchema(pParse, pTab->iDb);
if( (pIx = pWInfo->a[i].pIdx)!=0 ){ if( (pIx = pWInfo->a[i].pIdx)!=0 ){
sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0); sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
sqlite3VdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0); sqlite3VdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum,pIx->zName,0);
} }
} }
@@ -749,6 +749,10 @@ WhereInfo *sqlite3WhereBegin(
int testOp; int testOp;
int nColumn = (pLevel->score+4)/8; int nColumn = (pLevel->score+4)/8;
brk = pLevel->brk = sqlite3VdbeMakeLabel(v); brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
/* For each column of the index, find the term of the WHERE clause that
** constraints that column. If the WHERE clause term is X=expr, then
** evaluation expr and leave the result on the stack */
for(j=0; j<nColumn; j++){ for(j=0; j<nColumn; j++){
for(k=0; k<nExpr; k++){ for(k=0; k<nExpr; k++){
Expr *pX = aExpr[k].p; Expr *pX = aExpr[k].p;
@@ -791,17 +795,34 @@ WhereInfo *sqlite3WhereBegin(
} }
pLevel->iMem = pParse->nMem++; pLevel->iMem = pParse->nMem++;
cont = pLevel->cont = sqlite3VdbeMakeLabel(v); cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
/* At this point, the top nColumn elements of the stack are the
** values of columns in the index we are using. Check to see if
** any of these values are NULL. If they are, they will not match any
** index entries, so skip immediately to the next iteration of the loop */
sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
sqlite3VdbeAddOp(v, OP_Goto, 0, brk); sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
/* Generate an index key from the top nColumn elements of the stack */
sqlite3VdbeAddOp(v, OP_MakeKey, nColumn, 0); sqlite3VdbeAddOp(v, OP_MakeKey, nColumn, 0);
sqlite3IndexAffinityStr(v, pIdx); sqlite3IndexAffinityStr(v, pIdx);
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
/* Choose a testOp that will determine when we have moved past the
** last element of the table that matches the index key we just
** created */
if( nColumn==pIdx->nColumn || pLevel->bRev ){ if( nColumn==pIdx->nColumn || pLevel->bRev ){
testOp = OP_IdxGT; testOp = OP_IdxGT;
}else{ }else{
testOp = OP_IdxGE; testOp = OP_IdxGE;
} }
/* Generate code (1) to move to the first matching element of the table.
** Then generate code (2) that jumps to "brk" after the cursor is past
** the last matching element of the table. The code (1) is executed
** once to initialize the search, the code (2) is executed before each
** iteration of the scan to see if the scan has finished. */
if( pLevel->bRev ){ if( pLevel->bRev ){
/* Scan in reverse order */ /* Scan in reverse order */
sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk); sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
@@ -1003,7 +1024,7 @@ WhereInfo *sqlite3WhereBegin(
sqlite3IndexAffinityStr(v, pIdx); sqlite3IndexAffinityStr(v, pIdx);
if( pLevel->bRev ){ if( pLevel->bRev ){
sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk); sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
if( !geFlag ){ if( leFlag ){
sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC); sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
} }
}else{ }else{
@@ -1202,6 +1223,3 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqliteFree(pWInfo); sqliteFree(pWInfo);
return; return;
} }

View File

@@ -10,7 +10,7 @@
#*********************************************************************** #***********************************************************************
# This file runs all tests. # This file runs all tests.
# #
# $Id: quick.test,v 1.12 2004/05/18 10:06:26 danielk1977 Exp $ # $Id: quick.test,v 1.13 2004/05/19 13:13:08 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -45,7 +45,6 @@ lappend EXCLUDE version.test ;# uses the btree_meta API (not updated)
# implementation. # implementation.
lappend EXCLUDE misc1.test lappend EXCLUDE misc1.test
lappend EXCLUDE capi2.test lappend EXCLUDE capi2.test
lappend EXCLUDE where.test
if {[sqlite -has-codec]} { if {[sqlite -has-codec]} {

View File

@@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this file is testing the use of indices in WHERE clases. # focus of this file is testing the use of indices in WHERE clases.
# #
# $Id: where.test,v 1.17 2003/06/15 23:42:25 drh Exp $ # $Id: where.test,v 1.18 2004/05/19 13:13:08 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -280,7 +280,7 @@ do_test where-5.1 {
count { count {
SELECT * FROM t1 WHERE rowid IN (1,2,3,1234) order by 1; SELECT * FROM t1 WHERE rowid IN (1,2,3,1234) order by 1;
} }
} {1 0 4 2 1 9 3 1 16 0} } {1 0 4 2 1 9 3 1 16 3}
do_test where-5.2 { do_test where-5.2 {
count { count {
SELECT * FROM t1 WHERE rowid+0 IN (1,2,3,1234) order by 1; SELECT * FROM t1 WHERE rowid+0 IN (1,2,3,1234) order by 1;
@@ -290,7 +290,7 @@ do_test where-5.3 {
count { count {
SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1; SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
} }
} {1 0 4 2 1 9 3 1 16 10} } {1 0 4 2 1 9 3 1 16 13}
do_test where-5.4 { do_test where-5.4 {
count { count {
SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1; SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
@@ -302,33 +302,33 @@ do_test where-5.5 {
(select rowid from t1 where rowid IN (-1,2,4)) (select rowid from t1 where rowid IN (-1,2,4))
ORDER BY 1; ORDER BY 1;
} }
} {2 1 9 4 2 25 1} } {2 1 9 4 2 25 3}
do_test where-5.6 { do_test where-5.6 {
count { count {
SELECT * FROM t1 WHERE rowid+0 IN SELECT * FROM t1 WHERE rowid+0 IN
(select rowid from t1 where rowid IN (-1,2,4)) (select rowid from t1 where rowid IN (-1,2,4))
ORDER BY 1; ORDER BY 1;
} }
} {2 1 9 4 2 25 199} } {2 1 9 4 2 25 201}
do_test where-5.7 { do_test where-5.7 {
count { count {
SELECT * FROM t1 WHERE w IN SELECT * FROM t1 WHERE w IN
(select rowid from t1 where rowid IN (-1,2,4)) (select rowid from t1 where rowid IN (-1,2,4))
ORDER BY 1; ORDER BY 1;
} }
} {2 1 9 4 2 25 7} } {2 1 9 4 2 25 9}
do_test where-5.8 { do_test where-5.8 {
count { count {
SELECT * FROM t1 WHERE w+0 IN SELECT * FROM t1 WHERE w+0 IN
(select rowid from t1 where rowid IN (-1,2,4)) (select rowid from t1 where rowid IN (-1,2,4))
ORDER BY 1; ORDER BY 1;
} }
} {2 1 9 4 2 25 199} } {2 1 9 4 2 25 201}
do_test where-5.9 { do_test where-5.9 {
count { count {
SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1; SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1;
} }
} {2 1 9 3 1 16 6} } {2 1 9 3 1 16 7}
do_test where-5.10 { do_test where-5.10 {
count { count {
SELECT * FROM t1 WHERE x+0 IN (1,7) ORDER BY 1; SELECT * FROM t1 WHERE x+0 IN (1,7) ORDER BY 1;
@@ -348,12 +348,12 @@ do_test where-5.13 {
count { count {
SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1; SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1;
} }
} {2 1 9 3 1 16 6} } {2 1 9 3 1 16 7}
do_test where-5.14 { do_test where-5.14 {
count { count {
SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1; SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1;
} }
} {2 1 9 6} } {2 1 9 7}
# This procedure executes the SQL. Then it checks the generated program # This procedure executes the SQL. Then it checks the generated program
# for the SQL and appends a "nosort" to the result if the program contains the # for the SQL and appends a "nosort" to the result if the program contains the