From 7cf6e4de35ce301cb9c68fe51314c4cd9469b8aa Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 May 2004 14:56:55 +0000 Subject: [PATCH] Change opcode names and comments to better describe the operation of the incrKey flag. OP_MoveTo becomes OP_MoveGe. (CVS 1407) FossilOrigin-Name: 8f249c45cbc77f4320798ff1a830b55e5c74888a --- manifest | 28 +++++------ manifest.uuid | 2 +- src/delete.c | 8 +--- src/insert.c | 11 ++--- src/select.c | 4 +- src/update.c | 7 +-- src/vdbe.c | 121 ++++++++++++++++++++++++++---------------------- src/vdbeInt.h | 2 +- src/vdbeaux.c | 15 ++++-- src/where.c | 45 +++++++----------- test/where.test | 3 +- 11 files changed, 121 insertions(+), 125 deletions(-) diff --git a/manifest b/manifest index 2371a2cc16..8c1cda16d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bug\sfixes\sin\swhere.c.\s\sThe\swhere.test\stest\sworks\sagain.\s(CVS\s1406) -D 2004-05-19T13:13:08 +C Change\sopcode\snames\sand\scomments\sto\sbetter\sdescribe\sthe\soperation\sof\nthe\sincrKey\sflag.\s\sOP_MoveTo\sbecomes\sOP_MoveGe.\s(CVS\s1407) +D 2004-05-19T14:56:56 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -29,13 +29,13 @@ F src/btree_rb.c 9d7973e266ee6f9c61ce592f68742ce9cd5b10e5 F src/build.c 84a9b37700a18db370b9dbb77f1636df5cdf0290 F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29 F src/date.c 0eb0a89960bb45c7f7e768748605a7a97b0c8064 -F src/delete.c a069dcc2ec0cc3487c8ababebc59a429b4556144 +F src/delete.c 2e1dda38345416a1ea1c0a6468589a7472334dac F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 F src/expr.c de3d86e98d9073399a8173610fb9f02d0e197aea F src/func.c cfbb7096efb58e2857e3b312a8958a12774b625a F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb -F src/insert.c 60cc57b8468749d7e023798b9d7f91eeb4cd279a +F src/insert.c 0ee4c4039fede2b9ab594c4d2db24c9b22e0fbc5 F src/main.c 4b82d7e78f4c9799343b02740a5ba9768d5e464d F src/md5.c 8e39fdae6d8776b87558e91dcc94740c9b635a9c F src/os.c ddcda92f7fd71b4513c57c1ec797917f206d504e @@ -46,7 +46,7 @@ F src/parse.y d2e226650738931c047c2562326ed05882af2330 F src/pragma.c 2332e7fa9d7cd4b21f30583a696bee36628404ca F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 -F src/select.c 2981cafe3b21ca06c97ddec8c7181f209a06ee82 +F src/select.c d01c03462d57b9d1ea25eea297bbd2c1b1c70e47 F src/shell.c 0c4662e13bfbfd3d13b066c5859cc97ad2f95d21 F src/sqlite.h.in 8c62076ea226b1870df977d7438bf99383d02387 F src/sqliteInt.h 1da4a9c26da43f235c45c1de0c49fadf6c40d0e6 @@ -59,15 +59,15 @@ F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296 F src/test5.c c92dca7028b19b9c8319d55e0a5037fc183640a6 F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847 F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f -F src/update.c 0cc7291dd0e0f82cf93085e49c973e8ef9e51fd5 +F src/update.c 1f6687f8d1085f896a24c0fa13d802223ed55539 F src/utf.c 48c537bf7990ce32a36b051401874d024ec2a07b F src/util.c b72f775a6c3fa404d70250382f63d708e17bc332 F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476 -F src/vdbe.c b64632880456575000b369f11ffe118965184dce +F src/vdbe.c 42ecfcd3bf67b9922702cbad2dd87be0bc1cc986 F src/vdbe.h 314e9c07db73a42a6ba91ab7539e27652fc88870 -F src/vdbeInt.h 3f76e27be527f4848dc2aae898f2d8709eb1b32c -F src/vdbeaux.c 5743e15988d1cbe2db055c1cb6faaa062c1ec601 -F src/where.c 67bbdef0ce7fcd661cbf02f3fd91ff8cdb7a4a44 +F src/vdbeInt.h faaa64433d2498f7a6eabccebac854e097b83680 +F src/vdbeaux.c 453e9f6d98fffec8c07ecd99ad9e1bc5b5cf09b1 +F src/where.c e7a7eeb46a81f8ccf84a297db99b3121429769cb F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 F test/attach2.test 7c388dee63a4c1997695c3d41957f32ce784ac56 @@ -152,7 +152,7 @@ F test/vacuum.test a2a44544df719666efb51afbfeb6062fd59a672a F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/version.test 2ba212ba06380e65e476bdf2fcd390e8b05af5a0 F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53 -F test/where.test 45a816fc3b055a8306a1482f98b7c0b2cf14581b +F test/where.test 32135ef3fe2bd427a94ad4982c35565c46abafe2 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/lemon.c f4fb7226c930435e994441a470ed60a7c540f518 F tool/lempar.c 0b5e7a58634e0d448929b8e85f7981c2aa708d57 @@ -193,7 +193,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 821b0b297c11a5e8d08d73b5eff810652e5a0d27 -R c82e653b769eb6c799477d31b330ecb3 +P 7c31e257e2d109bfedf63dc307b422e1abd46d0e +R 5feb1ed8cc5ac536a6c28ba5fb650adc U drh -Z 82230e305545f87ef38ec9ab9f82ee14 +Z 09dcaf5d692d1cd749b1f77eda04144f diff --git a/manifest.uuid b/manifest.uuid index d826b0d5d1..7b56c40d86 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c31e257e2d109bfedf63dc307b422e1abd46d0e \ No newline at end of file +8f249c45cbc77f4320798ff1a830b55e5c74888a \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index df1a0485d5..939519a09b 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.67 2004/05/18 09:58:07 danielk1977 Exp $ +** $Id: delete.c,v 1.68 2004/05/19 14:56:56 drh Exp $ */ #include "sqliteInt.h" @@ -234,8 +234,7 @@ void sqlite3DeleteFrom( sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); } - sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0); - + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); sqlite3VdbeAddOp(v, OP_RowData, iCur, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0); @@ -394,6 +393,3 @@ void sqlite3GenerateRowIndexDelete( sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0); } } - - - diff --git a/src/insert.c b/src/insert.c index 12ed4a4d53..52096a8e5e 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.102 2004/05/18 09:58:07 danielk1977 Exp $ +** $Id: insert.c,v 1.103 2004/05/19 14:56:56 drh Exp $ */ #include "sqliteInt.h" @@ -823,7 +823,7 @@ void sqlite3GenerateConstraintChecks( sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0); if( isUpdate ){ sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1); - sqlite3VdbeAddOp(v, OP_MoveTo, base, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } seenReplace = 1; break; @@ -840,7 +840,7 @@ void sqlite3GenerateConstraintChecks( if( isUpdate ){ sqlite3VdbeChangeP2(v, jumpInst1, contAddr); sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1); - sqlite3VdbeAddOp(v, OP_MoveTo, base, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } } @@ -926,7 +926,7 @@ void sqlite3GenerateConstraintChecks( sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0); if( isUpdate ){ sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1); - sqlite3VdbeAddOp(v, OP_MoveTo, base, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } seenReplace = 1; break; @@ -1010,6 +1010,3 @@ int sqlite3OpenTableAndIndices(Parse *pParse, Table *pTab, int base){ } return i; } - - - diff --git a/src/select.c b/src/select.c index 1e1ab300cd..5f49313ed7 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.168 2004/05/18 22:38:32 drh Exp $ +** $Id: select.c,v 1.169 2004/05/19 14:56:56 drh Exp $ */ #include "sqliteInt.h" @@ -2023,7 +2023,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ sqlite3VdbeAddOp(v, seekOp, base+1, 0); sqlite3VdbeAddOp(v, OP_IdxRecno, base+1, 0); sqlite3VdbeAddOp(v, OP_Close, base+1, 0); - sqlite3VdbeAddOp(v, OP_MoveTo, base, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } eList.nExpr = 1; memset(&eListItem, 0, sizeof(eListItem)); diff --git a/src/update.c b/src/update.c index 71c6c6f840..e35ee4c87d 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.76 2004/05/18 09:58:08 danielk1977 Exp $ +** $Id: update.c,v 1.77 2004/05/19 14:56:57 drh Exp $ */ #include "sqliteInt.h" @@ -262,7 +262,7 @@ void sqlite3Update( sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); } - sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); /* Generate the OLD table */ @@ -458,6 +458,3 @@ update_cleanup: sqlite3ExprDelete(pWhere); return; } - - - diff --git a/src/vdbe.c b/src/vdbe.c index ac28e3b2a6..688670553e 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.303 2004/05/19 13:13:08 drh Exp $ +** $Id: vdbe.c,v 1.304 2004/05/19 14:56:57 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -52,7 +52,7 @@ /* ** The following global variable is incremented every time a cursor -** moves, either by the OP_MoveTo or the OP_Next opcode. The test +** moves, either by the OP_MoveXX, OP_Next, or OP_Prev opcodes. The test ** procedures use this information to make sure that indices are ** working correctly. This variable has no function other than to ** help verify the correct operation of the library. @@ -2757,43 +2757,50 @@ case OP_Close: { break; } -/* Opcode: MoveTo P1 P2 * +/* Opcode: MoveGe P1 P2 * ** ** Pop the top of the stack and use its value as a key. Reposition -** cursor P1 so that it points to an entry with a matching key. If -** the table contains no record with a matching key, then the cursor -** is left pointing at the first record that is greater than the key. +** cursor P1 so that it points to the smallest entry that is greater +** than or equal to the key that was popped ffrom the stack. +** If there are no records greater than or equal to the key and P2 +** is not zero, then jump to P2. +** +** See also: Found, NotFound, Distinct, MoveLt, MoveGt, MoveLe +*/ +/* Opcode: MoveGt P1 P2 * +** +** Pop the top of the stack and use its value as a key. Reposition +** cursor P1 so that it points to the smallest entry that is greater +** than the key from the stack. ** If there are no records greater than the key and P2 is not zero, -** then an immediate jump to P2 is made. +** then jump to P2. ** -** 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 move. This causes the P1 cursor to move -** 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, MoveGe, MoveLe */ /* Opcode: MoveLt P1 P2 * ** ** Pop the top of the stack and use its value as a key. Reposition -** cursor P1 so that it points to the entry with the largest key that is -** less than the key popped from the stack. -** If there are no records less than than the key and P2 -** is not zero then an immediate jump to P2 is made. +** cursor P1 so that it points to the largest entry that is less +** than the key from the stack. +** If there are no records less than the key and P2 is not zero, +** then jump to P2. ** -** 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 move. This causes the P1 cursor to move -** 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: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLe +*/ +/* Opcode: MoveLe P1 P2 * ** -** See also: MoveTo +** Pop the top of the stack and use its value as a key. Reposition +** cursor P1 so that it points to the largest entry that is less than +** or equal to the key that was popped from the stack. +** If there are no records less than or eqal to the key and P2 is not zero, +** then jump to P2. +** +** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt */ case OP_MoveLt: -case OP_MoveTo: { +case OP_MoveLe: +case OP_MoveGe: +case OP_MoveGt: { int i = pOp->p1; Cursor *pC; @@ -2802,13 +2809,15 @@ case OP_MoveTo: { pC = p->apCsr[i]; if( pC->pCursor!=0 ){ int res, oc; + oc = pOp->opcode; pC->nullRow = 0; + pC->incrKey = oc==OP_MoveGt || oc==OP_MoveLe; if( pC->intKey ){ i64 iKey; assert( !pOp->p3 ); Integerify(pTos); iKey = intToKey(pTos->i); - if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){ + if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){ pC->movetoTarget = iKey; pC->deferredMoveto = 1; Release(pTos); @@ -2831,14 +2840,16 @@ case OP_MoveTo: { pC->cacheValid = 0; pC->incrKey = 0; sqlite3_search_count++; - oc = pOp->opcode; - if( oc==OP_MoveTo && res<0 ){ - sqlite3BtreeNext(pC->pCursor, &res); - pC->recnoIsValid = 0; - if( res && pOp->p2>0 ){ - pc = pOp->p2 - 1; + if( oc==OP_MoveGe || oc==OP_MoveGt ){ + if( res<0 ){ + sqlite3BtreeNext(pC->pCursor, &res); + pC->recnoIsValid = 0; + if( res && pOp->p2>0 ){ + pc = pOp->p2 - 1; + } } - }else if( oc==OP_MoveLt ){ + }else{ + assert( oc==OP_MoveLt || oc==OP_MoveLe ); if( res>=0 ){ sqlite3BtreePrevious(pC->pCursor, &res); pC->recnoIsValid = 0; @@ -2927,12 +2938,13 @@ case OP_Found: { ** using MakeIdxKey. Call it K. This instruction pops R from the ** stack but it leaves K unchanged. ** -** P1 is an index. So all but the last four bytes of K are an -** index string. The last four bytes of K are a record number. +** P1 is an index. So it has no data and its key consists of a +** record generated by OP_MakeIdxKey. This key contains one or more +** fields followed by a varint ROWID. ** ** This instruction asks if there is an entry in P1 where the -** index string matches K but the record number is different -** from R. If there is no such entry, then there is an immediate +** fields matches K but the rowid is different from R. +** If there is no such entry, then there is an immediate ** jump to P2. If any entry does exist where the index string ** matches K but the record number is not R, then the record ** number for that entry is pushed onto the stack and control @@ -2987,7 +2999,7 @@ case OP_IsUnique: { break; } } - rc = sqlite3VdbeIdxKeyCompare(pCx, len, zKey, 0, &res); + rc = sqlite3VdbeIdxKeyCompare(pCx, len, zKey, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res>0 ){ pc = pOp->p2 - 1; @@ -3685,7 +3697,7 @@ case OP_IdxPut: { int c; sqlite3BtreeKeySize(pCrsr, &n); if( n==nKey && - sqlite3VdbeIdxKeyCompare(pC, len, zKey, 0, &c)==SQLITE_OK + sqlite3VdbeIdxKeyCompare(pC, len, zKey, &c)==SQLITE_OK && c==0 ){ rc = SQLITE_CONSTRAINT; @@ -3802,32 +3814,31 @@ case OP_IdxRecno: { break; } -/* Opcode: IdxGT P1 P2 P3 +/* Opcode: IdxGT P1 P2 * ** ** Compare the top of the stack against the key on the index entry that ** 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 ** then jump to P2. Otherwise fall through to the next instruction. ** 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 P3 ** ** Compare the top of the stack against the key on the index entry that ** 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 in the cursor is greater than or equal to ** the top of the stack ** then jump to P2. Otherwise fall through to the next instruction. ** 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. +** an epsilon prior to the comparison. This make the opcode work +** like IdxGT except that if the key from the stack is a prefix of +** the key in the cursor, the result is false whereas it would be +** true with IdxGT. */ -/* Opcode: IdxLT P1 P2 * +/* Opcode: IdxLT P1 P2 P3 ** ** Compare the top of the stack against the key on the index entry that ** cursor P1 is currently pointing to. Ignore the ROWID of the @@ -3837,7 +3848,8 @@ case OP_IdxRecno: { ** ** 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. +** an epsilon prior to the comparison. This makes the opcode work +** like IdxLE. */ case OP_IdxLT: case OP_IdxGT: @@ -3853,10 +3865,9 @@ case OP_IdxGE: { Stringify(pTos); assert( pC->deferredMoveto==0 ); - if( pOp->p3 ){ - pC->incrKey = 1; - } - rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, 0, &res); + pC->incrKey = pOp->p3!=0; + assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT ); + rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, &res); pC->incrKey = 0; if( rc!=SQLITE_OK ){ break; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 6d99459bbe..f86a4aff31 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -328,7 +328,7 @@ int sqlite3VdbeSerialPut(unsigned char *, const Mem *); int sqlite3VdbeSerialGet(const unsigned char *, u64, Mem *); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); -int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int, int*); +int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(Mem *, Mem *); int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 579c80d3a5..9c4f702355 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1626,11 +1626,16 @@ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ return SQLITE_OK; } +/* +** Compare the key of index entry that cursor pC is point to against +** the key string in pKey (of length nKey). Write into *pRes a number +** that is negative, zero, or positive if pC is less than, equal to, +** or greater than pKey. Return SQLITE_OK on success. +*/ int sqlite3VdbeIdxKeyCompare( - Cursor *pC, - int nKey, const unsigned char *pKey, - int ignorerowid, - int *res + Cursor *pC, /* The cursor to compare against */ + int nKey, const u8 *pKey, /* The key to compare */ + int *res /* Write the comparison result here */ ){ unsigned char *pCellKey; u64 nCellKey; @@ -1662,10 +1667,12 @@ int sqlite3VdbeIdxKeyCompare( len = nCellKey-2; while( pCellKey[len] && --len ); +#if 0 if( ignorerowid ){ nKey--; while( pKey[nKey] && --nKey ); } +#endif *res = sqlite3VdbeKeyCompare(pC, len, pCellKey, nKey, pKey); if( freeCellKey ){ diff --git a/src/where.c b/src/where.c index cc50d1a58e..cc8ac97dde 100644 --- a/src/where.c +++ b/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.97 2004/05/19 13:13:08 drh Exp $ +** $Id: where.c,v 1.98 2004/05/19 14:56:57 drh Exp $ */ #include "sqliteInt.h" @@ -809,15 +809,6 @@ WhereInfo *sqlite3WhereBegin( sqlite3IndexAffinityStr(v, pIdx); 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 ){ - testOp = OP_IdxGT; - }else{ - 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 @@ -825,18 +816,18 @@ WhereInfo *sqlite3WhereBegin( ** iteration of the scan to see if the scan has finished. */ if( pLevel->bRev ){ /* Scan in reverse order */ - sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk); - sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC); + sqlite3VdbeAddOp(v, OP_MoveLe, pLevel->iCur, brk); start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); sqlite3VdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk); pLevel->op = OP_Prev; }else{ /* Scan in the forward order */ - sqlite3VdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk); + sqlite3VdbeAddOp(v, OP_MoveGe, pLevel->iCur, brk); start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0); - sqlite3VdbeAddOp(v, testOp, pLevel->iCur, brk); - if( testOp==OP_IdxGE ){ - sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC); + if( nColumn==pIdx->nColumn || 0 ){ + sqlite3VdbeAddOp(v, OP_IdxGT, pLevel->iCur, brk); + }else{ + sqlite3VdbeOp3(v, OP_IdxGE, pLevel->iCur, brk, "+", P3_STATIC); } pLevel->op = OP_Next; } @@ -846,7 +837,7 @@ WhereInfo *sqlite3WhereBegin( if( i==pTabList->nSrc-1 && pushKey ){ haveKey = 1; }else{ - sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); haveKey = 0; } pLevel->p1 = pLevel->iCur; @@ -871,7 +862,7 @@ WhereInfo *sqlite3WhereBegin( } sqlite3VdbeAddOp(v, OP_ForceInt, aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk); - sqlite3VdbeAddOp(v, OP_MoveTo, iCur, brk); + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, brk); aExpr[k].p = 0; }else{ sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk); @@ -1023,10 +1014,8 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0); sqlite3IndexAffinityStr(v, pIdx); if( pLevel->bRev ){ - sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk); - if( leFlag ){ - sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC); - } + int op = leFlag ? OP_MoveLe : OP_MoveLt; + sqlite3VdbeAddOp(v, op, pLevel->iCur, brk); }else{ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); } @@ -1083,10 +1072,8 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); testOp = OP_IdxLT; }else{ - sqlite3VdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk); - if( !geFlag ){ - sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC); - } + int op = geFlag ? OP_MoveGe : OP_MoveGt; + sqlite3VdbeAddOp(v, op, pLevel->iCur, brk); } }else if( pLevel->bRev ){ testOp = OP_Noop; @@ -1112,7 +1099,7 @@ WhereInfo *sqlite3WhereBegin( if( i==pTabList->nSrc-1 && pushKey ){ haveKey = 1; }else{ - sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); haveKey = 0; } @@ -1135,7 +1122,7 @@ WhereInfo *sqlite3WhereBegin( } if( haveKey ){ haveKey = 0; - sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); } sqlite3ExprIfFalse(pParse, aExpr[j].p, cont, 1); aExpr[j].p = 0; @@ -1158,7 +1145,7 @@ WhereInfo *sqlite3WhereBegin( ** no outer joins with DELETE and UPDATE. */ haveKey = 0; - sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0); + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); } sqlite3ExprIfFalse(pParse, aExpr[j].p, cont, 1); aExpr[j].p = 0; diff --git a/test/where.test b/test/where.test index d0c73884fd..465fb81696 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.18 2004/05/19 13:13:08 drh Exp $ +# $Id: where.test,v 1.19 2004/05/19 14:56:57 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -140,6 +140,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} + do_test where-1.28 { count {SELECT w FROM t1 WHERE x+1=4 AND y+1==122} } {10 99}