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

Add OP_IdxGT and OP_IdxLE as distinct opcodes. Formerly these operations where

done using OP_IdxGE and OP_IdxLT with the P5 flag set.  But VDBE code is easier
to read with distinct opcode names.  Also change OP_SeekGe to OP_SeekGE, and
so forth, so that the capitalization is consistent.  The whole point of this
change is to improve the readability of VDBE listings.

FossilOrigin-Name: b6bea903ac8e1717ed50b221d73bd0be061c7663
This commit is contained in:
drh
2014-02-14 15:13:36 +00:00
parent 2953ba9e20
commit 4a1d365903
4 changed files with 94 additions and 71 deletions

View File

@@ -1,5 +1,5 @@
C Revise\show\sthe\sTcl\ssystem\sencoding\sis\shandled\sby\sthe\stest\ssuite. C Add\sOP_IdxGT\sand\sOP_IdxLE\sas\sdistinct\sopcodes.\s\sFormerly\sthese\soperations\swhere\ndone\susing\sOP_IdxGE\sand\sOP_IdxLT\swith\sthe\sP5\sflag\sset.\s\sBut\sVDBE\scode\sis\seasier\nto\sread\swith\sdistinct\sopcode\snames.\s\sAlso\schange\sOP_SeekGe\sto\sOP_SeekGE,\sand\nso\sforth,\sso\sthat\sthe\scapitalization\sis\sconsistent.\s\sThe\swhole\spoint\sof\sthis\nchange\sis\sto\simprove\sthe\sreadability\sof\sVDBE\slistings.
D 2014-02-14T00:25:03.606 D 2014-02-14T15:13:36.850
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -277,7 +277,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 3f0872b12ec3fc24ee540f8bb09de181ddad6d8d F src/vdbe.c 543ed4ed0c41b34affad239374d4c07e6e5b2401
F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26
F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8
F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820
@@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c b0436385f40e86f0f4cc60355cd018bde2c89d4b F src/where.c 43eb827f10d90972578eb0759d01bf0094fcb8c7
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P b22b61406899c2694dae984995d2484fdb8122f1 P 9e573198e107f1b85ee37c52a10343d38968bda1
R e61eea6addc7b24a1393827be3ebc05a R 761a583803ea417c3e82fa617fd0a139
U mistachkin U drh
Z f753108c2da8e4ac5af912585f7a37ad Z 39171055bea51b7fba314c7bdb8e0ff5

View File

@@ -1 +1 @@
9e573198e107f1b85ee37c52a10343d38968bda1 b6bea903ac8e1717ed50b221d73bd0be061c7663

View File

