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

Change opcode names and comments to better describe the operation of

the incrKey flag.  OP_MoveTo becomes OP_MoveGe. (CVS 1407)

FossilOrigin-Name: 8f249c45cbc77f4320798ff1a830b55e5c74888a
This commit is contained in:
drh
2004-05-19 14:56:55 +00:00
parent 772ae62a82
commit 7cf6e4de35
11 changed files with 121 additions and 125 deletions

View File

@@ -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

View File

@@ -1 +1 @@
7c31e257e2d109bfedf63dc307b422e1abd46d0e
8f249c45cbc77f4320798ff1a830b55e5c74888a

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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));

View File

@@ -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;
}

View 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.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;

View File

@@ -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*);

View File

@@ -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 ){

View File

@@ -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;

View File

@@ -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}