From 1a844c380b83d94c70a735ee8035ce02c21f2df7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Dec 2002 22:29:28 +0000 Subject: [PATCH] Fix a bug in the reverse scan logic that comes up when the table being scanned is empty. Add additional tests for the reverse scan. (CVS 797) FossilOrigin-Name: 0051c87d5e8d07fae09da2eb7b0d8cbd1bbd3c8e --- manifest | 16 ++++---- manifest.uuid | 2 +- src/btree.c | 7 ++-- src/vdbe.c | 16 ++++++-- test/where.test | 101 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 125 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index ea9bcc9913..6c666c9e49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sthe\slogic\sthat\sdecides\sif\sthe\sORDER\sBY\scan\sbe\signored\sdue\sto\sthe\nuse\sof\san\sindex.\s\sTests\supdated.\s(CVS\s796) -D 2002-12-04T21:50:16 +C Fix\sa\sbug\sin\sthe\sreverse\sscan\slogic\sthat\scomes\sup\swhen\sthe\stable\sbeing\nscanned\sis\sempty.\s\sAdd\sadditional\stests\sfor\sthe\sreverse\sscan.\s(CVS\s797) +D 2002-12-04T22:29:28 F Makefile.in 868c17a1ae1c07603d491274cc8f86c04acf2a1e F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -18,7 +18,7 @@ F main.mk 9d13839b9697af332d788fe6e801e68da027cc5c F publish.sh e5b83867d14708ed58cec8cba0a4f201e969474d F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea -F src/btree.c 2ae69698a620c01b9cb88f447be01ab3e1e3355f +F src/btree.c 215d4b322c98fbff795095fa253d9ea108d4b9de F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda F src/build.c 415dce8886aabb6d45851caed7014707056d668b F src/delete.c aad9d4051ab46e6f6391ea5f7b8994a7c05bdd15 @@ -52,7 +52,7 @@ F src/tokenize.c 75e3bb37305b64e118e709752066f494c4f93c30 F src/trigger.c 5ba917fc226b96065108da28186c2efaec53e481 F src/update.c 881e4c8e7c786545da4fd2d95da19252b2e31137 F src/util.c ca7650ef2cc2d50241e48029fca109a3016144ee -F src/vdbe.c 84b224d0ecfb2555a976f074924dd3e6d3d91dfb +F src/vdbe.c aa6165ae4f2303795e4c5531293576c541363e40 F src/vdbe.h b7584044223104ba7896a7f87b66daebdd6022ba F src/where.c af235636b7bc7f7f42ee1c7162d1958ad0102cab F test/all.test 873d30e25a41b3aa48fec5633a7ec1816e107029 @@ -115,7 +115,7 @@ F test/update.test 7ffb062d580a972e7870d0f51d5af3ab9bfeae08 F test/vacuum.test 059871b312eb910bbe49dafde1d01490cc2c6bbe F test/version.test 605fd0d7e7d571370c32b12dbf395b58953de246 F test/view.test c64fa39ea57f3c2066c854290f032ad13b23b83d -F test/where.test 9e6e7e0a8bc6eff879bf12a497d6529df7fa9852 +F test/where.test ffaa91611edb8961d887d02492aa13f82782ff66 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/lemon.c 022adc2830c2705828f744d2c59798bd462eb465 F tool/lempar.c 73a991cc3017fb34804250fa901488b5147b3717 @@ -152,7 +152,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P c7a3487981de0ed5b43ea3ff4d46ab4437068dca -R ad809775145f9a28c47c1aa04b1e5814 +P bfb9a2aa939ecffc5dc2c7c23bddd57d357bdf13 +R e8e5bb54da6e21aac3b570ab92f52726 U drh -Z 2d97197b4281b66cabb81cf1fc140ed8 +Z ef156328459f096ede699892581cbeef diff --git a/manifest.uuid b/manifest.uuid index f25a3cbbb1..1723f4a045 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfb9a2aa939ecffc5dc2c7c23bddd57d357bdf13 \ No newline at end of file +0051c87d5e8d07fae09da2eb7b0d8cbd1bbd3c8e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 6554584c76..193c224d66 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.74 2002/12/04 13:40:26 drh Exp $ +** $Id: btree.c,v 1.75 2002/12/04 22:29:28 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -1495,7 +1495,8 @@ int sqliteBtreeLast(BtCursor *pCur, int *pRes){ ** this value is as follows: ** ** *pRes<0 The cursor is left pointing at an entry that -** is smaller than pKey. +** is smaller than pKey or if the table is empty +** and the cursor is therefore left point to nothing. ** ** *pRes==0 The cursor is left pointing at an entry that ** exactly matches pKey. @@ -1513,7 +1514,7 @@ int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){ int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->pPage; - int c = -1; + int c = -1; /* pRes return if table is empty must be -1 */ lwr = 0; upr = pPage->nCell-1; while( lwr<=upr ){ diff --git a/src/vdbe.c b/src/vdbe.c index 93b4ee9342..58a5374767 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -36,7 +36,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.186 2002/12/04 20:01:06 drh Exp $ +** $Id: vdbe.c,v 1.187 2002/12/04 22:29:29 drh Exp $ */ #include "sqliteInt.h" #include @@ -3394,9 +3394,17 @@ case OP_MoveTo: { if( res && pOp->p2>0 ){ pc = pOp->p2 - 1; } - }else if( oc==OP_MoveLt && res>=0 ){ - sqliteBtreePrevious(pC->pCursor, &res); - pC->recnoIsValid = 0; + }else if( oc==OP_MoveLt ){ + if( res>=0 ){ + sqliteBtreePrevious(pC->pCursor, &res); + pC->recnoIsValid = 0; + }else{ + /* res might be negative because the table is empty. Check to + ** see if this is the case. + */ + int keysize; + res = sqliteBtreeKeySize(pC->pCursor,&keysize)!=0 || keysize==0; + } if( res && pOp->p2>0 ){ pc = pOp->p2 - 1; } diff --git a/test/where.test b/test/where.test index 7a9f2d47db..32bd0d139b 100644 --- a/test/where.test +++ b/test/where.test @@ -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.12 2002/12/04 21:50:16 drh Exp $ +# $Id: where.test,v 1.13 2002/12/04 22:29:29 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -588,5 +588,104 @@ do_test where-7.14 { SELECT w FROM t1 WHERE x=3 AND y>100 AND y<196 ORDER BY y; } } {10 11 12 nosort} +do_test where-7.15 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y<81 ORDER BY y; + } +} {nosort} +do_test where-7.16 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y<=81 ORDER BY y; + } +} {8 nosort} +do_test where-7.17 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y>256 ORDER BY y; + } +} {nosort} +do_test where-7.18 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y>=256 ORDER BY y; + } +} {15 nosort} +do_test where-7.19 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y<81 ORDER BY y DESC; + } +} {nosort} +do_test where-7.20 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y<=81 ORDER BY y DESC; + } +} {8 nosort} +do_test where-7.21 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y>256 ORDER BY y DESC; + } +} {nosort} +do_test where-7.22 { + cksort { + SELECT w FROM t1 WHERE x=3 AND y>=256 ORDER BY y DESC; + } +} {15 nosort} +do_test where-7.23 { + cksort { + SELECT w FROM t1 WHERE x=0 AND y<4 ORDER BY y; + } +} {nosort} +do_test where-7.24 { + cksort { + SELECT w FROM t1 WHERE x=0 AND y<=4 ORDER BY y; + } +} {1 nosort} +do_test where-7.25 { + cksort { + SELECT w FROM t1 WHERE x=6 AND y>10201 ORDER BY y; + } +} {nosort} +do_test where-7.26 { + cksort { + SELECT w FROM t1 WHERE x=6 AND y>=10201 ORDER BY y; + } +} {100 nosort} +do_test where-7.27 { + cksort { + SELECT w FROM t1 WHERE x=0 AND y<4 ORDER BY y DESC; + } +} {nosort} +do_test where-7.28 { + cksort { + SELECT w FROM t1 WHERE x=0 AND y<=4 ORDER BY y DESC; + } +} {1 nosort} +do_test where-7.29 { + cksort { + SELECT w FROM t1 WHERE x=6 AND y>10201 ORDER BY y DESC; + } +} {nosort} +do_test where-7.30 { + cksort { + SELECT w FROM t1 WHERE x=6 AND y>=10201 ORDER BY y DESC; + } +} {100 nosort} + +do_test where-8.1 { + execsql { + CREATE TABLE t4 AS SELECT * FROM t1; + CREATE INDEX i4xy ON t4(x,y); + } + cksort { + SELECT w FROM t4 WHERE x=4 and y<1000 ORDER BY y DESC limit 3; + } +} {30 29 28 nosort} +do_test where-8.2 { + execsql { + DELETE FROM t4; + } + cksort { + SELECT w FROM t4 WHERE x=4 and y<1000 ORDER BY y DESC limit 3; + } +} {nosort} + finish_test