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. */
}
#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];
- }
+ 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( opProperty & OPFLG_IN2 ){ REGISTER_TRACE(pOp->p2, pIn2); }
- if( opProperty & OPFLG_IN3 ){ REGISTER_TRACE(pOp->p3, pIn3); }
-#endif
- }
+ 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 ){
** 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;
** 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;
*/
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;
** 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 */
}
** 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;
}
*/
case OP_Int64: { /* out2-prerelease */
assert( pOp->p4.pI64!=0 );
- pOut->flags = MEM_Int;
pOut->u.i = *pOp->p4.pI64;
break;
}
** Write a NULL into register P2.
*/
case OP_Null: { /* out2-prerelease */
+ pOut->flags = MEM_Null;
break;
}
** 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);
** 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);
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);
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 ){
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;
** 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;
** 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 ){
** to have only a real value.
*/
case OP_RealAffinity: { /* in1 */
+ pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Int ){
sqlite3VdbeMemRealify(pIn1);
}
** 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;
** 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);
** 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);
}
** 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);
}
** 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);
}
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 ){
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{
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{
** 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{
** 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{
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{
** 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;
}
** 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;
}
}else{
nEntry = 0;
}
- pOut->flags = MEM_Int;
pOut->u.i = nEntry;
break;
}
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
pOut->u.i = iMeta;
- MemSetTypeFlag(pOut, MEM_Int);
break;
}
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);
/* 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;
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;
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 );
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 );
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];
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;
}
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
- MemSetTypeFlag(pOut, MEM_Int);
pOut->u.i = v;
break;
}
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;
}
}
pOut->u.i = v;
- MemSetTypeFlag(pOut, MEM_Int);
break;
}
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) ){
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;
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- MemSetTypeFlag(pOut, MEM_Int);
pOut->u.i = rowid;
+ pOut->flags = MEM_Int;
}
}
break;
#else
iCnt = db->activeVdbeCnt;
#endif
+ pOut->flags = MEM_Null;
if( iCnt>1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
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 ){
}
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
pOut->u.i = pgno;
- MemSetTypeFlag(pOut, MEM_Int);
break;
}
** 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);
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
){
pc = pOp->p2 - 1;
}else{
/* A value was pulled from the index */
- sqlite3VdbeMemSetInt64(pOut, val);
+ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
}
break;
}
int iSet;
int exists;
+ pIn1 = &aMem[pOp->p1];
+ pIn3 = &aMem[pOp->p3];
iSet = pOp->p4.i;
assert( pIn3->flags&MEM_Int );
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;
** 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;
** 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;
** 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 ){
** 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;
#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 */