@@ -3425,10 +3425,10 @@ case OP_Close: {
** **
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
*/ */
case OP_SeekLt: /* jump, in3 */ case OP_SeekLT: /* jump, in3 */
case OP_SeekLe: /* jump, in3 */ case OP_SeekLE: /* jump, in3 */
case OP_SeekGe: /* jump, in3 */ case OP_SeekGE: /* jump, in3 */
case OP_SeekGt: { /* jump, in3 */ case OP_SeekGT: { /* jump, in3 */
int res; int res;
int oc; int oc;
VdbeCursor *pC; VdbeCursor *pC;
@@ -3441,9 +3441,9 @@ case OP_SeekGt: { /* jump, in3 */
pC = p->apCsr[pOp->p1]; pC = p->apCsr[pOp->p1];
assert( pC!=0 ); assert( pC!=0 );
assert( pC->pseudoTableReg==0 ); assert( pC->pseudoTableReg==0 );
assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekLE == OP_SeekLT+1 );
assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGE == OP_SeekLT+2 );
assert( OP_SeekGt == OP_SeekLt+3 ); assert( OP_SeekGT == OP_SeekLT+3 );
assert( pC->isOrdered ); assert( pC->isOrdered );
assert( pC->pCursor!=0 ); assert( pC->pCursor!=0 );
oc = pOp->opcode; oc = pOp->opcode;
@@ -3475,19 +3475,19 @@ case OP_SeekGt: { /* jump, in3 */
** (x <= 4.9) -> (x < 5) ** (x <= 4.9) -> (x < 5)
*/ */
if( pIn3->r<(double)iKey ){ if( pIn3->r<(double)iKey ){
assert( OP_SeekGe==(OP_SeekGt-1) ); assert( OP_SeekGE==(OP_SeekGT-1) );
assert( OP_SeekLt==(OP_SeekLe-1) ); assert( OP_SeekLT==(OP_SeekLE-1) );
assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) ); assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) );
if( (oc & 0x0001)==(OP_SeekGt & 0x0001) ) oc--; if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--;
} }
/* If the approximation iKey is smaller than the actual real search /* If the approximation iKey is smaller than the actual real search
** term, substitute <= for < and > for >=. */ ** term, substitute <= for < and > for >=. */
else if( pIn3->r>(double)iKey ){ else if( pIn3->r>(double)iKey ){
assert( OP_SeekLe==(OP_SeekLt+1) ); assert( OP_SeekLE==(OP_SeekLT+1) );
assert( OP_SeekGt==(OP_SeekGe+1) ); assert( OP_SeekGT==(OP_SeekGE+1) );
assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) ); assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
if( (oc & 0x0001)==(OP_SeekLt & 0x0001) ) oc++; if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
} }
} }
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
@@ -3506,17 +3506,17 @@ case OP_SeekGt: { /* jump, in3 */
r.nField = (u16)nField; r.nField = (u16)nField;
/* The next line of code computes as follows, only faster: /* The next line of code computes as follows, only faster:
** if( oc==OP_SeekGt || oc==OP_SeekLe ){ ** if( oc==OP_SeekGT || oc==OP_SeekLE ){
** r.flags = UNPACKED_INCRKEY; ** r.flags = UNPACKED_INCRKEY;
** }else{ ** }else{
** r.flags = 0; ** r.flags = 0;
** } ** }
*/ */
r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt))); r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLT)));
assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY ); assert( oc!=OP_SeekGT || r.flags==UNPACKED_INCRKEY );
assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY ); assert( oc!=OP_SeekLE || r.flags==UNPACKED_INCRKEY );
assert( oc!=OP_SeekGe || r.flags==0 ); assert( oc!=OP_SeekGE || r.flags==0 );
assert( oc!=OP_SeekLt || r.flags==0 ); assert( oc!=OP_SeekLT || r.flags==0 );
r.aMem = &aMem[pOp->p3]; r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
@@ -3534,8 +3534,8 @@ case OP_SeekGt: { /* jump, in3 */
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
sqlite3_search_count++; sqlite3_search_count++;
#endif #endif
if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
if( res<0 || (res==0 && oc==OP_SeekGt) ){ if( res<0 || (res==0 && oc==OP_SeekGT) ){
res = 0; res = 0;
rc = sqlite3BtreeNext(pC->pCursor, &res); rc = sqlite3BtreeNext(pC->pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error; if( rc!=SQLITE_OK ) goto abort_due_to_error;
@@ -3544,8 +3544,8 @@ case OP_SeekGt: { /* jump, in3 */
res = 0; res = 0;
} }
}else{ }else{
assert( oc==OP_SeekLt || oc==OP_SeekLe ); assert( oc==OP_SeekLT || oc==OP_SeekLE );
if( res>0 || (res==0 && oc==OP_SeekLt) ){ if( res>0 || (res==0 && oc==OP_SeekLT) ){
res = 0; res = 0;
rc = sqlite3BtreePrevious(pC->pCursor, &res); rc = sqlite3BtreePrevious(pC->pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error; if( rc!=SQLITE_OK ) goto abort_due_to_error;
@@ -4620,30 +4620,48 @@ case OP_IdxRowid: { /* out2-prerelease */
** Synopsis: key=r[P3@P4] ** Synopsis: key=r[P3@P4]
** **
** The P4 register values beginning with P3 form an unpacked index ** The P4 register values beginning with P3 form an unpacked index
** key that omits the ROWID. Compare this key value against the index ** key that omits the PRIMARY KEY. Compare this key value against the index
** that P1 is currently pointing to, ignoring the ROWID on the P1 index. ** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID
** fields at the end.
** **
** If the P1 index entry is greater than or equal to the key value ** If the P1 index entry is greater than or equal to the key value
** then jump to P2. Otherwise fall through to the next instruction. ** then jump to P2. Otherwise fall through to the next instruction.
*/
/* Opcode: IdxGT P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
** **
** If P5 is non-zero then the key value is increased by an epsilon ** The P4 register values beginning with P3 form an unpacked index
** prior to the comparison. This make the opcode work like IdxGT except ** key that omits the PRIMARY KEY. Compare this key value against the index
** that if the key from register P3 is a prefix of the key in the cursor, ** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID
** the result is false whereas it would be true with IdxGT. ** fields at the end.
**
** If the P1 index entry is greater than the key value
** then jump to P2. Otherwise fall through to the next instruction.
*/ */
/* Opcode: IdxLT P1 P2 P3 P4 P5 /* Opcode: IdxLT P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4] ** Synopsis: key=r[P3@P4]
** **
** The P4 register values beginning with P3 form an unpacked index ** The P4 register values beginning with P3 form an unpacked index
** key that omits the ROWID. Compare this key value against the index ** key that omits the PRIMARY KEY or ROWID. Compare this key value against
** that P1 is currently pointing to, ignoring the ROWID on the P1 index. ** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
** ROWID on the P1 index.
** **
** If the P1 index entry is less than the key value then jump to P2. ** If the P1 index entry is less than the key value then jump to P2.
** Otherwise fall through to the next instruction. ** Otherwise fall through to the next instruction.
**
** If P5 is non-zero then the key value is increased by an epsilon prior
** to the comparison. This makes the opcode work like IdxLE.
*/ */
/* Opcode: IdxLE P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
** key that omits the PRIMARY KEY or ROWID. Compare this key value against
** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
** ROWID on the P1 index.
**
** If the P1 index entry is less than or equal to the key value then jump
** to P2. Otherwise fall through to the next instruction.
*/
case OP_IdxLE: /* jump */
case OP_IdxGT: /* jump */
case OP_IdxLT: /* jump */ case OP_IdxLT: /* jump */
case OP_IdxGE: { /* jump */ case OP_IdxGE: { /* jump */
VdbeCursor *pC; VdbeCursor *pC;
@@ -4660,9 +4678,11 @@ case OP_IdxGE: { /* jump */
assert( pOp->p4type==P4_INT32 ); assert( pOp->p4type==P4_INT32 );
r.pKeyInfo = pC->pKeyInfo; r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i; r.nField = (u16)pOp->p4.i;
if( pOp->p5 ){ if( pOp->opcode<OP_IdxLT ){
assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxGT );
r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
}else{ }else{
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT );
r.flags = UNPACKED_PREFIX_MATCH; r.flags = UNPACKED_PREFIX_MATCH;
} }
r.aMem = &aMem[pOp->p3]; r.aMem = &aMem[pOp->p3];
@@ -4671,10 +4691,12 @@ case OP_IdxGE: { /* jump */
#endif #endif
res = 0; /* Not needed. Only used to silence a warning. */ res = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res); rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res);
if( pOp->opcode==OP_IdxLT ){ assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
if( (pOp->opcode&1)==(OP_IdxLT&1) ){
assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
res = -res; res = -res;
}else{ }else{
assert( pOp->opcode==OP_IdxGE ); assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
res++; res++;
} }
if( res>0 ){ if( res>0 ){

View File

@@ -2505,7 +2505,7 @@ static int codeAllEqualityTerms(
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
j = sqlite3VdbeAddOp0(v, OP_Goto); j = sqlite3VdbeAddOp0(v, OP_Goto);
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt), pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
iIdxCur, 0, regBase, nSkip); iIdxCur, 0, regBase, nSkip);
sqlite3VdbeJumpHere(v, j); sqlite3VdbeJumpHere(v, j);
for(j=0; j<nSkip; j++){ for(j=0; j<nSkip; j++){
@@ -2885,10 +2885,10 @@ static Bitmask codeOneLoopStart(
** seek opcodes. It depends on a particular ordering of TK_xx ** seek opcodes. It depends on a particular ordering of TK_xx
*/ */
const u8 aMoveOp[] = { const u8 aMoveOp[] = {
/* TK_GT */ OP_SeekGt, /* TK_GT */ OP_SeekGT,
/* TK_LE */ OP_SeekLe, /* TK_LE */ OP_SeekLE,
/* TK_LT */ OP_SeekLt, /* TK_LT */ OP_SeekLT,
/* TK_GE */ OP_SeekGe /* TK_GE */ OP_SeekGE
}; };
assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
@@ -2973,15 +2973,16 @@ static Bitmask codeOneLoopStart(
0, 0,
OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */
OP_Last, /* 3: (!start_constraints && startEq && bRev) */ OP_Last, /* 3: (!start_constraints && startEq && bRev) */
OP_SeekGt, /* 4: (start_constraints && !startEq && !bRev) */ OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */
OP_SeekLt, /* 5: (start_constraints && !startEq && bRev) */ OP_SeekLT, /* 5: (start_constraints && !startEq && bRev) */
OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */ OP_SeekGE, /* 6: (start_constraints && startEq && !bRev) */
OP_SeekLe /* 7: (start_constraints && startEq && bRev) */ OP_SeekLE /* 7: (start_constraints && startEq && bRev) */
}; };
static const u8 aEndOp[] = { static const u8 aEndOp[] = {
OP_Noop, /* 0: (!end_constraints) */ OP_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */
OP_IdxGE, /* 1: (end_constraints && !bRev) */ OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */
OP_IdxLT /* 2: (end_constraints && bRev) */ OP_IdxLE, /* 2: (end_constraints && bRev && !endEq) */
OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */
}; };
u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */
int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */
@@ -3093,10 +3094,10 @@ static Bitmask codeOneLoopStart(
assert( op!=0 ); assert( op!=0 );
testcase( op==OP_Rewind ); testcase( op==OP_Rewind );
testcase( op==OP_Last ); testcase( op==OP_Last );
testcase( op==OP_SeekGt ); testcase( op==OP_SeekGT );
testcase( op==OP_SeekGe ); testcase( op==OP_SeekGE );
testcase( op==OP_SeekLe ); testcase( op==OP_SeekLE );
testcase( op==OP_SeekLt ); testcase( op==OP_SeekLT );
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
/* Load the value for the inequality constraint at the end of the /* Load the value for the inequality constraint at the end of the
@@ -3124,13 +3125,13 @@ static Bitmask codeOneLoopStart(
pLevel->p2 = sqlite3VdbeCurrentAddr(v); pLevel->p2 = sqlite3VdbeCurrentAddr(v);
/* Check if the index cursor is past the end of the range. */ /* Check if the index cursor is past the end of the range. */
op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)]; if( pRangeEnd || nEq ){
testcase( op==OP_Noop ); op = aEndOp[bRev*2 + endEq];
testcase( op==OP_IdxGT );
testcase( op==OP_IdxGE ); testcase( op==OP_IdxGE );
testcase( op==OP_IdxLT ); testcase( op==OP_IdxLT );
if( op!=OP_Noop ){ testcase( op==OP_IdxLE );
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0);
} }
/* If there are inequality constraints, check that the value /* If there are inequality constraints, check that the value