From: drh Date: Fri, 14 Feb 2014 15:13:36 +0000 (+0000) Subject: Add OP_IdxGT and OP_IdxLE as distinct opcodes. Formerly these operations where X-Git-Tag: version-3.8.4~68 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a1d365903ef55c06c7731fbd5fbb7811f9805ee;p=thirdparty%2Fsqlite.git 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 --- diff --git a/manifest b/manifest index 823607add4..b85a23bdd5 100644 --- a/manifest +++ b/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 diff --git a/manifest.uuid b/manifest.uuid index 70012cb83b..7c4fe4fd3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e573198e107f1b85ee37c52a10343d38968bda1 \ No newline at end of file +b6bea903ac8e1717ed50b221d73bd0be061c7663 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 00cff1e21e..610376dd20 100644 --- a/src/vdbe.c +++ b/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,32 +4620,50 @@ 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. +*/ +/* Opcode: IdxLE 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 makes the opcode work like IdxLE. +** 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 */ +case OP_IdxGE: { /* jump */ VdbeCursor *pC; int res; UnpackedRecord r; @@ -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->opcodeopcode==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 ){ diff --git a/src/where.c b/src/where.c index d0d95c081d..94e939e27f 100644 --- a/src/where.c +++ b/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; ju.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 ); - testcase( op==OP_IdxGE ); - testcase( op==OP_IdxLT ); - if( op!=OP_Noop ){ + if( pRangeEnd || nEq ){ + op = aEndOp[bRev*2 + endEq]; + testcase( op==OP_IdxGT ); + testcase( op==OP_IdxGE ); + testcase( op==OP_IdxLT ); + 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