Enhancements to the VDBE opcode loop to reduce the number of machine-code
instructions evaluated by about 10%. FossilOrigin-Name: 9744ffb3f5bc6d8fd59fbb6577a0d549411cd967
This commit is contained in:
parent
039fc32e84
commit
3c65721a5b
18
manifest
18
manifest
@ -1,8 +1,8 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
C Code\sgenerator\stries\sto\savoid\spointless\sOP_IsNull\sand\sOP_Affinity\sopcodes.
|
||||
D 2009-11-17T18:31:48
|
||||
C Enhancements\sto\sthe\sVDBE\sopcode\sloop\sto\sreduce\sthe\snumber\sof\smachine-code\ninstructions\sevaluated\sby\sabout\s10%.
|
||||
D 2009-11-17T23:59:58
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 53f3dfa49f28ab5b80cb083fb7c9051e596bcfa1
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -210,7 +210,7 @@ F src/update.c 8efeb09822886e33c265dd96d29a3d865ea6dcf2
|
||||
F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052
|
||||
F src/util.c ad4f03079ba0fe83590d1cc9197e8e4844e38592
|
||||
F src/vacuum.c 03309a08d549f9389cc3a3589afd4fadbdaf0679
|
||||
F src/vdbe.c 678dc437014c654707b7980e5a1a76b7dea5fecd
|
||||
F src/vdbe.c ed60d48b50b0e21f3ff87936f5c3d5667d4f8b8b
|
||||
F src/vdbe.h 5f35750615163d1064052785b4a9f0eb004a720d
|
||||
F src/vdbeInt.h d7ea821ac7813c9bea0fe87558c35e07b2c7c44d
|
||||
F src/vdbeapi.c 17680ab7a75ec938c5ba039a6c87489d01faf2cb
|
||||
@ -771,14 +771,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P e4943adb83819dee06e2e9da25ff6d967ca170de
|
||||
R 537d50eb63e21c879029e20006a4ef86
|
||||
P ebb0c8a3e977dc741704e733b5a5d931d9b27028
|
||||
R dad6cdc4c4a1dec37df2a9a1ce7926da
|
||||
U drh
|
||||
Z 25f5f894370572ec60a402b96fc8f463
|
||||
Z 1249a61e88d85d90c0245acb22f5c40f
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||
|
||||
iD8DBQFLAuwXoxKgR168RlERAvfhAJ9lIC9tv6mdYLAjmFMbVFDbfsV4pQCdFA1+
|
||||
c0IYZzkLkFY6S76oMkFaA2k=
|
||||
=BCOF
|
||||
iD8DBQFLAzkBoxKgR168RlERApdIAJ4+6zJDY9FY78sInSHpbNE0CiUriQCeMvQr
|
||||
4Rd5fpIsbKIZ9/+W9YH/eYE=
|
||||
=va/T
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -1 +1 @@
|
||||
ebb0c8a3e977dc741704e733b5a5d931d9b27028
|
||||
9744ffb3f5bc6d8fd59fbb6577a0d549411cd967
|
157
src/vdbe.c
157
src/vdbe.c
@ -543,7 +543,6 @@ int sqlite3VdbeExec(
|
||||
int rc = SQLITE_OK; /* Value to return */
|
||||
sqlite3 *db = p->db; /* The database */
|
||||
u8 encoding = ENC(db); /* The database encoding */
|
||||
u8 opProperty;
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
u8 checkProgress; /* True if progress callbacks are enabled */
|
||||
int nProgressOps = 0; /* Opcodes executed since progress callback. */
|
||||
@ -660,47 +659,46 @@ int sqlite3VdbeExec(
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do common setup processing for any opcode that is marked
|
||||
** with the "out2-prerelease" tag. Such opcodes have a single
|
||||
** output which is specified by the P2 parameter. The P2 register
|
||||
** is initialized to a NULL.
|
||||
/* On any opcode with the "out2-prerelase" tag, free any
|
||||
** external allocations out of mem[p2] and set mem[p2] to be
|
||||
** an undefined integer. Opcodes will either fill in the integer
|
||||
** value or convert mem[p2] to a different type.
|
||||
*/
|
||||
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
|
||||
opProperty = pOp->opflags;
|
||||
if( opProperty & (OPFLG_OUT2_PRERELEASE | OPFLG_IN1 | OPFLG_IN2
|
||||
| OPFLG_IN3 | OPFLG_OUT2 | OPFLG_OUT3)
|
||||
){
|
||||
if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=p->nMem );
|
||||
pOut = &aMem[pOp->p2];
|
||||
sqlite3VdbeMemReleaseExternal(pOut);
|
||||
pOut->flags = MEM_Null;
|
||||
pOut->n = 0;
|
||||
}else{
|
||||
if( (opProperty & OPFLG_IN1)!=0 ){
|
||||
assert( pOp->p1>0 );
|
||||
assert( pOp->p1<=p->nMem );
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
REGISTER_TRACE(pOp->p1, pIn1);
|
||||
}
|
||||
if( (opProperty & (OPFLG_IN2|OPFLG_OUT2))!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=p->nMem );
|
||||
assert( (opProperty & OPFLG_OUT2)==0 || (opProperty & OPFLG_IN3)==0 );
|
||||
pIn2 = pOut = &aMem[pOp->p2];
|
||||
}
|
||||
if( (opProperty & (OPFLG_IN3|OPFLG_OUT3))!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=p->nMem );
|
||||
pIn3 = pOut = &aMem[pOp->p3];
|
||||
}
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( opProperty & OPFLG_IN2 ){ REGISTER_TRACE(pOp->p2, pIn2); }
|
||||
if( opProperty & OPFLG_IN3 ){ REGISTER_TRACE(pOp->p3, pIn3); }
|
||||
#endif
|
||||
}
|
||||
if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=p->nMem );
|
||||
pOut = &aMem[pOp->p2];
|
||||
sqlite3VdbeMemReleaseExternal(pOut);
|
||||
pOut->flags = MEM_Int;
|
||||
}
|
||||
|
||||
/* Sanity checking on other operands */
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( (pOp->opflags & OPFLG_IN1)!=0 ){
|
||||
assert( pOp->p1>0 );
|
||||
assert( pOp->p1<=p->nMem );
|
||||
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_IN2)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=p->nMem );
|
||||
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_IN3)!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=p->nMem );
|
||||
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=p->nMem );
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=p->nMem );
|
||||
}
|
||||
#endif
|
||||
|
||||
switch( pOp->opcode ){
|
||||
|
||||
@ -758,6 +756,7 @@ case OP_Goto: { /* jump */
|
||||
** and then jump to address P2.
|
||||
*/
|
||||
case OP_Gosub: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( (pIn1->flags & MEM_Dyn)==0 );
|
||||
pIn1->flags = MEM_Int;
|
||||
pIn1->u.i = pc;
|
||||
@ -771,6 +770,7 @@ case OP_Gosub: { /* jump, in1 */
|
||||
** Jump to the next instruction after the address in register P1.
|
||||
*/
|
||||
case OP_Return: { /* in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags & MEM_Int );
|
||||
pc = (int)pIn1->u.i;
|
||||
break;
|
||||
@ -782,6 +782,7 @@ case OP_Return: { /* in1 */
|
||||
*/
|
||||
case OP_Yield: { /* in1 */
|
||||
int pcDest;
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( (pIn1->flags & MEM_Dyn)==0 );
|
||||
pIn1->flags = MEM_Int;
|
||||
pcDest = (int)pIn1->u.i;
|
||||
@ -798,6 +799,7 @@ case OP_Yield: { /* in1 */
|
||||
** value in register P3 is not NULL, then this routine is a no-op.
|
||||
*/
|
||||
case OP_HaltIfNull: { /* in3 */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
if( (pIn3->flags & MEM_Null)==0 ) break;
|
||||
/* Fall through into OP_Halt */
|
||||
}
|
||||
@ -865,7 +867,6 @@ case OP_Halt: {
|
||||
** The 32-bit integer value P1 is written into register P2.
|
||||
*/
|
||||
case OP_Integer: { /* out2-prerelease */
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = pOp->p1;
|
||||
break;
|
||||
}
|
||||
@ -877,7 +878,6 @@ case OP_Integer: { /* out2-prerelease */
|
||||
*/
|
||||
case OP_Int64: { /* out2-prerelease */
|
||||
assert( pOp->p4.pI64!=0 );
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = *pOp->p4.pI64;
|
||||
break;
|
||||
}
|
||||
@ -947,6 +947,7 @@ case OP_String: { /* out2-prerelease */
|
||||
** Write a NULL into register P2.
|
||||
*/
|
||||
case OP_Null: { /* out2-prerelease */
|
||||
pOut->flags = MEM_Null;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1046,6 +1047,8 @@ case OP_Move: {
|
||||
** is made of any string or blob constant. See also OP_SCopy.
|
||||
*/
|
||||
case OP_Copy: { /* in1, out2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pOut = &aMem[pOp->p2];
|
||||
assert( pOut!=pIn1 );
|
||||
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
|
||||
Deephemeralize(pOut);
|
||||
@ -1066,6 +1069,8 @@ case OP_Copy: { /* in1, out2 */
|
||||
** copy.
|
||||
*/
|
||||
case OP_SCopy: { /* in1, out2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pOut = &aMem[pOp->p2];
|
||||
assert( pOut!=pIn1 );
|
||||
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
|
||||
REGISTER_TRACE(pOp->p2, pOut);
|
||||
@ -1154,6 +1159,9 @@ case OP_ResultRow: {
|
||||
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
|
||||
i64 nByte;
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
pOut = &aMem[pOp->p3];
|
||||
assert( pIn1!=pOut );
|
||||
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
@ -1227,8 +1235,11 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
||||
double rA; /* Real value of left operand */
|
||||
double rB; /* Real value of right operand */
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
applyNumericAffinity(pIn1);
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
applyNumericAffinity(pIn2);
|
||||
pOut = &aMem[pOp->p3];
|
||||
flags = pIn1->flags | pIn2->flags;
|
||||
if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
|
||||
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
|
||||
@ -1459,6 +1470,9 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
|
||||
i64 a;
|
||||
i64 b;
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
pOut = &aMem[pOp->p3];
|
||||
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
break;
|
||||
@ -1485,6 +1499,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
|
||||
** To force any register to be an integer, just add 0.
|
||||
*/
|
||||
case OP_AddImm: { /* in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
sqlite3VdbeMemIntegerify(pIn1);
|
||||
pIn1->u.i += pOp->p2;
|
||||
break;
|
||||
@ -1498,6 +1513,7 @@ case OP_AddImm: { /* in1 */
|
||||
** raise an SQLITE_MISMATCH exception.
|
||||
*/
|
||||
case OP_MustBeInt: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
|
||||
if( (pIn1->flags & MEM_Int)==0 ){
|
||||
if( pOp->p2==0 ){
|
||||
@ -1522,6 +1538,7 @@ case OP_MustBeInt: { /* jump, in1 */
|
||||
** to have only a real value.
|
||||
*/
|
||||
case OP_RealAffinity: { /* in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( pIn1->flags & MEM_Int ){
|
||||
sqlite3VdbeMemRealify(pIn1);
|
||||
}
|
||||
@ -1539,6 +1556,7 @@ case OP_RealAffinity: { /* in1 */
|
||||
** A NULL value is not changed by this routine. It remains NULL.
|
||||
*/
|
||||
case OP_ToText: { /* same as TK_TO_TEXT, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( pIn1->flags & MEM_Null ) break;
|
||||
assert( MEM_Str==(MEM_Blob>>3) );
|
||||
pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
|
||||
@ -1560,6 +1578,7 @@ case OP_ToText: { /* same as TK_TO_TEXT, in1 */
|
||||
** A NULL value is not changed by this routine. It remains NULL.
|
||||
*/
|
||||
case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( pIn1->flags & MEM_Null ) break;
|
||||
if( (pIn1->flags & MEM_Blob)==0 ){
|
||||
applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
|
||||
@ -1583,6 +1602,7 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */
|
||||
** A NULL value is not changed by this routine. It remains NULL.
|
||||
*/
|
||||
case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){
|
||||
sqlite3VdbeMemNumerify(pIn1);
|
||||
}
|
||||
@ -1600,6 +1620,7 @@ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */
|
||||
** A NULL value is not changed by this routine. It remains NULL.
|
||||
*/
|
||||
case OP_ToInt: { /* same as TK_TO_INT, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( (pIn1->flags & MEM_Null)==0 ){
|
||||
sqlite3VdbeMemIntegerify(pIn1);
|
||||
}
|
||||
@ -1617,6 +1638,7 @@ case OP_ToInt: { /* same as TK_TO_INT, in1 */
|
||||
** A NULL value is not changed by this routine. It remains NULL.
|
||||
*/
|
||||
case OP_ToReal: { /* same as TK_TO_REAL, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( (pIn1->flags & MEM_Null)==0 ){
|
||||
sqlite3VdbeMemRealify(pIn1);
|
||||
}
|
||||
@ -1705,6 +1727,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
int res; /* Result of the comparison of pIn1 against pIn3 */
|
||||
char affinity; /* Affinity to use for comparison */
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
if( (pIn1->flags | pIn3->flags)&MEM_Null ){
|
||||
/* One or both operands are NULL */
|
||||
if( pOp->p5 & SQLITE_NULLEQ ){
|
||||
@ -1876,11 +1900,13 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
||||
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
||||
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( pIn1->flags & MEM_Null ){
|
||||
v1 = 2;
|
||||
}else{
|
||||
v1 = sqlite3VdbeIntValue(pIn1)!=0;
|
||||
}
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
if( pIn2->flags & MEM_Null ){
|
||||
v2 = 2;
|
||||
}else{
|
||||
@ -1893,6 +1919,7 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
||||
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
|
||||
v1 = or_logic[v1*3+v2];
|
||||
}
|
||||
pOut = &aMem[pOp->p3];
|
||||
if( v1==2 ){
|
||||
MemSetTypeFlag(pOut, MEM_Null);
|
||||
}else{
|
||||
@ -1909,6 +1936,8 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
||||
** NULL, then a NULL is stored in P2.
|
||||
*/
|
||||
case OP_Not: { /* same as TK_NOT, in1, out2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pOut = &aMem[pOp->p2];
|
||||
if( pIn1->flags & MEM_Null ){
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
}else{
|
||||
@ -1924,6 +1953,8 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */
|
||||
** a NULL then store a NULL in P2.
|
||||
*/
|
||||
case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pOut = &aMem[pOp->p2];
|
||||
if( pIn1->flags & MEM_Null ){
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
}else{
|
||||
@ -1947,6 +1978,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
|
||||
case OP_If: /* jump, in1 */
|
||||
case OP_IfNot: { /* jump, in1 */
|
||||
int c;
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( pIn1->flags & MEM_Null ){
|
||||
c = pOp->p3;
|
||||
}else{
|
||||
@ -1968,6 +2000,7 @@ case OP_IfNot: { /* jump, in1 */
|
||||
** Jump to P2 if the value in register P1 is NULL.
|
||||
*/
|
||||
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( (pIn1->flags & MEM_Null)!=0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
@ -1979,6 +2012,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
|
||||
** Jump to P2 if the value in register P1 is not NULL.
|
||||
*/
|
||||
case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( (pIn1->flags & MEM_Null)==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
@ -2456,7 +2490,6 @@ case OP_Count: { /* out2-prerelease */
|
||||
}else{
|
||||
nEntry = 0;
|
||||
}
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = nEntry;
|
||||
break;
|
||||
}
|
||||
@ -2777,7 +2810,6 @@ case OP_ReadCookie: { /* out2-prerelease */
|
||||
|
||||
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
|
||||
pOut->u.i = iMeta;
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2798,6 +2830,7 @@ case OP_SetCookie: { /* in3 */
|
||||
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
|
||||
pDb = &db->aDb[pOp->p1];
|
||||
assert( pDb->pBt!=0 );
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
sqlite3VdbeMemIntegerify(pIn3);
|
||||
/* See note about index shifting on OP_ReadCookie */
|
||||
rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i);
|
||||
@ -3182,6 +3215,7 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
/* The input value in P3 might be of any type: integer, real, string,
|
||||
** blob, or NULL. But it needs to be an integer before we can do
|
||||
** the seek, so covert it. */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
applyNumericAffinity(pIn3);
|
||||
iKey = sqlite3VdbeIntValue(pIn3);
|
||||
pC->rowidIsValid = 0;
|
||||
@ -3321,6 +3355,7 @@ case OP_Seek: { /* in2 */
|
||||
if( ALWAYS(pC->pCursor!=0) ){
|
||||
assert( pC->isTable );
|
||||
pC->nullRow = 0;
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
|
||||
pC->rowidIsValid = 0;
|
||||
pC->deferredMoveto = 1;
|
||||
@ -3371,6 +3406,7 @@ case OP_Found: { /* jump, in3 */
|
||||
assert( pOp->p4type==P4_INT32 );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
if( ALWAYS(pC->pCursor!=0) ){
|
||||
|
||||
assert( pC->isTable==0 );
|
||||
@ -3444,6 +3480,7 @@ case OP_IsUnique: { /* jump, in3 */
|
||||
UnpackedRecord r; /* B-Tree index search key */
|
||||
i64 R; /* Rowid stored in register P3 */
|
||||
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
aMx = &aMem[pOp->p4.i];
|
||||
/* Assert that the values of parameters P1 and P4 are in range. */
|
||||
assert( pOp->p4type==P4_INT32 );
|
||||
@ -3512,6 +3549,7 @@ case OP_NotExists: { /* jump, in3 */
|
||||
int res;
|
||||
u64 iKey;
|
||||
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
assert( pIn3->flags & MEM_Int );
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
@ -3555,7 +3593,6 @@ case OP_Sequence: { /* out2-prerelease */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
assert( p->apCsr[pOp->p1]!=0 );
|
||||
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3692,7 +3729,6 @@ case OP_NewRowid: { /* out2-prerelease */
|
||||
pC->deferredMoveto = 0;
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
}
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
pOut->u.i = v;
|
||||
break;
|
||||
}
|
||||
@ -3984,7 +4020,7 @@ case OP_Rowid: { /* out2-prerelease */
|
||||
assert( pC!=0 );
|
||||
assert( pC->pseudoTableReg==0 );
|
||||
if( pC->nullRow ){
|
||||
/* Do nothing so that reg[P2] remains NULL */
|
||||
pOut->flags = MEM_Null;
|
||||
break;
|
||||
}else if( pC->deferredMoveto ){
|
||||
v = pC->movetoTarget;
|
||||
@ -4012,7 +4048,6 @@ case OP_Rowid: { /* out2-prerelease */
|
||||
}
|
||||
}
|
||||
pOut->u.i = v;
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4197,6 +4232,7 @@ case OP_IdxInsert: { /* in2 */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
assert( pIn2->flags & MEM_Blob );
|
||||
pCrsr = pC->pCursor;
|
||||
if( ALWAYS(pCrsr!=0) ){
|
||||
@ -4265,6 +4301,7 @@ case OP_IdxRowid: { /* out2-prerelease */
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
pCrsr = pC->pCursor;
|
||||
pOut->flags = MEM_Null;
|
||||
if( ALWAYS(pCrsr!=0) ){
|
||||
rc = sqlite3VdbeCursorMoveto(pC);
|
||||
if( NEVER(rc) ) goto abort_due_to_error;
|
||||
@ -4275,8 +4312,8 @@ case OP_IdxRowid: { /* out2-prerelease */
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
pOut->u.i = rowid;
|
||||
pOut->flags = MEM_Int;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4378,6 +4415,7 @@ case OP_Destroy: { /* out2-prerelease */
|
||||
#else
|
||||
iCnt = db->activeVdbeCnt;
|
||||
#endif
|
||||
pOut->flags = MEM_Null;
|
||||
if( iCnt>1 ){
|
||||
rc = SQLITE_LOCKED;
|
||||
p->errorAction = OE_Abort;
|
||||
@ -4386,7 +4424,7 @@ case OP_Destroy: { /* out2-prerelease */
|
||||
assert( iCnt==1 );
|
||||
assert( (p->btreeMask & (1<<iDb))!=0 );
|
||||
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = iMoved;
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
if( rc==SQLITE_OK && iMoved!=0 ){
|
||||
@ -4473,7 +4511,6 @@ case OP_CreateTable: { /* out2-prerelease */
|
||||
}
|
||||
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
|
||||
pOut->u.i = pgno;
|
||||
MemSetTypeFlag(pOut, MEM_Int);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4672,6 +4709,8 @@ case OP_IntegrityCk: {
|
||||
** An assertion fails if P2 is not an integer.
|
||||
*/
|
||||
case OP_RowSetAdd: { /* in1, in2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
assert( (pIn2->flags & MEM_Int)!=0 );
|
||||
if( (pIn1->flags & MEM_RowSet)==0 ){
|
||||
sqlite3VdbeMemSetRowSet(pIn1);
|
||||
@ -4690,6 +4729,7 @@ case OP_RowSetAdd: { /* in1, in2 */
|
||||
case OP_RowSetRead: { /* jump, in1, out3 */
|
||||
i64 val;
|
||||
CHECK_FOR_INTERRUPT;
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( (pIn1->flags & MEM_RowSet)==0
|
||||
|| sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
|
||||
){
|
||||
@ -4698,7 +4738,7 @@ case OP_RowSetRead: { /* jump, in1, out3 */
|
||||
pc = pOp->p2 - 1;
|
||||
}else{
|
||||
/* A value was pulled from the index */
|
||||
sqlite3VdbeMemSetInt64(pOut, val);
|
||||
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4730,6 +4770,8 @@ case OP_RowSetTest: { /* jump, in1, in3 */
|
||||
int iSet;
|
||||
int exists;
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
iSet = pOp->p4.i;
|
||||
assert( pIn3->flags&MEM_Int );
|
||||
|
||||
@ -4956,6 +4998,7 @@ case OP_MemMax: { /* in2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
}
|
||||
sqlite3VdbeMemIntegerify(pIn1);
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
sqlite3VdbeMemIntegerify(pIn2);
|
||||
if( pIn1->u.i<pIn2->u.i){
|
||||
pIn1->u.i = pIn2->u.i;
|
||||
@ -4972,6 +5015,7 @@ case OP_MemMax: { /* in2 */
|
||||
** not contain an integer. An assertion fault will result if you try.
|
||||
*/
|
||||
case OP_IfPos: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
if( pIn1->u.i>0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
@ -4987,6 +5031,7 @@ case OP_IfPos: { /* jump, in1 */
|
||||
** not contain an integer. An assertion fault will result if you try.
|
||||
*/
|
||||
case OP_IfNeg: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
if( pIn1->u.i<0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
@ -5003,6 +5048,7 @@ case OP_IfNeg: { /* jump, in1 */
|
||||
** not contain an integer. An assertion fault will result if you try.
|
||||
*/
|
||||
case OP_IfZero: { /* jump, in1 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
assert( pIn1->flags&MEM_Int );
|
||||
pIn1->u.i += pOp->p3;
|
||||
if( pIn1->u.i==0 ){
|
||||
@ -5565,7 +5611,6 @@ case OP_Pagecount: { /* out2-prerelease */
|
||||
** page count has already been successfully read and cached. So the
|
||||
** sqlite3PagerPagecount() call above cannot fail. */
|
||||
if( ALWAYS(rc==SQLITE_OK) ){
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = nPage;
|
||||
}
|
||||
break;
|
||||
@ -5643,11 +5688,11 @@ default: { /* This is really OP_Noop and OP_Explain */
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->trace ){
|
||||
if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
|
||||
if( opProperty & OPFLG_OUT2_PRERELEASE ){
|
||||
registerTrace(p->trace, pOp->p2, pOut);
|
||||
if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
|
||||
registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]);
|
||||
}
|
||||
if( opProperty & OPFLG_OUT3 ){
|
||||
registerTrace(p->trace, pOp->p3, pOut);
|
||||
if( pOp->opflags & OPFLG_OUT3 ){
|
||||
registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
Loading…
Reference in New Issue
Block a user