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:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
||||
C Revise\show\sthe\sTcl\ssystem\sencoding\sis\shandled\sby\sthe\stest\ssuite.
|
||||
D 2014-02-14T00:25:03.606
|
||||
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-14T15:13:36.850
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -277,7 +277,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee
|
||||
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
||||
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
|
||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||
F src/vdbe.c 3f0872b12ec3fc24ee540f8bb09de181ddad6d8d
|
||||
F src/vdbe.c 543ed4ed0c41b34affad239374d4c07e6e5b2401
|
||||
F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26
|
||||
F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8
|
||||
F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820
|
||||
@@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
||||
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
||||
F src/where.c b0436385f40e86f0f4cc60355cd018bde2c89d4b
|
||||
F src/where.c 43eb827f10d90972578eb0759d01bf0094fcb8c7
|
||||
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||
P b22b61406899c2694dae984995d2484fdb8122f1
|
||||
R e61eea6addc7b24a1393827be3ebc05a
|
||||
U mistachkin
|
||||
Z f753108c2da8e4ac5af912585f7a37ad
|
||||
P 9e573198e107f1b85ee37c52a10343d38968bda1
|
||||
R 761a583803ea417c3e82fa617fd0a139
|
||||
U drh
|
||||
Z 39171055bea51b7fba314c7bdb8e0ff5
|
||||
|
@@ -1 +1 @@
|
||||
9e573198e107f1b85ee37c52a10343d38968bda1
|
||||
b6bea903ac8e1717ed50b221d73bd0be061c7663
|
100
src/vdbe.c
100
src/vdbe.c
@@ -3425,10 +3425,10 @@ case OP_Close: {
|
||||
**
|
||||
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
|
||||
*/
|
||||
case OP_SeekLt: /* jump, in3 */
|
||||
case OP_SeekLe: /* jump, in3 */
|
||||
case OP_SeekGe: /* jump, in3 */
|
||||
case OP_SeekGt: { /* jump, in3 */
|
||||
case OP_SeekLT: /* jump, in3 */
|
||||
case OP_SeekLE: /* jump, in3 */
|
||||
case OP_SeekGE: /* jump, in3 */
|
||||
case OP_SeekGT: { /* jump, in3 */
|
||||
int res;
|
||||
int oc;
|
||||
VdbeCursor *pC;
|
||||
@@ -3441,9 +3441,9 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
assert( pC->pseudoTableReg==0 );
|
||||
assert( OP_SeekLe == OP_SeekLt+1 );
|
||||
assert( OP_SeekGe == OP_SeekLt+2 );
|
||||
assert( OP_SeekGt == OP_SeekLt+3 );
|
||||
assert( OP_SeekLE == OP_SeekLT+1 );
|
||||
assert( OP_SeekGE == OP_SeekLT+2 );
|
||||
assert( OP_SeekGT == OP_SeekLT+3 );
|
||||
assert( pC->isOrdered );
|
||||
assert( pC->pCursor!=0 );
|
||||
oc = pOp->opcode;
|
||||
@@ -3475,19 +3475,19 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
** (x <= 4.9) -> (x < 5)
|
||||
*/
|
||||
if( pIn3->r<(double)iKey ){
|
||||
assert( OP_SeekGe==(OP_SeekGt-1) );
|
||||
assert( OP_SeekLt==(OP_SeekLe-1) );
|
||||
assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) );
|
||||
if( (oc & 0x0001)==(OP_SeekGt & 0x0001) ) oc--;
|
||||
assert( OP_SeekGE==(OP_SeekGT-1) );
|
||||
assert( OP_SeekLT==(OP_SeekLE-1) );
|
||||
assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) );
|
||||
if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--;
|
||||
}
|
||||
|
||||
/* If the approximation iKey is smaller than the actual real search
|
||||
** term, substitute <= for < and > for >=. */
|
||||
else if( pIn3->r>(double)iKey ){
|
||||
assert( OP_SeekLe==(OP_SeekLt+1) );
|
||||
assert( OP_SeekGt==(OP_SeekGe+1) );
|
||||
assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) );
|
||||
if( (oc & 0x0001)==(OP_SeekLt & 0x0001) ) oc++;
|
||||
assert( OP_SeekLE==(OP_SeekLT+1) );
|
||||
assert( OP_SeekGT==(OP_SeekGE+1) );
|
||||
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
|
||||
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
|
||||
}
|
||||
}
|
||||
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
|
||||
@@ -3506,17 +3506,17 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
r.nField = (u16)nField;
|
||||
|
||||
/* 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;
|
||||
** }else{
|
||||
** r.flags = 0;
|
||||
** }
|
||||
*/
|
||||
r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)));
|
||||
assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY );
|
||||
assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY );
|
||||
assert( oc!=OP_SeekGe || r.flags==0 );
|
||||
assert( oc!=OP_SeekLt || r.flags==0 );
|
||||
r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLT)));
|
||||
assert( oc!=OP_SeekGT || r.flags==UNPACKED_INCRKEY );
|
||||
assert( oc!=OP_SeekLE || r.flags==UNPACKED_INCRKEY );
|
||||
assert( oc!=OP_SeekGE || r.flags==0 );
|
||||
assert( oc!=OP_SeekLT || r.flags==0 );
|
||||
|
||||
r.aMem = &aMem[pOp->p3];
|
||||
#ifdef SQLITE_DEBUG
|
||||
@@ -3534,8 +3534,8 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
#ifdef SQLITE_TEST
|
||||
sqlite3_search_count++;
|
||||
#endif
|
||||
if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt );
|
||||
if( res<0 || (res==0 && oc==OP_SeekGt) ){
|
||||
if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
|
||||
if( res<0 || (res==0 && oc==OP_SeekGT) ){
|
||||
res = 0;
|
||||
rc = sqlite3BtreeNext(pC->pCursor, &res);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
@@ -3544,8 +3544,8 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
res = 0;
|
||||
}
|
||||
}else{
|
||||
assert( oc==OP_SeekLt || oc==OP_SeekLe );
|
||||
if( res>0 || (res==0 && oc==OP_SeekLt) ){
|
||||
assert( oc==OP_SeekLT || oc==OP_SeekLE );
|
||||
if( res>0 || (res==0 && oc==OP_SeekLT) ){
|
||||
res = 0;
|
||||
rc = sqlite3BtreePrevious(pC->pCursor, &res);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
@@ -4620,30 +4620,48 @@ case OP_IdxRowid: { /* out2-prerelease */
|
||||
** Synopsis: key=r[P3@P4]
|
||||
**
|
||||
** The P4 register values beginning with P3 form an unpacked index
|
||||
** key that omits the ROWID. Compare this key value against the index
|
||||
** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
|
||||
** key that omits the PRIMARY KEY. Compare this key value against the 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
|
||||
** 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
|
||||
** prior to the comparison. This make the opcode work like IdxGT except
|
||||
** that if the key from register P3 is a prefix of the key in the cursor,
|
||||
** the result is false whereas it would be true with IdxGT.
|
||||
** The P4 register values beginning with P3 form an unpacked index
|
||||
** key that omits the PRIMARY KEY. Compare this key value against the 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 the key value
|
||||
** then jump to P2. Otherwise fall through to the next instruction.
|
||||
*/
|
||||
/* Opcode: IdxLT 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 ROWID. Compare this key value against the index
|
||||
** that P1 is currently pointing to, ignoring the ROWID on the P1 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 the key value then jump to P2.
|
||||
** 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_IdxGE: { /* jump */
|
||||
VdbeCursor *pC;
|
||||
@@ -4660,9 +4678,11 @@ case OP_IdxGE: { /* jump */
|
||||
assert( pOp->p4type==P4_INT32 );
|
||||
r.pKeyInfo = pC->pKeyInfo;
|
||||
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;
|
||||
}else{
|
||||
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT );
|
||||
r.flags = UNPACKED_PREFIX_MATCH;
|
||||
}
|
||||
r.aMem = &aMem[pOp->p3];
|
||||
@@ -4671,10 +4691,12 @@ case OP_IdxGE: { /* jump */
|
||||
#endif
|
||||
res = 0; /* Not needed. Only used to silence a warning. */
|
||||
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;
|
||||
}else{
|
||||
assert( pOp->opcode==OP_IdxGE );
|
||||
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
|
||||
res++;
|
||||
}
|
||||
if( res>0 ){
|
||||
|
41
src/where.c
41
src/where.c
@@ -2505,7 +2505,7 @@ static int codeAllEqualityTerms(
|
||||
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
|
||||
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
|
||||
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);
|
||||
sqlite3VdbeJumpHere(v, 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
|
||||
*/
|
||||
const u8 aMoveOp[] = {
|
||||
/* TK_GT */ OP_SeekGt,
|
||||
/* TK_LE */ OP_SeekLe,
|
||||
/* TK_LT */ OP_SeekLt,
|
||||
/* TK_GE */ OP_SeekGe
|
||||
/* TK_GT */ OP_SeekGT,
|
||||
/* TK_LE */ OP_SeekLE,
|
||||
/* TK_LT */ OP_SeekLT,
|
||||
/* TK_GE */ OP_SeekGE
|
||||
};
|
||||
assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
|
||||
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
|
||||
@@ -2973,15 +2973,16 @@ static Bitmask codeOneLoopStart(
|
||||
0,
|
||||
OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */
|
||||
OP_Last, /* 3: (!start_constraints && startEq && bRev) */
|
||||
OP_SeekGt, /* 4: (start_constraints && !startEq && !bRev) */
|
||||
OP_SeekLt, /* 5: (start_constraints && !startEq && bRev) */
|
||||
OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */
|
||||
OP_SeekLe /* 7: (start_constraints && startEq && bRev) */
|
||||
OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */
|
||||
OP_SeekLT, /* 5: (start_constraints && !startEq && bRev) */
|
||||
OP_SeekGE, /* 6: (start_constraints && startEq && !bRev) */
|
||||
OP_SeekLE /* 7: (start_constraints && startEq && bRev) */
|
||||
};
|
||||
static const u8 aEndOp[] = {
|
||||
OP_Noop, /* 0: (!end_constraints) */
|
||||
OP_IdxGE, /* 1: (end_constraints && !bRev) */
|
||||
OP_IdxLT /* 2: (end_constraints && bRev) */
|
||||
OP_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */
|
||||
OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */
|
||||
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 */
|
||||
int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */
|
||||
@@ -3093,10 +3094,10 @@ static Bitmask codeOneLoopStart(
|
||||
assert( op!=0 );
|
||||
testcase( op==OP_Rewind );
|
||||
testcase( op==OP_Last );
|
||||
testcase( op==OP_SeekGt );
|
||||
testcase( op==OP_SeekGe );
|
||||
testcase( op==OP_SeekLe );
|
||||
testcase( op==OP_SeekLt );
|
||||
testcase( op==OP_SeekGT );
|
||||
testcase( op==OP_SeekGE );
|
||||
testcase( op==OP_SeekLE );
|
||||
testcase( op==OP_SeekLT );
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
|
||||
/* Load the value for the inequality constraint at the end of the
|
||||
@@ -3124,13 +3125,13 @@ static Bitmask codeOneLoopStart(
|
||||
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
|
||||
|
||||
/* Check if the index cursor is past the end of the range. */
|
||||
op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
|
||||
testcase( op==OP_Noop );
|
||||
if( pRangeEnd || nEq ){
|
||||
op = aEndOp[bRev*2 + endEq];
|
||||
testcase( op==OP_IdxGT );
|
||||
testcase( op==OP_IdxGE );
|
||||
testcase( op==OP_IdxLT );
|
||||
if( op!=OP_Noop ){
|
||||
testcase( op==OP_IdxLE );
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0);
|
||||
}
|
||||
|
||||
/* If there are inequality constraints, check that the value
|
||||
|
Reference in New Issue
Block a user