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:
28
manifest
28
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
|
||||
|
@@ -1 +1 @@
|
||||
7c31e257e2d109bfedf63dc307b422e1abd46d0e
|
||||
8f249c45cbc77f4320798ff1a830b55e5c74888a
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
11
src/insert.c
11
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
121
src/vdbe.c
121
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;
|
||||
|
@@ -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*);
|
||||
|
@@ -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 ){
|
||||
|
45
src/where.c
45
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;
|
||||
|
@@ -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}
|
||||
|
Reference in New Issue
Block a user