summaryrefslogtreecommitdiffstats
path: root/lib/libsqlite3/src/vdbe.c
diff options
context:
space:
mode:
authorjturner <jturner@openbsd.org>2015-09-12 02:08:34 +0000
committerjturner <jturner@openbsd.org>2015-09-12 02:08:34 +0000
commit9002a9ec67ed1654a017252f6e4bc93deef91d2a (patch)
tree775f5d1fe0cf77f56c7617f4e867764206a537c7 /lib/libsqlite3/src/vdbe.c
parentadd missing functions to NAME; (diff)
downloadwireguard-openbsd-9002a9ec67ed1654a017252f6e4bc93deef91d2a.tar.xz
wireguard-openbsd-9002a9ec67ed1654a017252f6e4bc93deef91d2a.zip
Update sqlite3 to 3.8.11.1. Bump major, regen .pc and header. Changes
available here: http://sqlite.org/changes.html Tested in bulk by aja@. ok landry@ "Please crank sqlite when you get this mail." deraadt@
Diffstat (limited to 'lib/libsqlite3/src/vdbe.c')
-rw-r--r--lib/libsqlite3/src/vdbe.c662
1 files changed, 378 insertions, 284 deletions
diff --git a/lib/libsqlite3/src/vdbe.c b/lib/libsqlite3/src/vdbe.c
index f2de90d14c1..fe97087c098 100644
--- a/lib/libsqlite3/src/vdbe.c
+++ b/lib/libsqlite3/src/vdbe.c
@@ -270,7 +270,7 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
** SQLITE_AFF_TEXT:
** Convert pRec to a text representation.
**
-** SQLITE_AFF_NONE:
+** SQLITE_AFF_BLOB:
** No-op. pRec is unchanged.
*/
static void applyAffinity(
@@ -296,6 +296,7 @@ static void applyAffinity(
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
sqlite3VdbeMemStringify(pRec, enc, 1);
}
+ pRec->flags &= ~(MEM_Real|MEM_Int);
}
}
@@ -514,6 +515,21 @@ static int checkSavepointCount(sqlite3 *db){
}
#endif
+/*
+** Return the register of pOp->p2 after first preparing it to be
+** overwritten with an integer value.
+*/
+static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
+ Mem *pOut;
+ assert( pOp->p2>0 );
+ assert( pOp->p2<=(p->nMem-p->nCursor) );
+ pOut = &p->aMem[pOp->p2];
+ memAboutToChange(p, pOut);
+ if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
+ pOut->flags = MEM_Int;
+ return pOut;
+}
+
/*
** Execute as much of a VDBE program as we can.
@@ -522,9 +538,11 @@ static int checkSavepointCount(sqlite3 *db){
int sqlite3VdbeExec(
Vdbe *p /* The VDBE */
){
- int pc=0; /* The program counter */
Op *aOp = p->aOp; /* Copy of p->aOp */
- Op *pOp; /* Current operation */
+ Op *pOp = aOp; /* Current operation */
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ Op *pOrigOp; /* Value of pOp at the top of the loop */
+#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
@@ -564,13 +582,9 @@ int sqlite3VdbeExec(
sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( db->xProgress ){
+ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
assert( 0 < db->nProgressOps );
- nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
- if( nProgressLimit==0 ){
- nProgressLimit = db->nProgressOps;
- }else{
- nProgressLimit %= (unsigned)db->nProgressOps;
- }
+ nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
}
#endif
#ifdef SQLITE_DEBUG
@@ -600,23 +614,22 @@ int sqlite3VdbeExec(
}
sqlite3EndBenignMalloc();
#endif
- for(pc=p->pc; rc==SQLITE_OK; pc++){
- assert( pc>=0 && pc<p->nOp );
+ for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
+ assert( pOp>=aOp && pOp<&aOp[p->nOp]);
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
start = sqlite3Hwtime();
#endif
nVmStep++;
- pOp = &aOp[pc];
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- if( p->anExec ) p->anExec[pc]++;
+ if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
#endif
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
- sqlite3VdbePrintOp(stdout, pc, pOp);
+ sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
}
#endif
@@ -633,23 +646,9 @@ int sqlite3VdbeExec(
}
#endif
- /* On any opcode with the "out2-prerelease" 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] );
- if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=(p->nMem-p->nCursor) );
- pOut = &aMem[pOp->p2];
- memAboutToChange(p, pOut);
- if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
- pOut->flags = MEM_Int;
- }
-
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
+ assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
@@ -682,6 +681,9 @@ int sqlite3VdbeExec(
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ pOrigOp = pOp;
+#endif
switch( pOp->opcode ){
@@ -705,7 +707,7 @@ int sqlite3VdbeExec(
**
** Other keywords in the comment that follows each case are used to
** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
-** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See
+** Keywords include: in1, in2, in3, out2, out3. See
** the mkopcodeh.awk script for additional information.
**
** Documentation about VDBE opcodes is generated by scanning this file
@@ -733,7 +735,8 @@ int sqlite3VdbeExec(
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
- pc = pOp->p2 - 1;
+jump_to_p2_and_check_for_interrupt:
+ pOp = &aOp[pOp->p2 - 1];
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
@@ -778,9 +781,13 @@ case OP_Gosub: { /* jump */
assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
- pIn1->u.i = pc;
+ pIn1->u.i = (int)(pOp-aOp);
REGISTER_TRACE(pOp->p1, pIn1);
- pc = pOp->p2 - 1;
+
+ /* Most jump operations do a goto to this spot in order to update
+ ** the pOp pointer. */
+jump_to_p2:
+ pOp = &aOp[pOp->p2 - 1];
break;
}
@@ -792,7 +799,7 @@ case OP_Gosub: { /* jump */
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags==MEM_Int );
- pc = (int)pIn1->u.i;
+ pOp = &aOp[pIn1->u.i];
pIn1->flags = MEM_Undefined;
break;
}
@@ -816,7 +823,7 @@ case OP_InitCoroutine: { /* jump */
assert( !VdbeMemDynamic(pOut) );
pOut->u.i = pOp->p3 - 1;
pOut->flags = MEM_Int;
- if( pOp->p2 ) pc = pOp->p2 - 1;
+ if( pOp->p2 ) goto jump_to_p2;
break;
}
@@ -836,7 +843,7 @@ case OP_EndCoroutine: { /* in1 */
pCaller = &aOp[pIn1->u.i];
assert( pCaller->opcode==OP_Yield );
assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
- pc = pCaller->p2 - 1;
+ pOp = &aOp[pCaller->p2 - 1];
pIn1->flags = MEM_Undefined;
break;
}
@@ -860,9 +867,9 @@ case OP_Yield: { /* in1, jump */
assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
pcDest = (int)pIn1->u.i;
- pIn1->u.i = pc;
+ pIn1->u.i = (int)(pOp - aOp);
REGISTER_TRACE(pOp->p1, pIn1);
- pc = pcDest;
+ pOp = &aOp[pcDest];
break;
}
@@ -913,30 +920,34 @@ case OP_HaltIfNull: { /* in3 */
case OP_Halt: {
const char *zType;
const char *zLogFmt;
+ VdbeFrame *pFrame;
+ int pcx;
+ pcx = (int)(pOp - aOp);
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
- VdbeFrame *pFrame = p->pFrame;
+ pFrame = p->pFrame;
p->pFrame = pFrame->pParent;
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
- pc = sqlite3VdbeFrameRestore(pFrame);
+ pcx = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
+ /* Instruction pcx is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified
** as the p2 of the calling OP_Program. */
- pc = p->aOp[pc].p2-1;
+ pcx = p->aOp[pcx].p2-1;
}
aOp = p->aOp;
aMem = p->aMem;
+ pOp = &aOp[pcx];
break;
}
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
- p->pc = pc;
+ p->pc = pcx;
if( p->rc ){
if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
@@ -953,14 +964,13 @@ case OP_Halt: {
assert( zType!=0 || pOp->p4.z!=0 );
zLogFmt = "abort at %d in [%s]: %s";
if( zType && pOp->p4.z ){
- sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
- zType, pOp->p4.z);
+ sqlite3VdbeError(p, "%s constraint failed: %s", zType, pOp->p4.z);
}else if( pOp->p4.z ){
- sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
+ sqlite3VdbeError(p, "%s", pOp->p4.z);
}else{
- sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
+ sqlite3VdbeError(p, "%s constraint failed", zType);
}
- sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg);
+ sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -979,7 +989,8 @@ case OP_Halt: {
**
** The 32-bit integer value P1 is written into register P2.
*/
-case OP_Integer: { /* out2-prerelease */
+case OP_Integer: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p1;
break;
}
@@ -990,7 +1001,8 @@ case OP_Integer: { /* out2-prerelease */
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
-case OP_Int64: { /* out2-prerelease */
+case OP_Int64: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64;
break;
@@ -1003,7 +1015,8 @@ case OP_Int64: { /* out2-prerelease */
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
*/
-case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
+case OP_Real: { /* same as TK_FLOAT, out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->u.r = *pOp->p4.pReal;
@@ -1019,8 +1032,9 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
** this transformation, the length of string P4 is computed and stored
** as the P1 parameter.
*/
-case OP_String8: { /* same as TK_STRING, out2-prerelease */
+case OP_String8: { /* same as TK_STRING, out2 */
assert( pOp->p4.z!=0 );
+ pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
@@ -1057,8 +1071,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
** the same sequence of bytes, it is merely interpreted as a BLOB instead
** of a string, as if it had been CAST.
*/
-case OP_String: { /* out2-prerelease */
+case OP_String: { /* out2 */
assert( pOp->p4.z!=0 );
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = pOp->p4.z;
pOut->n = pOp->p1;
@@ -1086,9 +1101,10 @@ case OP_String: { /* out2-prerelease */
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
-case OP_Null: { /* out2-prerelease */
+case OP_Null: { /* out2 */
int cnt;
u16 nullFlag;
+ pOut = out2Prerelease(p, pOp);
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
@@ -1123,8 +1139,9 @@ case OP_SoftNull: {
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
-case OP_Blob: { /* out2-prerelease */
+case OP_Blob: { /* out2 */
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
+ pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
@@ -1139,7 +1156,7 @@ case OP_Blob: { /* out2-prerelease */
** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
-case OP_Variable: { /* out2-prerelease */
+case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
@@ -1148,6 +1165,7 @@ case OP_Variable: { /* out2-prerelease */
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
+ pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
@@ -1182,10 +1200,11 @@ case OP_Move: {
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
- pOut->pScopyFrom += p1 - pOp->p2;
+ if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
+ pOut->pScopyFrom += pOp->p2 - p1;
}
#endif
+ Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
pIn1++;
pOut++;
@@ -1324,7 +1343,7 @@ case OP_ResultRow: {
/* Return SQLITE_ROW
*/
- p->pc = pc + 1;
+ p->pc = (int)(pOp - aOp) + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
@@ -1527,10 +1546,10 @@ case OP_CollSeq: {
break;
}
-/* Opcode: Function P1 P2 P3 P4 P5
+/* Opcode: Function0 P1 P2 P3 P4 P5
** Synopsis: r[P3]=func(r[P2@P5])
**
-** Invoke a user function (P4 is a pointer to a Function structure that
+** Invoke a user function (P4 is a pointer to a FuncDef object that
** defines the function) with P5 arguments taken from register P2 and
** successors. The result of the function is stored in register P3.
** Register P3 must not be one of the function inputs.
@@ -1542,59 +1561,100 @@ case OP_CollSeq: {
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
-** See also: AggStep and AggFinal
+** See also: Function, AggStep, AggFinal
*/
-case OP_Function: {
- int i;
- Mem *pArg;
- sqlite3_context ctx;
- sqlite3_value **apVal;
+/* Opcode: Function P1 P2 P3 P4 P5
+** Synopsis: r[P3]=func(r[P2@P5])
+**
+** Invoke a user function (P4 is a pointer to an sqlite3_context object that
+** contains a pointer to the function to be run) with P5 arguments taken
+** from register P2 and successors. The result of the function is stored
+** in register P3. Register P3 must not be one of the function inputs.
+**
+** P1 is a 32-bit bitmask indicating whether or not each argument to the
+** function was determined to be constant at compile time. If the first
+** argument was constant then bit 0 of P1 is set. This is used to determine
+** whether meta data associated with a user function argument using the
+** sqlite3_set_auxdata() API may be safely retained until the next
+** invocation of this opcode.
+**
+** SQL functions are initially coded as OP_Function0 with P4 pointing
+** to a FuncDef object. But on first evaluation, the P4 operand is
+** automatically converted into an sqlite3_context object and the operation
+** changed to this OP_Function opcode. In this way, the initialization of
+** the sqlite3_context object occurs only once, rather than once for each
+** evaluation of the function.
+**
+** See also: Function0, AggStep, AggFinal
+*/
+case OP_Function0: {
int n;
+ sqlite3_context *pCtx;
+ assert( pOp->p4type==P4_FUNCDEF );
n = pOp->p5;
- apVal = p->apArg;
- assert( apVal || n==0 );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- ctx.pOut = &aMem[pOp->p3];
- memAboutToChange(p, ctx.pOut);
-
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
- pArg = &aMem[pOp->p2];
- for(i=0; i<n; i++, pArg++){
- assert( memIsValid(pArg) );
- apVal[i] = pArg;
- Deephemeralize(pArg);
- REGISTER_TRACE(pOp->p2+i, pArg);
+ pCtx = sqlite3DbMallocRaw(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
+ if( pCtx==0 ) goto no_mem;
+ pCtx->pOut = 0;
+ pCtx->pFunc = pOp->p4.pFunc;
+ pCtx->iOp = (int)(pOp - aOp);
+ pCtx->pVdbe = p;
+ pCtx->argc = n;
+ pOp->p4type = P4_FUNCCTX;
+ pOp->p4.pCtx = pCtx;
+ pOp->opcode = OP_Function;
+ /* Fall through into OP_Function */
+}
+case OP_Function: {
+ int i;
+ sqlite3_context *pCtx;
+
+ assert( pOp->p4type==P4_FUNCCTX );
+ pCtx = pOp->p4.pCtx;
+
+ /* If this function is inside of a trigger, the register array in aMem[]
+ ** might change from one evaluation to the next. The next block of code
+ ** checks to see if the register array has changed, and if so it
+ ** reinitializes the relavant parts of the sqlite3_context object */
+ pOut = &aMem[pOp->p3];
+ if( pCtx->pOut != pOut ){
+ pCtx->pOut = pOut;
+ for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
- assert( pOp->p4type==P4_FUNCDEF );
- ctx.pFunc = pOp->p4.pFunc;
- ctx.iOp = pc;
- ctx.pVdbe = p;
- MemSetTypeFlag(ctx.pOut, MEM_Null);
- ctx.fErrorOrAux = 0;
+ memAboutToChange(p, pCtx->pOut);
+#ifdef SQLITE_DEBUG
+ for(i=0; i<pCtx->argc; i++){
+ assert( memIsValid(pCtx->argv[i]) );
+ REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
+ }
+#endif
+ MemSetTypeFlag(pCtx->pOut, MEM_Null);
+ pCtx->fErrorOrAux = 0;
db->lastRowid = lastRowid;
- (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
+ (*pCtx->pFunc->xFunc)(pCtx, pCtx->argc, pCtx->argv); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
/* If the function returned an error, throw an exception */
- if( ctx.fErrorOrAux ){
- if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
- rc = ctx.isError;
+ if( pCtx->fErrorOrAux ){
+ if( pCtx->isError ){
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
+ rc = pCtx->isError;
}
- sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
+ sqlite3VdbeDeleteAuxData(p, pCtx->iOp, pOp->p1);
}
/* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(ctx.pOut, encoding);
- if( sqlite3VdbeMemTooBig(ctx.pOut) ){
- goto too_big;
+ if( pOut->flags & (MEM_Str|MEM_Blob) ){
+ sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
+ if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
}
- REGISTER_TRACE(pOp->p3, ctx.pOut);
- UPDATE_MAX_BLOBSIZE(ctx.pOut);
+ REGISTER_TRACE(pOp->p3, pCtx->pOut);
+ UPDATE_MAX_BLOBSIZE(pCtx->pOut);
break;
}
@@ -1713,8 +1773,7 @@ case OP_MustBeInt: { /* jump, in1 */
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
- pc = pOp->p2 - 1;
- break;
+ goto jump_to_p2;
}
}
}
@@ -1758,9 +1817,9 @@ case OP_RealAffinity: { /* in1 */
** A NULL value is not changed by this routine. It remains NULL.
*/
case OP_Cast: { /* in1 */
- assert( pOp->p2>=SQLITE_AFF_NONE && pOp->p2<=SQLITE_AFF_REAL );
+ assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL );
testcase( pOp->p2==SQLITE_AFF_TEXT );
- testcase( pOp->p2==SQLITE_AFF_NONE );
+ testcase( pOp->p2==SQLITE_AFF_BLOB );
testcase( pOp->p2==SQLITE_AFF_NUMERIC );
testcase( pOp->p2==SQLITE_AFF_INTEGER );
testcase( pOp->p2==SQLITE_AFF_REAL );
@@ -1900,7 +1959,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}else{
VdbeBranchTaken(2,3);
if( pOp->p5 & SQLITE_JUMPIFNULL ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}
}
break;
@@ -1952,6 +2011,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
default: res = res>=0; break;
}
+ /* Undo any changes made by applyAffinity() to the input registers. */
+ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
+ pIn1->flags = flags1;
+ assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
+ pIn3->flags = flags3;
+
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
@@ -1961,14 +2026,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}else{
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}
}
- /* Undo any changes made by applyAffinity() to the input registers. */
- assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
- pIn1->flags = flags1;
- assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
- pIn3->flags = flags3;
break;
}
@@ -2063,11 +2123,11 @@ case OP_Compare: {
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
- pc = pOp->p1 - 1; VdbeBranchTaken(0,3);
+ VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
}else if( iCompare==0 ){
- pc = pOp->p2 - 1; VdbeBranchTaken(1,3);
+ VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
}else{
- pc = pOp->p3 - 1; VdbeBranchTaken(2,3);
+ VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
}
break;
}
@@ -2177,7 +2237,7 @@ case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}else{
p->aOnceFlag[pOp->p1] = 1;
}
@@ -2212,7 +2272,7 @@ case OP_IfNot: { /* jump, in1 */
}
VdbeBranchTaken(c!=0, 2);
if( c ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}
break;
}
@@ -2226,7 +2286,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
if( (pIn1->flags & MEM_Null)!=0 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
@@ -2240,7 +2300,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
if( (pIn1->flags & MEM_Null)==0 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
@@ -2454,7 +2514,7 @@ case OP_Column: {
}
}
- /* If after trying to extra new entries from the header, nHdrParsed is
+ /* If after trying to extract new entries from the header, nHdrParsed is
** still not up to p2, that means that the record has fewer than p2
** columns. So the result will be either the default value or a NULL.
*/
@@ -2570,7 +2630,7 @@ case OP_Affinity: {
** The mapping from character to affinity is given by the SQLITE_AFF_
** macros defined in sqliteInt.h.
**
-** If P4 is NULL then all index fields have the affinity NONE.
+** If P4 is NULL then all index fields have the affinity BLOB.
*/
case OP_MakeRecord: {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
@@ -2578,7 +2638,7 @@ case OP_MakeRecord: {
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
i64 nByte; /* Data space required for this record */
- int nZero; /* Number of zero bytes at the end of the record */
+ i64 nZero; /* Number of zero bytes at the end of the record */
int nVarint; /* Number of bytes in a varint */
u32 serial_type; /* Type field */
Mem *pData0; /* First field to be combined into the record */
@@ -2642,7 +2702,7 @@ case OP_MakeRecord: {
len = sqlite3VdbeSerialTypeLen(serial_type);
if( pRec->flags & MEM_Zero ){
if( nData ){
- sqlite3VdbeMemExpandBlob(pRec);
+ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
}else{
nZero += pRec->u.nZero;
len -= pRec->u.nZero;
@@ -2670,7 +2730,7 @@ case OP_MakeRecord: {
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
}
nByte = nHdr+nData;
- if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
@@ -2721,7 +2781,7 @@ case OP_MakeRecord: {
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
-case OP_Count: { /* out2-prerelease */
+case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
@@ -2729,6 +2789,7 @@ case OP_Count: { /* out2-prerelease */
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry);
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
}
@@ -2767,8 +2828,7 @@ case OP_Savepoint: {
/* A new savepoint cannot be created if there are active write
** statements (i.e. open read/write incremental blob handles).
*/
- sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
- "SQL statements in progress");
+ sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress");
rc = SQLITE_BUSY;
}else{
nName = sqlite3Strlen30(zName);
@@ -2819,15 +2879,14 @@ case OP_Savepoint: {
iSavepoint++;
}
if( !pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
+ sqlite3VdbeError(p, "no such savepoint: %s", zName);
rc = SQLITE_ERROR;
}else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
/* It is not possible to release (commit) a savepoint if there are
** active write statements.
*/
- sqlite3SetString(&p->zErrMsg, db,
- "cannot release savepoint - SQL statements in progress"
- );
+ sqlite3VdbeError(p, "cannot release savepoint - "
+ "SQL statements in progress");
rc = SQLITE_BUSY;
}else{
@@ -2842,7 +2901,7 @@ case OP_Savepoint: {
}
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
+ p->pc = (int)(pOp - aOp);
db->autoCommit = 0;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
@@ -2901,7 +2960,7 @@ case OP_Savepoint: {
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
- if( !isTransaction ){
+ if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
@@ -2933,23 +2992,12 @@ case OP_AutoCommit: {
assert( db->nVdbeActive>0 ); /* At least this one VM is active */
assert( p->bIsReader );
-#if 0
- if( turnOnAC && iRollback && db->nVdbeActive>1 ){
- /* If this instruction implements a ROLLBACK and other VMs are
- ** still running, and a transaction is active, return an error indicating
- ** that the other VMs must complete first.
- */
- sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- }else
-#endif
if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first.
*/
- sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
- "SQL statements in progress");
+ sqlite3VdbeError(p, "cannot commit transaction - "
+ "SQL statements in progress");
rc = SQLITE_BUSY;
}else if( desiredAutoCommit!=db->autoCommit ){
if( iRollback ){
@@ -2961,7 +3009,7 @@ case OP_AutoCommit: {
}else{
db->autoCommit = (u8)desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
+ p->pc = (int)(pOp - aOp);
db->autoCommit = (u8)(1-desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
@@ -2976,7 +3024,7 @@ case OP_AutoCommit: {
}
goto vdbe_return;
}else{
- sqlite3SetString(&p->zErrMsg, db,
+ sqlite3VdbeError(p,
(!desiredAutoCommit)?"cannot start a transaction within a transaction":(
(iRollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
@@ -3038,7 +3086,7 @@ case OP_Transaction: {
if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
- p->pc = pc;
+ p->pc = (int)(pOp - aOp);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
@@ -3117,7 +3165,7 @@ case OP_Transaction: {
** must be started or there must be an open cursor) before
** executing this instruction.
*/
-case OP_ReadCookie: { /* out2-prerelease */
+case OP_ReadCookie: { /* out2 */
int iMeta;
int iDb;
int iCookie;
@@ -3131,6 +3179,7 @@ case OP_ReadCookie: { /* out2-prerelease */
assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = iMeta;
break;
}
@@ -3452,7 +3501,7 @@ case OP_SequenceTest: {
pC = p->apCsr[pOp->p1];
assert( pC->pSorter );
if( (pC->seqCount++)==0 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
@@ -3499,6 +3548,26 @@ case OP_Close: {
break;
}
+#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
+/* Opcode: ColumnsUsed P1 * * P4 *
+**
+** This opcode (which only exists if SQLite was compiled with
+** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the
+** table or index for cursor P1 are used. P4 is a 64-bit integer
+** (P4_INT64) in which the first 63 bits are one for each of the
+** first 63 columns of the table or index that are actually used
+** by the cursor. The high-order bit is set if any column after
+** the 64th is used.
+*/
+case OP_ColumnsUsed: {
+ VdbeCursor *pC;
+ pC = p->apCsr[pOp->p1];
+ assert( pC->pCursor );
+ pC->maskUsed = *(u64*)pOp->p4.pI64;
+ break;
+}
+#endif
+
/* Opcode: SeekGE P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
@@ -3629,7 +3698,7 @@ case OP_SeekGT: { /* jump, in3 */
if( (pIn3->flags & MEM_Real)==0 ){
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
- pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
+ VdbeBranchTaken(1,2); goto jump_to_p2;
break;
}
@@ -3720,7 +3789,7 @@ case OP_SeekGT: { /* jump, in3 */
assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2);
if( res ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
@@ -3814,6 +3883,7 @@ case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
int alreadyExists;
+ int takeJump;
int ii;
VdbeCursor *pC;
int res;
@@ -3836,7 +3906,7 @@ case OP_Found: { /* jump, in3 */
pIn3 = &aMem[pOp->p3];
assert( pC->pCursor!=0 );
assert( pC->isTable==0 );
- pFree = 0; /* Not needed. Only used to suppress a compiler warning. */
+ pFree = 0;
if( pOp->p4.i>0 ){
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
@@ -3859,21 +3929,20 @@ case OP_Found: { /* jump, in3 */
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
+ takeJump = 0;
if( pOp->opcode==OP_NoConflict ){
/* For the OP_NoConflict opcode, take the jump if any of the
** input fields are NULL, since any key with a NULL will not
** conflict */
for(ii=0; ii<pIdxKey->nField; ii++){
if( pIdxKey->aMem[ii].flags & MEM_Null ){
- pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
+ takeJump = 1;
break;
}
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
- if( pOp->p4.i==0 ){
- sqlite3DbFree(db, pFree);
- }
+ sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
break;
}
@@ -3884,10 +3953,10 @@ case OP_Found: { /* jump, in3 */
pC->cacheStatus = CACHE_STALE;
if( pOp->opcode==OP_Found ){
VdbeBranchTaken(alreadyExists!=0,2);
- if( alreadyExists ) pc = pOp->p2 - 1;
+ if( alreadyExists ) goto jump_to_p2;
}else{
- VdbeBranchTaken(alreadyExists==0,2);
- if( !alreadyExists ) pc = pOp->p2 - 1;
+ VdbeBranchTaken(takeJump||alreadyExists==0,2);
+ if( takeJump || !alreadyExists ) goto jump_to_p2;
}
break;
}
@@ -3936,10 +4005,8 @@ case OP_NotExists: { /* jump, in3 */
pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0;
VdbeBranchTaken(res!=0,2);
- if( res!=0 ){
- pc = pOp->p2 - 1;
- }
pC->seekResult = res;
+ if( res!=0 ) goto jump_to_p2;
break;
}
@@ -3951,9 +4018,10 @@ case OP_NotExists: { /* jump, in3 */
** The sequence number on the cursor is incremented after this
** instruction.
*/
-case OP_Sequence: { /* out2-prerelease */
+case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
}
@@ -3974,7 +4042,7 @@ case OP_Sequence: { /* out2-prerelease */
** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
-case OP_NewRowid: { /* out2-prerelease */
+case OP_NewRowid: { /* out2 */
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
int res; /* Result of an sqlite3BtreeLast() */
@@ -3984,12 +4052,12 @@ case OP_NewRowid: { /* out2-prerelease */
v = 0;
res = 0;
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
- if( NEVER(pC->pCursor==0) ){
- /* The zero initialization above is all that is needed */
- }else{
+ assert( pC->pCursor!=0 );
+ {
/* The next rowid or record number (different terms for the same
** thing) is obtained in a two-step algorithm.
**
@@ -4297,9 +4365,7 @@ case OP_SorterCompare: {
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
- if( res ){
- pc = pOp->p2-1;
- }
+ if( res ) goto jump_to_p2;
break;
};
@@ -4428,12 +4494,13 @@ case OP_RowData: {
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
-case OP_Rowid: { /* out2-prerelease */
+case OP_Rowid: { /* out2 */
VdbeCursor *pC;
i64 v;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@@ -4486,7 +4553,7 @@ case OP_NullRow: {
break;
}
-/* Opcode: Last P1 P2 * * *
+/* Opcode: Last P1 P2 P3 * *
**
** The next use of the Rowid or Column or Prev instruction for P1
** will refer to the last entry in the database table or index.
@@ -4513,12 +4580,13 @@ case OP_Last: { /* jump */
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
+ pC->seekResult = pOp->p3;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
- if( res ) pc = pOp->p2 - 1;
+ if( res ) goto jump_to_p2;
}
break;
}
@@ -4582,9 +4650,7 @@ case OP_Rewind: { /* jump */
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
- if( res ){
- pc = pOp->p2 - 1;
- }
+ if( res ) goto jump_to_p2;
break;
}
@@ -4695,11 +4761,11 @@ next_tail:
VdbeBranchTaken(res==0,2);
if( res==0 ){
pC->nullRow = 0;
- pc = pOp->p2 - 1;
p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
+ goto jump_to_p2_and_check_for_interrupt;
}else{
pC->nullRow = 1;
}
@@ -4730,7 +4796,6 @@ next_tail:
case OP_SorterInsert: /* in2 */
case OP_IdxInsert: { /* in2 */
VdbeCursor *pC;
- BtCursor *pCrsr;
int nKey;
const char *zKey;
@@ -4740,18 +4805,17 @@ case OP_IdxInsert: { /* in2 */
assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
pIn2 = &aMem[pOp->p2];
assert( pIn2->flags & MEM_Blob );
- pCrsr = pC->pCursor;
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- assert( pCrsr!=0 );
+ assert( pC->pCursor!=0 );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
- if( isSorter(pC) ){
+ if( pOp->opcode==OP_SorterInsert ){
rc = sqlite3VdbeSorterWrite(pC, pIn2);
}else{
nKey = pIn2->n;
zKey = pIn2->z;
- rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3,
+ rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, "", 0, 0, pOp->p3,
((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
);
assert( pC->deferredMoveto==0 );
@@ -4807,11 +4871,12 @@ case OP_IdxDelete: {
**
** See also: Rowid, MakeRecord.
*/
-case OP_IdxRowid: { /* out2-prerelease */
+case OP_IdxRowid: { /* out2 */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@@ -4924,9 +4989,7 @@ case OP_IdxGE: { /* jump */
res++;
}
VdbeBranchTaken(res>0,2);
- if( res>0 ){
- pc = pOp->p2 - 1 ;
- }
+ if( res>0 ) goto jump_to_p2;
break;
}
@@ -4950,11 +5013,12 @@ case OP_IdxGE: { /* jump */
**
** See also: Clear
*/
-case OP_Destroy: { /* out2-prerelease */
+case OP_Destroy: { /* out2 */
int iMoved;
int iDb;
assert( p->readOnly==0 );
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Null;
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
@@ -5063,12 +5127,13 @@ case OP_ResetSorter: {
**
** See documentation on OP_CreateTable for additional information.
*/
-case OP_CreateIndex: /* out2-prerelease */
-case OP_CreateTable: { /* out2-prerelease */
+case OP_CreateIndex: /* out2 */
+case OP_CreateTable: { /* out2 */
int pgno;
int flags;
Db *pDb;
+ pOut = out2Prerelease(p, pOp);
pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
@@ -5294,12 +5359,12 @@ case OP_RowSetRead: { /* jump, in1, out3 */
){
/* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1);
- pc = pOp->p2 - 1;
VdbeBranchTaken(1,2);
+ goto jump_to_p2_and_check_for_interrupt;
}else{
/* A value was pulled from the index */
- sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
VdbeBranchTaken(0,2);
+ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
}
goto check_for_interrupt;
}
@@ -5350,10 +5415,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
if( iSet ){
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
VdbeBranchTaken(exists!=0,2);
- if( exists ){
- pc = pOp->p2 - 1;
- break;
- }
+ if( exists ) goto jump_to_p2;
}
if( iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
@@ -5412,7 +5474,7 @@ case OP_Program: { /* jump */
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
+ sqlite3VdbeError(p, "too many levels of trigger recursion");
break;
}
@@ -5442,7 +5504,7 @@ case OP_Program: { /* jump */
pFrame->v = p;
pFrame->nChildMem = nMem;
pFrame->nChildCsr = pProgram->nCsr;
- pFrame->pc = pc;
+ pFrame->pc = (int)(pOp - aOp);
pFrame->aMem = p->aMem;
pFrame->nMem = p->nMem;
pFrame->apCsr = p->apCsr;
@@ -5465,7 +5527,7 @@ case OP_Program: { /* jump */
pFrame = pRt->u.pFrame;
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
assert( pProgram->nCsr==pFrame->nChildCsr );
- assert( pc==pFrame->pc );
+ assert( (int)(pOp - aOp)==pFrame->pc );
}
p->nFrame++;
@@ -5486,7 +5548,7 @@ case OP_Program: { /* jump */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
#endif
- pc = -1;
+ pOp = &aOp[-1];
memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
@@ -5504,9 +5566,10 @@ case OP_Program: { /* jump */
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
-case OP_Param: { /* out2-prerelease */
+case OP_Param: { /* out2 */
VdbeFrame *pFrame;
Mem *pIn;
+ pOut = out2Prerelease(p, pOp);
pFrame = p->pFrame;
pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
@@ -5550,10 +5613,10 @@ case OP_FkCounter: {
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
- if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
+ if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}else{
VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
- if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
+ if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}
break;
}
@@ -5604,9 +5667,7 @@ case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken( pIn1->u.i>0, 2);
- if( pIn1->u.i>0 ){
- pc = pOp->p2 - 1;
- }
+ if( pIn1->u.i>0 ) goto jump_to_p2;
break;
}
@@ -5621,9 +5682,7 @@ case OP_IfNeg: { /* jump, in1 */
assert( pIn1->flags&MEM_Int );
pIn1->u.i += pOp->p3;
VdbeBranchTaken(pIn1->u.i<0, 2);
- if( pIn1->u.i<0 ){
- pc = pOp->p2 - 1;
- }
+ if( pIn1->u.i<0 ) goto jump_to_p2;
break;
}
@@ -5640,7 +5699,7 @@ case OP_IfNotZero: { /* jump, in1 */
VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i ){
pIn1->u.i += pOp->p3;
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
@@ -5656,9 +5715,7 @@ case OP_DecrJumpZero: { /* jump, in1 */
assert( pIn1->flags&MEM_Int );
pIn1->u.i--;
VdbeBranchTaken(pIn1->u.i==0, 2);
- if( pIn1->u.i==0 ){
- pc = pOp->p2 - 1;
- }
+ if( pIn1->u.i==0 ) goto jump_to_p2;
break;
}
@@ -5674,63 +5731,105 @@ case OP_JumpZeroIncr: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i==0, 2);
- if( (pIn1->u.i++)==0 ){
- pc = pOp->p2 - 1;
- }
+ if( (pIn1->u.i++)==0 ) goto jump_to_p2;
break;
}
-/* Opcode: AggStep * P2 P3 P4 P5
+/* Opcode: AggStep0 * P2 P3 P4 P5
** Synopsis: accum=r[P3] step(r[P2@P5])
**
** Execute the step function for an aggregate. The
** function has P5 arguments. P4 is a pointer to the FuncDef
-** structure that specifies the function. Use register
-** P3 as the accumulator.
+** structure that specifies the function. Register P3 is the
+** accumulator.
**
** The P5 arguments are taken from register P2 and its
** successors.
*/
-case OP_AggStep: {
+/* Opcode: AggStep * P2 P3 P4 P5
+** Synopsis: accum=r[P3] step(r[P2@P5])
+**
+** Execute the step function for an aggregate. The
+** function has P5 arguments. P4 is a pointer to an sqlite3_context
+** object that is used to run the function. Register P3 is
+** as the accumulator.
+**
+** The P5 arguments are taken from register P2 and its
+** successors.
+**
+** This opcode is initially coded as OP_AggStep0. On first evaluation,
+** the FuncDef stored in P4 is converted into an sqlite3_context and
+** the opcode is changed. In this way, the initialization of the
+** sqlite3_context only happens once, instead of on each call to the
+** step function.
+*/
+case OP_AggStep0: {
int n;
+ sqlite3_context *pCtx;
+
+ assert( pOp->p4type==P4_FUNCDEF );
+ n = pOp->p5;
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+ pCtx = sqlite3DbMallocRaw(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
+ if( pCtx==0 ) goto no_mem;
+ pCtx->pMem = 0;
+ pCtx->pFunc = pOp->p4.pFunc;
+ pCtx->iOp = (int)(pOp - aOp);
+ pCtx->pVdbe = p;
+ pCtx->argc = n;
+ pOp->p4type = P4_FUNCCTX;
+ pOp->p4.pCtx = pCtx;
+ pOp->opcode = OP_AggStep;
+ /* Fall through into OP_AggStep */
+}
+case OP_AggStep: {
int i;
+ sqlite3_context *pCtx;
Mem *pMem;
- Mem *pRec;
Mem t;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- n = pOp->p5;
- assert( n>=0 );
- pRec = &aMem[pOp->p2];
- apVal = p->apArg;
- assert( apVal || n==0 );
- for(i=0; i<n; i++, pRec++){
- assert( memIsValid(pRec) );
- apVal[i] = pRec;
- memAboutToChange(p, pRec);
+ assert( pOp->p4type==P4_FUNCCTX );
+ pCtx = pOp->p4.pCtx;
+ pMem = &aMem[pOp->p3];
+
+ /* If this function is inside of a trigger, the register array in aMem[]
+ ** might change from one evaluation to the next. The next block of code
+ ** checks to see if the register array has changed, and if so it
+ ** reinitializes the relavant parts of the sqlite3_context object */
+ if( pCtx->pMem != pMem ){
+ pCtx->pMem = pMem;
+ for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
- ctx.pFunc = pOp->p4.pFunc;
- assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- ctx.pMem = pMem = &aMem[pOp->p3];
+
+#ifdef SQLITE_DEBUG
+ for(i=0; i<pCtx->argc; i++){
+ assert( memIsValid(pCtx->argv[i]) );
+ REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
+ }
+#endif
+
pMem->n++;
sqlite3VdbeMemInit(&t, db, MEM_Null);
- ctx.pOut = &t;
- ctx.isError = 0;
- ctx.pVdbe = p;
- ctx.iOp = pc;
- ctx.skipFlag = 0;
- (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
- if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
- rc = ctx.isError;
- }
- if( ctx.skipFlag ){
+ pCtx->pOut = &t;
+ pCtx->fErrorOrAux = 0;
+ pCtx->skipFlag = 0;
+ (pCtx->pFunc->xStep)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
+ if( pCtx->fErrorOrAux ){
+ if( pCtx->isError ){
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
+ rc = pCtx->isError;
+ }
+ sqlite3VdbeMemRelease(&t);
+ }else{
+ assert( t.flags==MEM_Null );
+ }
+ if( pCtx->skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
i = pOp[-1].p1;
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
}
- sqlite3VdbeMemRelease(&t);
break;
}
@@ -5754,7 +5853,7 @@ case OP_AggFinal: {
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
if( rc ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
}
sqlite3VdbeChangeEncoding(pMem, encoding);
UPDATE_MAX_BLOBSIZE(pMem);
@@ -5813,7 +5912,7 @@ case OP_Checkpoint: {
**
** Write a string containing the final journal-mode to register P2.
*/
-case OP_JournalMode: { /* out2-prerelease */
+case OP_JournalMode: { /* out2 */
Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
@@ -5822,6 +5921,7 @@ case OP_JournalMode: { /* out2-prerelease */
const char *zFilename; /* Name of database file for pPager */
#endif
+ pOut = out2Prerelease(p, pOp);
eNew = pOp->p3;
assert( eNew==PAGER_JOURNALMODE_DELETE
|| eNew==PAGER_JOURNALMODE_TRUNCATE
@@ -5858,7 +5958,7 @@ case OP_JournalMode: { /* out2-prerelease */
){
if( !db->autoCommit || db->nVdbeRead>1 ){
rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db,
+ sqlite3VdbeError(p,
"cannot change %s wal mode from within a transaction",
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
@@ -5897,7 +5997,6 @@ case OP_JournalMode: { /* out2-prerelease */
}
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
- pOut = &aMem[pOp->p2];
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = (char *)sqlite3JournalModename(eNew);
pOut->n = sqlite3Strlen30(pOut->z);
@@ -5938,8 +6037,8 @@ case OP_IncrVacuum: { /* jump */
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
- pc = pOp->p2 - 1;
rc = SQLITE_OK;
+ goto jump_to_p2;
}
break;
}
@@ -5990,7 +6089,7 @@ case OP_TableLock: {
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
if( (rc&0xFF)==SQLITE_LOCKED ){
const char *z = pOp->p4.z;
- sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
+ sqlite3VdbeError(p, "database table is locked: %s", z);
}
}
break;
@@ -6092,8 +6191,9 @@ case OP_VOpen: {
pCur->pVtabCursor = pVtabCursor;
pVtab->nRef++;
}else{
- db->mallocFailed = 1;
+ assert( db->mallocFailed );
pModule->xClose(pVtabCursor);
+ goto no_mem;
}
}
break;
@@ -6149,25 +6249,19 @@ case OP_VFilter: { /* jump */
iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */
- {
- res = 0;
- apArg = p->apArg;
- for(i = 0; i<nArg; i++){
- apArg[i] = &pArgc[i+1];
- }
-
- rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
- sqlite3VtabImportErrmsg(p, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pVtabCursor);
- }
- VdbeBranchTaken(res!=0,2);
- if( res ){
- pc = pOp->p2 - 1;
- }
+ res = 0;
+ apArg = p->apArg;
+ for(i = 0; i<nArg; i++){
+ apArg[i] = &pArgc[i+1];
+ }
+ rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ if( rc==SQLITE_OK ){
+ res = pModule->xEof(pVtabCursor);
}
pCur->nullRow = 0;
-
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6254,7 +6348,7 @@ case OP_VNext: { /* jump */
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
- pc = pOp->p2 - 1;
+ goto jump_to_p2_and_check_for_interrupt;
}
goto check_for_interrupt;
}
@@ -6377,7 +6471,8 @@ case OP_VUpdate: {
**
** Write the current number of pages in database P1 to memory cell P2.
*/
-case OP_Pagecount: { /* out2-prerelease */
+case OP_Pagecount: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
break;
}
@@ -6393,10 +6488,11 @@ case OP_Pagecount: { /* out2-prerelease */
**
** Store the maximum page count after the change in register P2.
*/
-case OP_MaxPgcnt: { /* out2-prerelease */
+case OP_MaxPgcnt: { /* out2 */
unsigned int newMax;
Btree *pBt;
+ pOut = out2Prerelease(p, pOp);
pBt = db->aDb[pOp->p1].pBt;
newMax = 0;
if( pOp->p3 ){
@@ -6425,9 +6521,6 @@ case OP_Init: { /* jump */
char *zTrace;
char *z;
- if( pOp->p2 ){
- pc = pOp->p2 - 1;
- }
#ifndef SQLITE_OMIT_TRACE
if( db->xTrace
&& !p->doingRerun
@@ -6455,6 +6548,7 @@ case OP_Init: { /* jump */
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
+ if( pOp->p2 ) goto jump_to_p2;
break;
}
@@ -6486,8 +6580,8 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef VDBE_PROFILE
{
u64 endTime = sqlite3Hwtime();
- if( endTime>start ) pOp->cycles += endTime - start;
- pOp->cnt++;
+ if( endTime>start ) pOrigOp->cycles += endTime - start;
+ pOrigOp->cnt++;
}
#endif
@@ -6497,16 +6591,16 @@ default: { /* This is really OP_Noop and OP_Explain */
** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/
#ifndef NDEBUG
- assert( pc>=-1 && pc<p->nOp );
+ assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc);
- if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
- registerTrace(pOp->p2, &aMem[pOp->p2]);
+ if( pOrigOp->opflags & (OPFLG_OUT2) ){
+ registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
}
- if( pOp->opflags & OPFLG_OUT3 ){
- registerTrace(pOp->p3, &aMem[pOp->p3]);
+ if( pOrigOp->opflags & OPFLG_OUT3 ){
+ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
@@ -6521,7 +6615,7 @@ vdbe_error_halt:
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
- pc, p->zSql, p->zErrMsg);
+ (int)(pOp - aOp), p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
@@ -6543,7 +6637,7 @@ vdbe_return:
** is encountered.
*/
too_big:
- sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
+ sqlite3VdbeError(p, "string or blob too big");
rc = SQLITE_TOOBIG;
goto vdbe_error_halt;
@@ -6551,7 +6645,7 @@ too_big:
*/
no_mem:
db->mallocFailed = 1;
- sqlite3SetString(&p->zErrMsg, db, "out of memory");
+ sqlite3VdbeError(p, "out of memory");
rc = SQLITE_NOMEM;
goto vdbe_error_halt;
@@ -6562,7 +6656,7 @@ abort_due_to_error:
assert( p->zErrMsg==0 );
if( db->mallocFailed ) rc = SQLITE_NOMEM;
if( rc!=SQLITE_IOERR_NOMEM ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
}
goto vdbe_error_halt;
@@ -6573,6 +6667,6 @@ abort_due_to_interrupt:
assert( db->u1.isInterrupted );
rc = SQLITE_INTERRUPT;
p->rc = rc;
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
goto vdbe_error_halt;
}