diff options
Diffstat (limited to 'third_party/sqlite/src/vdbe.c')
-rw-r--r-- | third_party/sqlite/src/vdbe.c | 2665 |
1 files changed, 1584 insertions, 1081 deletions
diff --git a/third_party/sqlite/src/vdbe.c b/third_party/sqlite/src/vdbe.c index b326c79..e25280a 100644 --- a/third_party/sqlite/src/vdbe.c +++ b/third_party/sqlite/src/vdbe.c @@ -43,15 +43,14 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.772 2008/08/02 15:10:09 danielk1977 Exp $ +** $Id: vdbe.c,v 1.874 2009/07/24 17:58:53 danielk1977 Exp $ */ #include "sqliteInt.h" -#include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor -** moves, either by the OP_MoveXX, OP_Next, or OP_Prev opcodes. The test +** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test ** procedures use this information to make sure that indices are ** working correctly. This variable has no function other than to ** help verify the correct operation of the library. @@ -110,12 +109,6 @@ static void updateMaxBlobsize(Mem *p){ #endif /* -** Release the memory associated with a register. This -** leaves the Mem.flags field in an inconsistent state. -*/ -#define Release(P) if((P)->flags&MEM_Dyn){ sqlite3VdbeMemRelease(P); } - -/* ** Convert the given register into a string if it isn't one ** already. Return non-zero if a malloc() fails. */ @@ -176,32 +169,32 @@ static void _storeTypeInfo(Mem *pMem){ ** from the comments following the "case OP_xxxx:" statements in ** this file. */ -static unsigned char opcodeProperty[] = OPFLG_INITIALIZER; +static const unsigned char opcodeProperty[] = OPFLG_INITIALIZER; /* ** Return true if an opcode has any of the OPFLG_xxx properties ** specified by mask. */ int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){ - assert( opcode>0 && opcode<sizeof(opcodeProperty) ); + assert( opcode>0 && opcode<(int)sizeof(opcodeProperty) ); return (opcodeProperty[opcode]&mask)!=0; } /* -** Allocate cursor number iCur. Return a pointer to it. Return NULL +** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL ** if we run out of memory. */ -static Cursor *allocateCursor( - Vdbe *p, - int iCur, - Op *pOp, - int iDb, - int isBtreeCursor +static VdbeCursor *allocateCursor( + Vdbe *p, /* The virtual machine */ + int iCur, /* Index of the new VdbeCursor */ + int nField, /* Number of fields in the table or index */ + int iDb, /* When database the cursor belongs to, or -1 */ + int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ ){ /* Find the memory cell that will be used to store the blob of memory - ** required for this Cursor structure. It is convenient to use a + ** required for this VdbeCursor structure. It is convenient to use a ** vdbe memory cell to manage the memory allocation required for a - ** Cursor structure for the following reasons: + ** VdbeCursor structure for the following reasons: ** ** * Sometimes cursor numbers are used for a couple of different ** purposes in a vdbe program. The different uses might require @@ -219,18 +212,9 @@ static Cursor *allocateCursor( Mem *pMem = &p->aMem[p->nMem-iCur]; int nByte; - Cursor *pCx = 0; - /* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains - ** the number of fields in the records contained in the table or - ** index being opened. Use this to reserve space for the - ** Cursor.aType[] array. - */ - int nField = 0; - if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){ - nField = pOp->p2; - } + VdbeCursor *pCx = 0; nByte = - sizeof(Cursor) + + sizeof(VdbeCursor) + (isBtreeCursor?sqlite3BtreeCursorSize():0) + 2*nField*sizeof(u32); @@ -240,15 +224,16 @@ static Cursor *allocateCursor( p->apCsr[iCur] = 0; } if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){ - p->apCsr[iCur] = pCx = (Cursor *)pMem->z; + p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pMem->z, 0, nByte); pCx->iDb = iDb; pCx->nField = nField; if( nField ){ - pCx->aType = (u32 *)&pMem->z[sizeof(Cursor)]; + pCx->aType = (u32 *)&pMem->z[sizeof(VdbeCursor)]; } if( isBtreeCursor ){ - pCx->pCursor = (BtCursor *)&pMem->z[sizeof(Cursor)+2*nField*sizeof(u32)]; + pCx->pCursor = (BtCursor*) + &pMem->z[sizeof(VdbeCursor)+2*nField*sizeof(u32)]; } } return pCx; @@ -375,12 +360,12 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ } sqlite3_snprintf(100, zCsr, "%c", c); - zCsr += strlen(zCsr); + zCsr += sqlite3Strlen30(zCsr); sqlite3_snprintf(100, zCsr, "%d[", pMem->n); - zCsr += strlen(zCsr); + zCsr += sqlite3Strlen30(zCsr); for(i=0; i<16 && i<pMem->n; i++){ sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF)); - zCsr += strlen(zCsr); + zCsr += sqlite3Strlen30(zCsr); } for(i=0; i<16 && i<pMem->n; i++){ char z = pMem->z[i]; @@ -389,10 +374,10 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ } sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]); - zCsr += strlen(zCsr); + zCsr += sqlite3Strlen30(zCsr); if( f & MEM_Zero ){ - sqlite3_snprintf(100, zCsr,"+%lldz",pMem->u.i); - zCsr += strlen(zCsr); + sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero); + zCsr += sqlite3Strlen30(zCsr); } *zCsr = '\0'; }else if( f & MEM_Str ){ @@ -412,7 +397,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ } k = 2; sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n); - k += strlen(&zBuf[k]); + k += sqlite3Strlen30(&zBuf[k]); zBuf[k++] = '['; for(j=0; j<15 && j<pMem->n; j++){ u8 c = pMem->z[j]; @@ -424,7 +409,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ } zBuf[k++] = ']'; sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]); - k += strlen(&zBuf[k]); + k += sqlite3Strlen30(&zBuf[k]); zBuf[k++] = 0; } } @@ -441,8 +426,12 @@ static void memTracePrint(FILE *out, Mem *p){ fprintf(out, " si:%lld", p->u.i); }else if( p->flags & MEM_Int ){ fprintf(out, " i:%lld", p->u.i); +#ifndef SQLITE_OMIT_FLOATING_POINT }else if( p->flags & MEM_Real ){ fprintf(out, " r:%g", p->r); +#endif + }else if( p->flags & MEM_RowSet ){ + fprintf(out, " (rowset)"); }else{ char zBuf[200]; sqlite3VdbeMemPrettyPrint(p, zBuf); @@ -504,6 +493,26 @@ static int fileExists(sqlite3 *db, const char *zFile){ } #endif +#ifndef NDEBUG +/* +** This function is only called from within an assert() expression. It +** checks that the sqlite3.nTransaction variable is correctly set to +** the number of non-transaction savepoints currently in the +** linked list starting at sqlite3.pSavepoint. +** +** Usage: +** +** assert( checkSavepointCount(db) ); +*/ +static int checkSavepointCount(sqlite3 *db){ + int n = 0; + Savepoint *p; + for(p=db->pSavepoint; p; p=p->pNext) n++; + assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); + return 1; +} +#endif + /* ** Execute as much of a VDBE program as we can then return. ** @@ -543,11 +552,13 @@ int sqlite3VdbeExec( int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 encoding = ENC(db); /* The database encoding */ - Mem *pIn1, *pIn2, *pIn3; /* Input operands */ - Mem *pOut; /* Output operand */ + Mem *pIn1 = 0; /* 1st input operand */ + Mem *pIn2 = 0; /* 2nd input operand */ + Mem *pIn3 = 0; /* 3rd input operand */ + Mem *pOut = 0; /* Output operand */ u8 opProperty; int iCompare = 0; /* Result of last OP_Compare operation */ - int *aPermute = 0; /* Permuation of columns for OP_Compare */ + int *aPermute = 0; /* Permutation of columns for OP_Compare */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ @@ -555,10 +566,11 @@ int sqlite3VdbeExec( #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif + /*** INSERT STACK UNION HERE ***/ assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ assert( db->magic==SQLITE_MAGIC_BUSY ); - sqlite3BtreeMutexArrayEnter(&p->aMutex); + sqlite3VdbeMutexArrayEnter(p); if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ @@ -664,6 +676,7 @@ int sqlite3VdbeExec( pOut = &p->aMem[pOp->p2]; sqlite3VdbeMemReleaseExternal(pOut); pOut->flags = MEM_Null; + pOut->n = 0; }else /* Do common setup for opcodes marked with one of the following @@ -687,11 +700,12 @@ int sqlite3VdbeExec( assert( pOp->p2<=p->nMem ); pIn2 = &p->aMem[pOp->p2]; REGISTER_TRACE(pOp->p2, pIn2); - if( (opProperty & OPFLG_OUT3)!=0 ){ - assert( pOp->p3>0 ); - assert( pOp->p3<=p->nMem ); - pOut = &p->aMem[pOp->p3]; - } + /* As currently implemented, in2 implies out3. There is no reason + ** why this has to be, it just worked out that way. */ + assert( (opProperty & OPFLG_OUT3)!=0 ); + assert( pOp->p3>0 ); + assert( pOp->p3<=p->nMem ); + pOut = &p->aMem[pOp->p3]; }else if( (opProperty & OPFLG_IN3)!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=p->nMem ); @@ -783,7 +797,7 @@ case OP_Gosub: { /* jump */ */ case OP_Return: { /* in1 */ assert( pIn1->flags & MEM_Int ); - pc = pIn1->u.i; + pc = (int)pIn1->u.i; break; } @@ -791,24 +805,31 @@ case OP_Return: { /* in1 */ ** ** Swap the program counter with the value in register P1. */ -case OP_Yield: { +case OP_Yield: { /* in1 */ int pcDest; - assert( pOp->p1>0 ); - assert( pOp->p1<=p->nMem ); - pIn1 = &p->aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); pIn1->flags = MEM_Int; - pcDest = pIn1->u.i; + pcDest = (int)pIn1->u.i; pIn1->u.i = pc; REGISTER_TRACE(pOp->p1, pIn1); pc = pcDest; break; } +/* Opcode: HaltIfNull P1 P2 P3 P4 * +** +** Check the value in register P3. If is is NULL then Halt using +** parameter P1, P2, and P4 as if this were a Halt instruction. If the +** value in register P3 is not NULL, then this routine is a no-op. +*/ +case OP_HaltIfNull: { /* in3 */ + if( (pIn3->flags & MEM_Null)==0 ) break; + /* Fall through into OP_Halt */ +} /* Opcode: Halt P1 P2 * P4 * ** -** Exit immediately. All open cursors, Fifos, etc are closed +** Exit immediately. All open cursors, etc are closed ** automatically. ** ** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(), @@ -826,9 +847,27 @@ case OP_Yield: { ** is the same as executing Halt. */ case OP_Halt: { + if( pOp->p1==SQLITE_OK && p->pFrame ){ + /* Halt the sub-program. Return control to the parent frame. */ + VdbeFrame *pFrame = p->pFrame; + p->pFrame = pFrame->pParent; + p->nFrame--; + sqlite3VdbeSetChanges(db, p->nChange); + pc = sqlite3VdbeFrameRestore(pFrame); + if( pOp->p2==OE_Ignore ){ + /* Instruction pc 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; + } + break; + } + p->rc = pOp->p1; + p->errorAction = (u8)pOp->p2; p->pc = pc; - p->errorAction = pOp->p2; if( pOp->p4.z ){ sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); } @@ -884,13 +923,15 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ case OP_String8: { /* same as TK_STRING, out2-prerelease */ assert( pOp->p4.z!=0 ); pOp->opcode = OP_String; - pOp->p1 = strlen(pOp->p4.z); + pOp->p1 = sqlite3Strlen30(pOp->p4.z); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ - sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + if( rc==SQLITE_TOOBIG ) goto too_big; if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; - if( SQLITE_OK!=sqlite3VdbeMemMakeWriteable(pOut) ) goto no_mem; + assert( pOut->zMalloc==pOut->z ); + assert( pOut->flags & MEM_Dyn ); pOut->zMalloc = 0; pOut->flags |= MEM_Static; pOut->flags &= ~MEM_Dyn; @@ -900,11 +941,6 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; - if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - UPDATE_MAX_BLOBSIZE(pOut); - break; } #endif if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ @@ -936,7 +972,6 @@ case OP_Null: { /* out2-prerelease */ } -#ifndef SQLITE_OMIT_BLOB_LITERAL /* Opcode: Blob P1 P2 * P4 ** ** P4 points to a blob of data P1 bytes long. Store this @@ -953,28 +988,39 @@ case OP_Blob: { /* out2-prerelease */ UPDATE_MAX_BLOBSIZE(pOut); break; } -#endif /* SQLITE_OMIT_BLOB_LITERAL */ -/* Opcode: Variable P1 P2 * * * +/* Opcode: Variable P1 P2 P3 P4 * ** -** The value of variable P1 is written into register P2. A variable is -** an unknown in the original SQL string as handed to sqlite3_compile(). -** Any occurrence of the '?' character in the original SQL is considered -** a variable. Variables in the SQL string are number from left to -** right beginning with 1. The values of variables are set using the -** sqlite3_bind() API. +** Transfer the values of bound parameters P1..P1+P3-1 into registers +** P2..P2+P3-1. +** +** If the parameter is named, then its name appears in P4 and P3==1. +** The P4 value is used by sqlite3_bind_parameter_name(). */ -case OP_Variable: { /* out2-prerelease */ - int j = pOp->p1 - 1; - Mem *pVar; - assert( j>=0 && j<p->nVar ); +case OP_Variable: { + int p1; /* Variable to copy from */ + int p2; /* Register to copy to */ + int n; /* Number of values left to copy */ + Mem *pVar; /* Value being transferred */ - pVar = &p->aVar[j]; - if( sqlite3VdbeMemTooBig(pVar) ){ - goto too_big; + p1 = pOp->p1 - 1; + p2 = pOp->p2; + n = pOp->p3; + assert( p1>=0 && p1+n<=p->nVar ); + assert( p2>=1 && p2+n-1<=p->nMem ); + assert( pOp->p4.z==0 || pOp->p3==1 ); + + while( n-- > 0 ){ + pVar = &p->aVar[p1++]; + if( sqlite3VdbeMemTooBig(pVar) ){ + goto too_big; + } + pOut = &p->aMem[p2++]; + sqlite3VdbeMemReleaseExternal(pOut); + pOut->flags = MEM_Null; + sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); + UPDATE_MAX_BLOBSIZE(pOut); } - sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static); - UPDATE_MAX_BLOBSIZE(pOut); break; } @@ -986,19 +1032,22 @@ case OP_Variable: { /* out2-prerelease */ ** P1..P1+P3-1 and P2..P2+P3-1 to overlap. */ case OP_Move: { - char *zMalloc; - int n = pOp->p3; - int p1 = pOp->p1; - int p2 = pOp->p2; - assert( n>0 ); - assert( p1>0 ); - assert( p1+n<p->nMem ); + char *zMalloc; /* Holding variable for allocated memory */ + int n; /* Number of registers left to copy */ + int p1; /* Register to copy from */ + int p2; /* Register to copy to */ + + n = pOp->p3; + p1 = pOp->p1; + p2 = pOp->p2; + assert( n>0 && p1>0 && p2>0 ); + assert( p1+n<=p2 || p2+n<=p1 ); + pIn1 = &p->aMem[p1]; - assert( p2>0 ); - assert( p2+n<p->nMem ); pOut = &p->aMem[p2]; - assert( p1+n<=p2 || p2+n<=p1 ); while( n-- ){ + assert( pOut<=&p->aMem[p->nMem] ); + assert( pIn1<=&p->aMem[p->nMem] ); zMalloc = pOut->zMalloc; pOut->zMalloc = 0; sqlite3VdbeMemMove(pOut, pIn1); @@ -1017,10 +1066,7 @@ case OP_Move: { ** This instruction makes a deep copy of the value. A duplicate ** is made of any string or blob constant. See also OP_SCopy. */ -case OP_Copy: { - assert( pOp->p1>0 ); - assert( pOp->p1<=p->nMem ); - pIn1 = &p->aMem[pOp->p1]; +case OP_Copy: { /* in1 */ assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; @@ -1043,10 +1089,7 @@ case OP_Copy: { ** during the lifetime of the copy. Use OP_Copy to make a complete ** copy. */ -case OP_SCopy: { - assert( pOp->p1>0 ); - assert( pOp->p1<=p->nMem ); - pIn1 = &p->aMem[pOp->p1]; +case OP_SCopy: { /* in1 */ REGISTER_TRACE(pOp->p1, pIn1); assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); @@ -1070,7 +1113,28 @@ case OP_ResultRow: { int i; assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 ); - assert( pOp->p1+pOp->p2<=p->nMem ); + assert( pOp->p1+pOp->p2<=p->nMem+1 ); + + /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then + ** DML statements invoke this opcode to return the number of rows + ** modified to the user. This is the only way that a VM that + ** opens a statement transaction may invoke this opcode. + ** + ** In case this is such a statement, close any statement transaction + ** opened by this VM before returning control to the user. This is to + ** ensure that statement-transactions are always nested, not overlapping. + ** If the open statement-transaction is not closed here, then the user + ** may step another VM that opens its own statement transaction. This + ** may lead to overlapping statement transactions. + ** + ** The statement transaction is never a top-level transaction. Hence + ** the RELEASE call below can never fail. + */ + assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); + rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); + if( NEVER(rc!=SQLITE_OK) ){ + break; + } /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; @@ -1089,7 +1153,6 @@ case OP_ResultRow: { /* Return SQLITE_ROW */ - p->nCallback++; p->pc = pc + 1; rc = SQLITE_ROW; goto vdbe_return; @@ -1115,16 +1178,15 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ sqlite3VdbeMemSetNull(pOut); break; } - ExpandBlob(pIn1); + if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; Stringify(pIn1, encoding); - ExpandBlob(pIn2); Stringify(pIn2, encoding); nByte = pIn1->n + pIn2->n; if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } MemSetTypeFlag(pOut, MEM_Str); - if( sqlite3VdbeMemGrow(pOut, nByte+2, pOut==pIn2) ){ + if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ goto no_mem; } if( pOut!=pIn2 ){ @@ -1134,7 +1196,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ pOut->z[nByte] = 0; pOut->z[nByte+1] = 0; pOut->flags |= MEM_Term; - pOut->n = nByte; + pOut->n = (int)nByte; pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break; @@ -1162,9 +1224,9 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ /* Opcode: Divide P1 P2 P3 * * ** ** Divide the value in register P1 by the value in register P2 -** and store the result in register P3. If the value in register P2 -** is zero, then the result is NULL. -** If either input is NULL, the result is NULL. +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is +** NULL, the result is NULL. */ /* Opcode: Remainder P1 P2 P3 * * ** @@ -1178,21 +1240,25 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ - int flags; + int flags; /* Combined MEM_* flags from both inputs */ + i64 iA; /* Integer value of left operand */ + i64 iB; /* Integer value of right operand */ + double rA; /* Real value of left operand */ + double rB; /* Real value of right operand */ + applyNumericAffinity(pIn1); applyNumericAffinity(pIn2); 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, b; - a = pIn1->u.i; - b = pIn2->u.i; + iA = pIn1->u.i; + iB = pIn2->u.i; switch( pOp->opcode ){ - case OP_Add: b += a; break; - case OP_Subtract: b -= a; break; - case OP_Multiply: b *= a; break; + case OP_Add: iB += iA; break; + case OP_Subtract: iB -= iA; break; + case OP_Multiply: iB *= iA; break; case OP_Divide: { - if( a==0 ) goto arithmetic_result_is_null; + if( iA==0 ) goto arithmetic_result_is_null; /* Dividing the largest possible negative 64-bit integer (1<<63) by ** -1 returns an integer too large to store in a 64-bit data-type. On ** some architectures, the value overflows to (1<<63). On others, @@ -1200,45 +1266,45 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ ** behavior so that all architectures behave as if integer ** overflow occurred. */ - if( a==-1 && b==SMALLEST_INT64 ) a = 1; - b /= a; + if( iA==-1 && iB==SMALLEST_INT64 ) iA = 1; + iB /= iA; break; } default: { - if( a==0 ) goto arithmetic_result_is_null; - if( a==-1 ) a = 1; - b %= a; + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + iB %= iA; break; } } - pOut->u.i = b; + pOut->u.i = iB; MemSetTypeFlag(pOut, MEM_Int); }else{ - double a, b; - a = sqlite3VdbeRealValue(pIn1); - b = sqlite3VdbeRealValue(pIn2); + rA = sqlite3VdbeRealValue(pIn1); + rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ - case OP_Add: b += a; break; - case OP_Subtract: b -= a; break; - case OP_Multiply: b *= a; break; + case OP_Add: rB += rA; break; + case OP_Subtract: rB -= rA; break; + case OP_Multiply: rB *= rA; break; case OP_Divide: { - if( a==0.0 ) goto arithmetic_result_is_null; - b /= a; + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + if( rA==(double)0 ) goto arithmetic_result_is_null; + rB /= rA; break; } default: { - i64 ia = (i64)a; - i64 ib = (i64)b; - if( ia==0 ) goto arithmetic_result_is_null; - if( ia==-1 ) ia = 1; - b = ib % ia; + iA = (i64)rA; + iB = (i64)rB; + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + rB = (double)(iB % iA); break; } } - if( sqlite3IsNaN(b) ){ + if( sqlite3IsNaN(rB) ){ goto arithmetic_result_is_null; } - pOut->r = b; + pOut->r = rB; MemSetTypeFlag(pOut, MEM_Real); if( (flags & MEM_Real)==0 ){ sqlite3VdbeIntegerAffinity(pOut); @@ -1288,12 +1354,13 @@ case OP_Function: { Mem *pArg; sqlite3_context ctx; sqlite3_value **apVal; - int n = pOp->p5; + int n; + n = pOp->p5; apVal = p->apArg; assert( apVal || n==0 ); - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem) ); + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); pArg = &p->aMem[pOp->p2]; for(i=0; i<n; i++, pArg++){ @@ -1326,7 +1393,7 @@ case OP_Function: { MemSetTypeFlag(&ctx.s, MEM_Null); ctx.isError = 0; - if( ctx.pFunc->needCollSeq ){ + if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); @@ -1408,7 +1475,8 @@ case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ - i64 a, b; + i64 a; + i64 b; if( (pIn1->flags | pIn2->flags) & MEM_Null ){ sqlite3VdbeMemSetNull(pOut); @@ -1441,36 +1509,6 @@ case OP_AddImm: { /* in1 */ break; } -/* Opcode: ForceInt P1 P2 P3 * * -** -** Convert value in register P1 into an integer. If the value -** in P1 is not numeric (meaning that is is a NULL or a string that -** does not look like an integer or floating point number) then -** jump to P2. If the value in P1 is numeric then -** convert it into the least integer that is greater than or equal to its -** current value if P3==0, or to the least integer that is strictly -** greater than its current value if P3==1. -*/ -case OP_ForceInt: { /* jump, in1 */ - i64 v; - applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); - if( (pIn1->flags & (MEM_Int|MEM_Real))==0 ){ - pc = pOp->p2 - 1; - break; - } - if( pIn1->flags & MEM_Int ){ - v = pIn1->u.i + (pOp->p3!=0); - }else{ - assert( pIn1->flags & MEM_Real ); - v = (sqlite3_int64)pIn1->r; - if( pIn1->r>(double)v ) v++; - if( pOp->p3 && pIn1->r==(double)v ) v++; - } - pIn1->u.i = v; - MemSetTypeFlag(pIn1, MEM_Int); - break; -} - /* Opcode: MustBeInt P1 P2 * * * ** ** Force the value in register P1 to be an integer. If the value @@ -1526,7 +1564,7 @@ case OP_ToText: { /* same as TK_TO_TEXT, in1 */ applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); rc = ExpandBlob(pIn1); assert( pIn1->flags & MEM_Str || db->mallocFailed ); - pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob); + pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero); UPDATE_MAX_BLOBSIZE(pIn1); break; } @@ -1545,8 +1583,10 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ if( (pIn1->flags & MEM_Blob)==0 ){ applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); assert( pIn1->flags & MEM_Str || db->mallocFailed ); + MemSetTypeFlag(pIn1, MEM_Blob); + }else{ + pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob); } - MemSetTypeFlag(pIn1, MEM_Blob); UPDATE_MAX_BLOBSIZE(pIn1); break; } @@ -1693,6 +1733,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( affinity ){ applyAffinity(pIn1, affinity, encoding); applyAffinity(pIn3, affinity, encoding); + if( db->mallocFailed ) goto no_mem; } assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); @@ -1721,7 +1762,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ /* Opcode: Permutation * * * P4 * ** -** Set the permuation used by the OP_Compare operator to be the array +** Set the permutation used by the OP_Compare operator to be the array ** of integers in P4. ** ** The permutation is only valid until the next OP_Permutation, OP_Compare, @@ -1750,19 +1791,25 @@ case OP_Permutation: { ** and strings are less than blobs. */ case OP_Compare: { - int n = pOp->p3; - int i, p1, p2; - const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; + int n; + int i; + int p1; + int p2; + const KeyInfo *pKeyInfo; + int idx; + CollSeq *pColl; /* Collating sequence to use on this term */ + int bRev; /* True for DESCENDING sort order */ + + n = pOp->p3; + pKeyInfo = pOp->p4.pKeyInfo; assert( n>0 ); assert( pKeyInfo!=0 ); p1 = pOp->p1; - assert( p1>0 && p1+n-1<p->nMem ); + assert( p1>0 && p1+n<=p->nMem+1 ); p2 = pOp->p2; - assert( p2>0 && p2+n-1<p->nMem ); + assert( p2>0 && p2+n<=p->nMem+1 ); for(i=0; i<n; i++){ - int idx = aPermute ? aPermute[i] : i; - CollSeq *pColl; /* Collating sequence to use on this term */ - int bRev; /* True for DESCENDING sort order */ + idx = aPermute ? aPermute[i] : i; REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]); REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]); assert( i<pKeyInfo->nField ); @@ -1815,7 +1862,8 @@ case OP_Jump: { /* jump */ */ case OP_And: /* same as TK_AND, in1, in2, out3 */ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ - int v1, v2; /* 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ if( pIn1->flags & MEM_Null ){ v1 = 2; @@ -1843,31 +1891,35 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ break; } -/* Opcode: Not P1 * * * * +/* Opcode: Not P1 P2 * * * ** -** Interpret the value in register P1 as a boolean value. Replace it -** with its complement. If the value in register P1 is NULL its value -** is unchanged. +** Interpret the value in register P1 as a boolean value. Store the +** boolean complement in register P2. If the value in register P1 is +** NULL, then a NULL is stored in P2. */ case OP_Not: { /* same as TK_NOT, in1 */ - if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ - sqlite3VdbeMemIntegerify(pIn1); - pIn1->u.i = !pIn1->u.i; - assert( pIn1->flags&MEM_Int ); + pOut = &p->aMem[pOp->p2]; + if( pIn1->flags & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1)); + } break; } -/* Opcode: BitNot P1 * * * * +/* Opcode: BitNot P1 P2 * * * ** -** Interpret the content of register P1 as an integer. Replace it -** with its ones-complement. If the value is originally NULL, leave -** it unchanged. +** Interpret the content of register P1 as an integer. Store the +** ones-complement of the P1 value into register P2. If P1 holds +** a NULL then store a NULL in P2. */ case OP_BitNot: { /* same as TK_BITNOT, in1 */ - if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ - sqlite3VdbeMemIntegerify(pIn1); - pIn1->u.i = ~pIn1->u.i; - assert( pIn1->flags&MEM_Int ); + pOut = &p->aMem[pOp->p2]; + if( pIn1->flags & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1)); + } break; } @@ -1890,7 +1942,7 @@ case OP_IfNot: { /* jump, in1 */ c = pOp->p3; }else{ #ifdef SQLITE_OMIT_FLOATING_POINT - c = sqlite3VdbeIntValue(pIn1); + c = sqlite3VdbeIntValue(pIn1)!=0; #else c = sqlite3VdbeRealValue(pIn1)!=0.0; #endif @@ -1902,22 +1954,14 @@ case OP_IfNot: { /* jump, in1 */ break; } -/* Opcode: IsNull P1 P2 P3 * * +/* Opcode: IsNull P1 P2 * * * ** -** Jump to P2 if the value in register P1 is NULL. If P3 is greater -** than zero, then check all values reg(P1), reg(P1+1), -** reg(P1+2), ..., reg(P1+P3-1). +** Jump to P2 if the value in register P1 is NULL. */ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ - int n = pOp->p3; - assert( pOp->p3==0 || pOp->p1>0 ); - do{ - if( (pIn1->flags & MEM_Null)!=0 ){ - pc = pOp->p2 - 1; - break; - } - pIn1++; - }while( --n > 0 ); + if( (pIn1->flags & MEM_Null)!=0 ){ + pc = pOp->p2 - 1; + } break; } @@ -1932,27 +1976,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ break; } -/* Opcode: SetNumColumns * P2 * * * -** -** This opcode sets the number of columns for the cursor opened by the -** following instruction to P2. -** -** An OP_SetNumColumns is only useful if it occurs immediately before -** one of the following opcodes: -** -** OpenRead -** OpenWrite -** OpenPseudo -** -** If the OP_Column opcode is to be executed on a cursor, then -** this opcode must be present immediately before the opcode that -** opens the cursor. -*/ -case OP_SetNumColumns: { - break; -} - -/* Opcode: Column P1 P2 P3 P4 * +/* Opcode: Column P1 P2 P3 P4 P5 ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional @@ -1962,36 +1986,49 @@ case OP_SetNumColumns: { ** ** The value extracted is stored in register P3. ** -** If the KeyAsData opcode has previously executed on this cursor, then the -** field might be extracted from the key rather than the data. -** ** If the column contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. +** +** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, +** then the cache of the cursor is reset prior to extracting the column. +** The first OP_Column against a pseudo-table after the value of the content +** register has changed should have this bit set. */ case OP_Column: { u32 payloadSize; /* Number of bytes in the record */ - int p1 = pOp->p1; /* P1 value of the opcode */ - int p2 = pOp->p2; /* column number to retrieve */ - Cursor *pC = 0; /* The VDBE cursor */ + i64 payloadSize64; /* Number of bytes in the record */ + int p1; /* P1 value of the opcode */ + int p2; /* column number to retrieve */ + VdbeCursor *pC; /* The VDBE cursor */ char *zRec; /* Pointer to complete record-data */ BtCursor *pCrsr; /* The BTree cursor */ u32 *aType; /* aType[i] holds the numeric type of the i-th column */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ - u32 nField; /* number of fields in the record */ + int nField; /* number of fields in the record */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ char *zData; /* Part of the record being decoded */ Mem *pDest; /* Where to write the extracted value */ Mem sMem; /* For storing the record being decoded */ + u8 *zIdx; /* Index into header */ + u8 *zEndHdr; /* Pointer to first byte after the header */ + u32 offset; /* Offset into the data */ + u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */ + int szHdr; /* Size of the header size field at start of record */ + int avail; /* Number of bytes of available data */ + Mem *pReg; /* PseudoTable input register */ - sMem.flags = 0; - sMem.db = 0; - sMem.zMalloc = 0; + + p1 = pOp->p1; + p2 = pOp->p2; + pC = 0; + memset(&sMem, 0, sizeof(sMem)); assert( p1<p->nCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); pDest = &p->aMem[pOp->p3]; MemSetTypeFlag(pDest, MEM_Null); + zRec = 0; /* This block sets the variable payloadSize to be the total number of ** bytes in the record. @@ -2003,41 +2040,47 @@ case OP_Column: { ** If the data is unavailable, zRec is set to NULL. ** ** We also compute the number of columns in the record. For cursors, - ** the number of columns is stored in the Cursor.nField element. + ** the number of columns is stored in the VdbeCursor.nField element. */ pC = p->apCsr[p1]; assert( pC!=0 ); #ifndef SQLITE_OMIT_VIRTUALTABLE assert( pC->pVtabCursor==0 ); #endif - if( pC->pCursor!=0 ){ + pCrsr = pC->pCursor; + if( pCrsr!=0 ){ /* The record is stored in a B-Tree */ rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; - zRec = 0; - pCrsr = pC->pCursor; if( pC->nullRow ){ payloadSize = 0; }else if( pC->cacheStatus==p->cacheCtr ){ payloadSize = pC->payloadSize; zRec = (char*)pC->aRow; }else if( pC->isIndex ){ - i64 payloadSize64; - sqlite3BtreeKeySize(pCrsr, &payloadSize64); - payloadSize = payloadSize64; + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + rc = sqlite3BtreeKeySize(pCrsr, &payloadSize64); + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ + /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the + ** payload size, so it is impossible for payloadSize64 to be + ** larger than 32 bits. */ + assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); + payloadSize = (u32)payloadSize64; }else{ - sqlite3BtreeDataSize(pCrsr, &payloadSize); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + rc = sqlite3BtreeDataSize(pCrsr, &payloadSize); + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ } - nField = pC->nField; - }else{ - assert( pC->pseudoTable ); - /* The record is the sole entry of a pseudo-table */ - payloadSize = pC->nData; - zRec = pC->pData; - pC->cacheStatus = CACHE_STALE; + }else if( pC->pseudoTableReg>0 ){ + pReg = &p->aMem[pC->pseudoTableReg]; + assert( pReg->flags & MEM_Blob ); + payloadSize = pReg->n; + zRec = pReg->z; + pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; assert( payloadSize==0 || zRec!=0 ); - nField = pC->nField; - pCrsr = 0; + }else{ + /* Consider the row to be NULL */ + payloadSize = 0; } /* If payloadSize is 0, then just store a NULL */ @@ -2045,10 +2088,12 @@ case OP_Column: { assert( pDest->flags&MEM_Null ); goto op_column_out; } - if( payloadSize>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); + if( payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } + nField = pC->nField; assert( p2<nField ); /* Read and parse the table header. Store the results of the parse @@ -2058,13 +2103,8 @@ case OP_Column: { if( pC->cacheStatus==p->cacheCtr ){ aOffset = pC->aOffset; }else{ - u8 *zIdx; /* Index into header */ - u8 *zEndHdr; /* Pointer to first byte after the header */ - u32 offset; /* Offset into the data */ - int szHdrSz; /* Size of the header size field at start of record */ - int avail; /* Number of bytes of available data */ - assert(aType); + avail = 0; pC->aOffset = aOffset = &aType[nField]; pC->payloadSize = payloadSize; pC->cacheStatus = p->cacheCtr; @@ -2083,7 +2123,8 @@ case OP_Column: { ** having to make additional calls to fetch the content portion of ** the record. */ - if( avail>=payloadSize ){ + assert( avail>=0 ); + if( payloadSize <= (u32)avail ){ zRec = zData; pC->aRow = (u8*)zData; }else{ @@ -2093,7 +2134,37 @@ case OP_Column: { /* The following assert is true in all cases accept when ** the database file has been corrupted externally. ** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */ - szHdrSz = getVarint32((u8*)zData, offset); + szHdr = getVarint32((u8*)zData, offset); + + /* Make sure a corrupt database has not given us an oversize header. + ** Do this now to avoid an oversize memory allocation. + ** + ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte + ** types use so much data space that there can only be 4096 and 32 of + ** them, respectively. So the maximum header length results from a + ** 3-byte type for each of the maximum of 32768 columns plus three + ** extra bytes for the header length itself. 32768*3 + 3 = 98307. + */ + if( offset > 98307 ){ + rc = SQLITE_CORRUPT_BKPT; + goto op_column_out; + } + + /* Compute in len the number of bytes of data we need to read in order + ** to get nField type values. offset is an upper bound on this. But + ** nField might be significantly less than the true number of columns + ** in the table, and in that case, 5*nField+3 might be smaller than offset. + ** We want to minimize len in order to limit the size of the memory + ** allocation, especially if a corrupt database file has caused offset + ** to be oversized. Offset is limited to 98307 above. But 98307 might + ** still exceed Robson memory allocation limits on some configurations. + ** On systems that cannot tolerate large memory allocations, nField*5+3 + ** will likely be much smaller since nField will likely be less than + ** 20 or so. This insures that Robson memory allocation limits are + ** not exceeded even for corrupt database files. + */ + len = nField*5 + 3; + if( len > (int)offset ) len = (int)offset; /* The KeyFetch() or DataFetch() above are fast and will get the entire ** record header in most cases. But they will fail to get the complete @@ -2101,28 +2172,29 @@ case OP_Column: { ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to ** acquire the complete header text. */ - if( !zRec && avail<offset ){ + if( !zRec && avail<len ){ sMem.flags = 0; sMem.db = 0; - rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, len, pC->isIndex, &sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } zData = sMem.z; } - zEndHdr = (u8 *)&zData[offset]; - zIdx = (u8 *)&zData[szHdrSz]; + zEndHdr = (u8 *)&zData[len]; + zIdx = (u8 *)&zData[szHdr]; /* Scan the header and use it to fill in the aType[] and aOffset[] ** arrays. aType[i] will contain the type integer for the i-th ** column and aOffset[i] will contain the offset from the beginning ** of the record to the start of the data for the i-th column */ + offset64 = offset; for(i=0; i<nField; i++){ if( zIdx<zEndHdr ){ - aOffset[i] = offset; + aOffset[i] = (u32)offset64; zIdx += getVarint32(zIdx, aType[i]); - offset += sqlite3VdbeSerialTypeLen(aType[i]); + offset64 += sqlite3VdbeSerialTypeLen(aType[i]); }else{ /* If i is less that nField, then there are less fields in this ** record than SetNumColumns indicated there are columns in the @@ -2142,7 +2214,8 @@ case OP_Column: { ** of the record (when all fields present), then we must be dealing ** with a corrupt database. */ - if( zIdx>zEndHdr || offset>payloadSize || (zIdx==zEndHdr && offset!=payloadSize) ){ + if( (zIdx > zEndHdr)|| (offset64 > payloadSize) + || (zIdx==zEndHdr && offset64!=(u64)payloadSize) ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } @@ -2210,11 +2283,14 @@ op_column_out: ** memory cell in the range. */ case OP_Affinity: { - char *zAffinity = pOp->p4.z; - Mem *pData0 = &p->aMem[pOp->p1]; - Mem *pLast = &pData0[pOp->p2-1]; - Mem *pRec; + char *zAffinity; /* The affinity to be applied */ + Mem *pData0; /* First register to which to apply affinity */ + Mem *pLast; /* Last register to which to apply affinity */ + Mem *pRec; /* Current register */ + zAffinity = pOp->p4.z; + pData0 = &p->aMem[pOp->p1]; + pLast = &pData0[pOp->p2-1]; for(pRec=pData0; pRec<=pLast; pRec++){ ExpandBlob(pRec); applyAffinity(pRec, zAffinity[pRec-pData0], encoding); @@ -2241,6 +2317,22 @@ case OP_Affinity: { ** If P4 is NULL then all index fields have the affinity NONE. */ case OP_MakeRecord: { + u8 *zNewRecord; /* A buffer to hold the data for the new record */ + Mem *pRec; /* The new record */ + 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 */ + int nVarint; /* Number of bytes in a varint */ + u32 serial_type; /* Type field */ + Mem *pData0; /* First field to be combined into the record */ + Mem *pLast; /* Last field of the record */ + int nField; /* Number of fields in the record */ + char *zAffinity; /* The affinity string for the record */ + int file_format; /* File format to use for encoding */ + int i; /* Space used in zNewRecord[] */ + int len; /* Length of a field */ + /* Assuming the record contains N fields, the record format looks ** like this: ** @@ -2256,24 +2348,13 @@ case OP_MakeRecord: { ** hdr-size field is also a varint which is the offset from the beginning ** of the record to data0. */ - u8 *zNewRecord; /* A buffer to hold the data for the new record */ - Mem *pRec; /* The new record */ - u64 nData = 0; /* Number of bytes of data space */ - int nHdr = 0; /* Number of bytes of header space */ - u64 nByte = 0; /* Data space required for this record */ - int nZero = 0; /* 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 */ - Mem *pLast; /* Last field of the record */ - int nField; /* Number of fields in the record */ - char *zAffinity; /* The affinity string for the record */ - int file_format; /* File format to use for encoding */ - int i; /* Space used in zNewRecord[] */ - + nData = 0; /* Number of bytes of data space */ + nHdr = 0; /* Number of bytes of header space */ + nByte = 0; /* Data space required for this record */ + nZero = 0; /* Number of zero bytes at the end of the record */ nField = pOp->p1; zAffinity = pOp->p4.z; - assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem ); + assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 ); pData0 = &p->aMem[nField]; nField = pOp->p2; pLast = &pData0[nField-1]; @@ -2283,7 +2364,6 @@ case OP_MakeRecord: { ** out how much space is required for the new record. */ for(pRec=pData0; pRec<=pLast; pRec++){ - int len; if( zAffinity ){ applyAffinity(pRec, zAffinity[pRec-pData0], encoding); } @@ -2297,7 +2377,7 @@ case OP_MakeRecord: { if( pRec->flags & MEM_Zero ){ /* Only pure zero-filled BLOBs can be input to this Opcode. ** We do not allow blobs with a prefix and a zero-filled tail. */ - nZero += pRec->u.i; + nZero += pRec->u.nZero; }else if( len ){ nZero = 0; } @@ -2320,7 +2400,7 @@ case OP_MakeRecord: { */ assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 ); pOut = &p->aMem[pOp->p3]; - if( sqlite3VdbeMemGrow(pOut, nByte, 0) ){ + if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){ goto no_mem; } zNewRecord = (u8 *)pOut->z; @@ -2332,16 +2412,16 @@ case OP_MakeRecord: { i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ } for(pRec=pData0; pRec<=pLast; pRec++){ /* serial data */ - i += sqlite3VdbeSerialPut(&zNewRecord[i], nByte-i, pRec, file_format); + i += sqlite3VdbeSerialPut(&zNewRecord[i], (int)(nByte-i), pRec,file_format); } assert( i==nByte ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pOut->n = nByte; + pOut->n = (int)nByte; pOut->flags = MEM_Blob | MEM_Dyn; pOut->xDel = 0; if( nZero ){ - pOut->u.i = nZero; + pOut->u.nZero = nZero; pOut->flags |= MEM_Zero; } pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ @@ -2350,42 +2430,165 @@ case OP_MakeRecord: { break; } -/* Opcode: Statement P1 * * * * -** -** Begin an individual statement transaction which is part of a larger -** transaction. This is needed so that the statement -** can be rolled back after an error without having to roll back the -** entire transaction. The statement transaction will automatically -** commit when the VDBE halts. -** -** If the database connection is currently in autocommit mode (that -** is to say, if it is in between BEGIN and COMMIT) -** and if there are no other active statements on the same database -** connection, then this operation is a no-op. No statement transaction -** is needed since any error can use the normal ROLLBACK process to -** undo changes. -** -** If a statement transaction is started, then a statement journal file -** will be allocated and initialized. -** -** The statement is begun on the database file with index P1. The main -** database file has an index of 0 and the file used for temporary tables -** has an index of 1. -*/ -case OP_Statement: { - if( db->autoCommit==0 || db->activeVdbeCnt>1 ){ - int i = pOp->p1; - Btree *pBt; - assert( i>=0 && i<db->nDb ); - assert( db->aDb[i].pBt!=0 ); - pBt = db->aDb[i].pBt; - assert( sqlite3BtreeIsInTrans(pBt) ); - assert( (p->btreeMask & (1<<i))!=0 ); - if( !sqlite3BtreeIsInStmt(pBt) ){ - rc = sqlite3BtreeBeginStmt(pBt); - p->openedStatement = 1; +/* Opcode: Count P1 P2 * * * +** +** Store the number of entries (an integer value) in the table or index +** opened by cursor P1 in register P2 +*/ +#ifndef SQLITE_OMIT_BTREECOUNT +case OP_Count: { /* out2-prerelease */ + i64 nEntry; + BtCursor *pCrsr; + + pCrsr = p->apCsr[pOp->p1]->pCursor; + if( pCrsr ){ + rc = sqlite3BtreeCount(pCrsr, &nEntry); + }else{ + nEntry = 0; + } + pOut->flags = MEM_Int; + pOut->u.i = nEntry; + break; +} +#endif + +/* Opcode: Savepoint P1 * * P4 * +** +** Open, release or rollback the savepoint named by parameter P4, depending +** on the value of P1. To open a new savepoint, P1==0. To release (commit) an +** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. +*/ +case OP_Savepoint: { + int p1; /* Value of P1 operand */ + char *zName; /* Name of savepoint */ + int nName; + Savepoint *pNew; + Savepoint *pSavepoint; + Savepoint *pTmp; + int iSavepoint; + int ii; + + p1 = pOp->p1; + zName = pOp->p4.z; + + /* Assert that the p1 parameter is valid. Also that if there is no open + ** transaction, then there cannot be any savepoints. + */ + assert( db->pSavepoint==0 || db->autoCommit==0 ); + assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); + assert( db->pSavepoint || db->isTransactionSavepoint==0 ); + assert( checkSavepointCount(db) ); + + if( p1==SAVEPOINT_BEGIN ){ + if( db->writeVdbeCnt>0 ){ + /* 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"); + rc = SQLITE_BUSY; + }else{ + nName = sqlite3Strlen30(zName); + + /* Create a new savepoint structure. */ + pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1); + if( pNew ){ + pNew->zName = (char *)&pNew[1]; + memcpy(pNew->zName, zName, nName+1); + + /* If there is no open transaction, then mark this as a special + ** "transaction savepoint". */ + if( db->autoCommit ){ + db->autoCommit = 0; + db->isTransactionSavepoint = 1; + }else{ + db->nSavepoint++; + } + + /* Link the new savepoint into the database handle's list. */ + pNew->pNext = db->pSavepoint; + db->pSavepoint = pNew; + } + } + }else{ + iSavepoint = 0; + + /* Find the named savepoint. If there is no such savepoint, then an + ** an error is returned to the user. */ + for( + pSavepoint = db->pSavepoint; + pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); + pSavepoint = pSavepoint->pNext + ){ + iSavepoint++; + } + if( !pSavepoint ){ + sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName); + rc = SQLITE_ERROR; + }else if( + db->writeVdbeCnt>0 || (p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) + ){ + /* It is not possible to release (commit) a savepoint if there are + ** active write statements. It is not possible to rollback a savepoint + ** if there are any active statements at all. + */ + sqlite3SetString(&p->zErrMsg, db, + "cannot %s savepoint - SQL statements in progress", + (p1==SAVEPOINT_ROLLBACK ? "rollback": "release") + ); + rc = SQLITE_BUSY; + }else{ + + /* Determine whether or not this is a transaction savepoint. If so, + ** and this is a RELEASE command, then the current transaction + ** is committed. + */ + int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; + if( isTransaction && p1==SAVEPOINT_RELEASE ){ + db->autoCommit = 1; + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ + p->pc = pc; + db->autoCommit = 0; + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + db->isTransactionSavepoint = 0; + rc = p->rc; + }else{ + iSavepoint = db->nSavepoint - iSavepoint - 1; + for(ii=0; ii<db->nDb; ii++){ + rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + } + if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ + sqlite3ExpirePreparedStatements(db); + sqlite3ResetInternalSchema(db, 0); + } + } + + /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all + ** savepoints nested inside of the savepoint being operated on. */ + while( db->pSavepoint!=pSavepoint ){ + pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + db->nSavepoint--; + } + + /* If it is a RELEASE, then destroy the savepoint being operated on too */ + if( p1==SAVEPOINT_RELEASE ){ + assert( pSavepoint==db->pSavepoint ); + db->pSavepoint = pSavepoint->pNext; + sqlite3DbFree(db, pSavepoint); + if( !isTransaction ){ + db->nSavepoint--; + } + } } } + break; } @@ -2393,42 +2596,54 @@ case OP_Statement: { ** ** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll ** back any currently active btree transactions. If there are any active -** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails. +** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if +** there are active writing VMs or active VMs that use shared cache. ** ** This instruction causes the VM to halt. */ case OP_AutoCommit: { - u8 i = pOp->p1; - u8 rollback = pOp->p2; - - assert( i==1 || i==0 ); - assert( i==1 || rollback==0 ); - + int desiredAutoCommit; + int iRollback; + int turnOnAC; + + desiredAutoCommit = pOp->p1; + iRollback = pOp->p2; + turnOnAC = desiredAutoCommit && !db->autoCommit; + assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); + assert( desiredAutoCommit==1 || iRollback==0 ); assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ - if( db->activeVdbeCnt>1 && i && !db->autoCommit ){ - /* If this instruction implements a COMMIT or ROLLBACK, other VMs are + if( turnOnAC && iRollback && db->activeVdbeCnt>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 %s transaction - " - "SQL statements in progress", - rollback ? "rollback" : "commit"); - rc = SQLITE_ERROR; - }else if( i!=db->autoCommit ){ - if( pOp->p2 ){ - assert( i==1 ); + sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + }else if( turnOnAC && !iRollback && db->writeVdbeCnt>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"); + rc = SQLITE_BUSY; + }else if( desiredAutoCommit!=db->autoCommit ){ + if( iRollback ){ + assert( desiredAutoCommit==1 ); sqlite3RollbackAll(db); db->autoCommit = 1; }else{ - db->autoCommit = i; + db->autoCommit = (u8)desiredAutoCommit; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; - db->autoCommit = 1-i; + db->autoCommit = (u8)(1-desiredAutoCommit); p->rc = rc = SQLITE_BUSY; goto vdbe_return; } } + assert( db->nStatement==0 ); + sqlite3CloseSavepoints(db); if( p->rc==SQLITE_OK ){ rc = SQLITE_DONE; }else{ @@ -2437,8 +2652,8 @@ case OP_AutoCommit: { goto vdbe_return; }else{ sqlite3SetString(&p->zErrMsg, db, - (!i)?"cannot start a transaction within a transaction":( - (rollback)?"cannot rollback - no transaction is active": + (!desiredAutoCommit)?"cannot start a transaction within a transaction":( + (iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); rc = SQLITE_ERROR; @@ -2465,15 +2680,24 @@ case OP_AutoCommit: { ** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained ** on the file. ** +** If a write-transaction is started and the Vdbe.usesStmtJournal flag is +** true (this flag is set if the Vdbe may modify more than one row and may +** throw an ABORT exception), a statement transaction may also be opened. +** More specifically, a statement transaction is opened iff the database +** connection is currently not in autocommit mode, or if there are other +** active statements. A statement transaction allows the affects of this +** VDBE to be rolled back after an error without having to roll back the +** entire transaction. If no error is encountered, the statement transaction +** will automatically commit when the VDBE halts. +** ** If P2 is zero, then a read-lock is obtained on the database file. */ case OP_Transaction: { - int i = pOp->p1; Btree *pBt; - assert( i>=0 && i<db->nDb ); - assert( (p->btreeMask & (1<<i))!=0 ); - pBt = db->aDb[i].pBt; + assert( pOp->p1>=0 && pOp->p1<db->nDb ); + assert( (p->btreeMask & (1<<pOp->p1))!=0 ); + pBt = db->aDb[pOp->p1].pBt; if( pBt ){ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); @@ -2485,6 +2709,18 @@ case OP_Transaction: { if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){ goto abort_due_to_error; } + + if( pOp->p2 && p->usesStmtJournal + && (db->autoCommit==0 || db->activeVdbeCnt>1) + ){ + assert( sqlite3BtreeIsInTrans(pBt) ); + if( p->iStatement==0 ){ + assert( db->nStatement>=0 && db->nSavepoint>=0 ); + db->nStatement++; + p->iStatement = db->nSavepoint + db->nStatement; + } + rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); + } } break; } @@ -2492,41 +2728,28 @@ case OP_Transaction: { /* Opcode: ReadCookie P1 P2 P3 * * ** ** Read cookie number P3 from database P1 and write it into register P2. -** P3==0 is the schema version. P3==1 is the database format. -** P3==2 is the recommended pager cache size, and so forth. P1==0 is +** P3==1 is the schema version. P3==2 is the database format. +** P3==3 is the recommended pager cache size, and so forth. P1==0 is ** the main database file and P1==1 is the database file used to store ** temporary tables. ** -** If P1 is negative, then this is a request to read the size of a -** databases free-list. P3 must be set to 1 in this case. The actual -** database accessed is ((P1+1)*-1). For example, a P1 parameter of -1 -** corresponds to database 0 ("main"), a P1 of -2 is database 1 ("temp"). -** ** There must be a read-lock on the database (either a transaction ** must be started or there must be an open cursor) before ** executing this instruction. */ case OP_ReadCookie: { /* out2-prerelease */ int iMeta; - int iDb = pOp->p1; - int iCookie = pOp->p3; + int iDb; + int iCookie; + iDb = pOp->p1; + iCookie = pOp->p3; assert( pOp->p3<SQLITE_N_BTREE_META ); - if( iDb<0 ){ - iDb = (-1*(iDb+1)); - iCookie *= -1; - } assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 ); assert( (p->btreeMask & (1<<iDb))!=0 ); - /* The indexing of meta values at the schema layer is off by one from - ** the indexing in the btree layer. The btree considers meta[0] to - ** be the number of free pages in the database (a read-only value) - ** and meta[1] to be the schema cookie. The schema layer considers - ** meta[1] to be the schema cookie. So we have to shift the index - ** by one in the following statement. - */ - rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta); + + sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); pOut->u.i = iMeta; MemSetTypeFlag(pOut, MEM_Int); break; @@ -2535,11 +2758,10 @@ case OP_ReadCookie: { /* out2-prerelease */ /* Opcode: SetCookie P1 P2 P3 * * ** ** Write the content of register P3 (interpreted as an integer) -** into cookie number P2 of database P1. -** P2==0 is the schema version. P2==1 is the database format. -** P2==2 is the recommended pager cache size, and so forth. P1==0 is -** the main database file and P1==1 is the database file used to store -** temporary tables. +** into cookie number P2 of database P1. P2==1 is the schema version. +** P2==2 is the database format. P2==3 is the recommended pager cache +** size, and so forth. P1==0 is the main database file and P1==1 is the +** database file used to store temporary tables. ** ** A transaction must be started before executing this opcode. */ @@ -2552,14 +2774,14 @@ case OP_SetCookie: { /* in3 */ assert( pDb->pBt!=0 ); sqlite3VdbeMemIntegerify(pIn3); /* See note about index shifting on OP_ReadCookie */ - rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pIn3->u.i); - if( pOp->p2==0 ){ + rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i); + if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ - pDb->pSchema->schema_cookie = pIn3->u.i; + pDb->pSchema->schema_cookie = (int)pIn3->u.i; db->flags |= SQLITE_InternChanges; - }else if( pOp->p2==1 ){ + }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ - pDb->pSchema->file_format = pIn3->u.i; + pDb->pSchema->file_format = (u8)pIn3->u.i; } if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database @@ -2592,12 +2814,11 @@ case OP_VerifyCookie: { assert( (p->btreeMask & (1<<pOp->p1))!=0 ); pBt = db->aDb[pOp->p1].pBt; if( pBt ){ - rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta); + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); }else{ - rc = SQLITE_OK; iMeta = 0; } - if( rc==SQLITE_OK && iMeta!=pOp->p2 ){ + if( iMeta!=pOp->p2 ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie @@ -2645,9 +2866,11 @@ case OP_VerifyCookie: { ** to get a read lock but fails, the script terminates with an ** SQLITE_BUSY error code. ** -** The P4 value is a pointer to a KeyInfo structure that defines the -** content and collating sequence of indices. P4 is NULL for cursors -** that are not pointing to indices. +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** structure, then said structure defines the content and collating +** sequence of the index being opened. Otherwise, if P4 is an integer +** value, it is set to the number of columns in the table. ** ** See also OpenWrite. */ @@ -2657,9 +2880,12 @@ case OP_VerifyCookie: { ** page is P2. Or if P5!=0 use the content of register P2 to find the ** root page. ** -** The P4 value is a pointer to a KeyInfo structure that defines the -** content and collating sequence of indices. P4 is NULL for cursors -** that are not pointing to indices. +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** structure, then said structure defines the content and collating +** sequence of the index being opened. Otherwise, if P4 is an integer +** value, it is set to the number of columns in the table, or to the +** largest index of any column of the table that is actually used. ** ** This instruction works just like OpenRead except that it opens the cursor ** in read/write mode. For a given table, there can be one or more read-only @@ -2669,14 +2895,19 @@ case OP_VerifyCookie: { */ case OP_OpenRead: case OP_OpenWrite: { - int i = pOp->p1; - int p2 = pOp->p2; - int iDb = pOp->p3; + int nField; + KeyInfo *pKeyInfo; + int p2; + int iDb; int wrFlag; Btree *pX; - Cursor *pCur; + VdbeCursor *pCur; Db *pDb; - + + nField = 0; + pKeyInfo = 0; + p2 = pOp->p2; + iDb = pOp->p3; assert( iDb>=0 && iDb<db->nDb ); assert( (p->btreeMask & (1<<iDb))!=0 ); pDb = &db->aDb[iDb]; @@ -2695,64 +2926,46 @@ case OP_OpenWrite: { assert( p2<=p->nMem ); pIn2 = &p->aMem[p2]; sqlite3VdbeMemIntegerify(pIn2); - p2 = pIn2->u.i; - assert( p2>=2 ); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateTable opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + if( NEVER(p2<2) ) { + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } } - assert( i>=0 ); - pCur = allocateCursor(p, i, &pOp[-1], iDb, 1); + if( pOp->p4type==P4_KEYINFO ){ + pKeyInfo = pOp->p4.pKeyInfo; + pKeyInfo->enc = ENC(p->db); + nField = pKeyInfo->nField+1; + }else if( pOp->p4type==P4_INT32 ){ + nField = pOp->p4.i; + } + assert( pOp->p1>=0 ); + pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; - rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, pCur->pCursor); - if( pOp->p4type==P4_KEYINFO ){ - pCur->pKeyInfo = pOp->p4.pKeyInfo; - pCur->pIncrKey = &pCur->pKeyInfo->incrKey; - pCur->pKeyInfo->enc = ENC(p->db); - }else{ - pCur->pKeyInfo = 0; - pCur->pIncrKey = &pCur->bogusIncrKey; - } - switch( rc ){ - case SQLITE_BUSY: { - p->pc = pc; - p->rc = rc = SQLITE_BUSY; - goto vdbe_return; - } - case SQLITE_OK: { - int flags = sqlite3BtreeFlags(pCur->pCursor); - /* Sanity checking. Only the lower four bits of the flags byte should - ** be used. Bit 3 (mask 0x08) is unpredictable. The lower 3 bits - ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or - ** 2 (zerodata for indices). If these conditions are not met it can - ** only mean that we are dealing with a corrupt database file - */ - if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - pCur->isTable = (flags & BTREE_INTKEY)!=0; - pCur->isIndex = (flags & BTREE_ZERODATA)!=0; - /* If P4==0 it means we are expected to open a table. If P4!=0 then - ** we expect to be opening an index. If this is not what happened, - ** then the database is corrupt - */ - if( (pCur->isTable && pOp->p4type==P4_KEYINFO) - || (pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - break; - } - case SQLITE_EMPTY: { - pCur->isTable = pOp->p4type!=P4_KEYINFO; - pCur->isIndex = !pCur->isTable; - pCur->pCursor = 0; - rc = SQLITE_OK; - break; - } - default: { - goto abort_due_to_error; - } + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); + pCur->pKeyInfo = pKeyInfo; + + /* Since it performs no memory allocation or IO, the only values that + ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK. + ** SQLITE_EMPTY is only returned when attempting to open the table + ** rooted at page 1 of a zero-byte database. */ + assert( rc==SQLITE_EMPTY || rc==SQLITE_OK ); + if( rc==SQLITE_EMPTY ){ + pCur->pCursor = 0; + rc = SQLITE_OK; } + + /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of + ** SQLite used to check if the root-page flags were sane at this point + ** and report database corruption if they were not, but this check has + ** since moved into the btree layer. */ + pCur->isTable = pOp->p4type!=P4_KEYINFO; + pCur->isIndex = !pCur->isTable; break; } @@ -2775,8 +2988,7 @@ case OP_OpenWrite: { ** that created confusion with the whole virtual-table idea. */ case OP_OpenEphemeral: { - int i = pOp->p1; - Cursor *pCx; + VdbeCursor *pCx; static const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | @@ -2784,8 +2996,8 @@ case OP_OpenEphemeral: { SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; - assert( i>=0 ); - pCx = allocateCursor(p, i, pOp, -1, 1); + assert( pOp->p1>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags, @@ -2809,49 +3021,40 @@ case OP_OpenEphemeral: { (KeyInfo*)pOp->p4.z, pCx->pCursor); pCx->pKeyInfo = pOp->p4.pKeyInfo; pCx->pKeyInfo->enc = ENC(p->db); - pCx->pIncrKey = &pCx->pKeyInfo->incrKey; } pCx->isTable = 0; }else{ rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor); pCx->isTable = 1; - pCx->pIncrKey = &pCx->bogusIncrKey; } } pCx->isIndex = !pCx->isTable; break; } -/* Opcode: OpenPseudo P1 P2 * * * +/* Opcode: OpenPseudo P1 P2 P3 * * ** ** Open a new cursor that points to a fake table that contains a single -** row of data. Any attempt to write a second row of data causes the -** first row to be deleted. All data is deleted when the cursor is -** closed. +** row of data. The content of that one row in the content of memory +** register P2. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. ** -** A pseudo-table created by this opcode is useful for holding the -** NEW or OLD tables in a trigger. Also used to hold the a single +** A pseudo-table created by this opcode is used to hold the a single ** row output from the sorter so that the row can be decomposed into -** individual columns using the OP_Column opcode. +** individual columns using the OP_Column opcode. The OP_Column opcode +** is the only cursor opcode that works with a pseudo-table. ** -** When OP_Insert is executed to insert a row in to the pseudo table, -** the pseudo-table cursor may or may not make it's own copy of the -** original row data. If P2 is 0, then the pseudo-table will copy the -** original row data. Otherwise, a pointer to the original memory cell -** is stored. In this case, the vdbe program must ensure that the -** memory cell containing the row data is not overwritten until the -** pseudo table is closed (or a new row is inserted into it). +** P3 is the number of fields in the records that will be stored by +** the pseudo-table. */ case OP_OpenPseudo: { - int i = pOp->p1; - Cursor *pCx; - assert( i>=0 ); - pCx = allocateCursor(p, i, &pOp[-1], -1, 0); + VdbeCursor *pCx; + + assert( pOp->p1>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; - pCx->pseudoTable = 1; - pCx->ephemPseudoTable = pOp->p2; - pCx->pIncrKey = &pCx->bogusIncrKey; + pCx->pseudoTableReg = pOp->p2; pCx->isTable = 1; pCx->isIndex = 0; break; @@ -2863,17 +3066,16 @@ case OP_OpenPseudo: { ** currently open, this instruction is a no-op. */ case OP_Close: { - int i = pOp->p1; - assert( i>=0 && i<p->nCursor ); - sqlite3VdbeFreeCursor(p, p->apCsr[i]); - p->apCsr[i] = 0; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); + p->apCsr[pOp->p1] = 0; break; } -/* Opcode: MoveGe P1 P2 P3 P4 * +/* Opcode: SeekGe P1 P2 P3 P4 * ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the integer value in register P3 as a key. If cursor P1 refers +** use the value in register P3 as the key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. ** @@ -2881,19 +3083,12 @@ case OP_Close: { ** is greater than or equal to the key value. If there are no records ** greater than or equal to the key and P2 is not zero, then jump to P2. ** -** A special feature of this opcode (and different from the -** related OP_MoveGt, OP_MoveLt, and OP_MoveLe) is that if P2 is -** zero and P1 is an SQL table (a b-tree with integer keys) then -** the seek is deferred until it is actually needed. It might be -** the case that the cursor is never accessed. By deferring the -** seek, we avoid unnecessary seeks. -** -** See also: Found, NotFound, Distinct, MoveLt, MoveGt, MoveLe +** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe */ -/* Opcode: MoveGt P1 P2 P3 P4 * +/* Opcode: SeekGt P1 P2 P3 P4 * ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the integer value in register P3 as a key. If cursor P1 refers +** use the value in register P3 as a key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. ** @@ -2901,12 +3096,12 @@ case OP_Close: { ** is greater than the key value. If there are no records greater than ** the key and P2 is not zero, then jump to P2. ** -** See also: Found, NotFound, Distinct, MoveLt, MoveGe, MoveLe +** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe */ -/* Opcode: MoveLt P1 P2 P3 P4 * +/* Opcode: SeekLt P1 P2 P3 P4 * ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the integer value in register P3 as a key. If cursor P1 refers +** use the value in register P3 as a key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. ** @@ -2914,12 +3109,12 @@ case OP_Close: { ** is less than the key value. If there are no records less than ** the key and P2 is not zero, then jump to P2. ** -** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLe +** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe */ -/* Opcode: MoveLe P1 P2 P3 P4 * +/* Opcode: SeekLe P1 P2 P3 P4 * ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the integer value in register P3 as a key. If cursor P1 refers +** use the value in register P3 as a key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. ** @@ -2927,49 +3122,97 @@ case OP_Close: { ** is less than or equal to the key value. If there are no records ** less than or equal to the key and P2 is not zero, then jump to P2. ** -** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt +** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt */ -case OP_MoveLt: /* jump, in3 */ -case OP_MoveLe: /* jump, in3 */ -case OP_MoveGe: /* jump, in3 */ -case OP_MoveGt: { /* jump, in3 */ - int i = pOp->p1; - Cursor *pC; +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; + UnpackedRecord r; + int nField; + i64 iKey; /* The rowid we are to seek to */ - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + assert( pOp->p2!=0 ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); + assert( pC->pseudoTableReg==0 ); if( pC->pCursor!=0 ){ - int res, oc; oc = pOp->opcode; pC->nullRow = 0; - *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe; if( pC->isTable ){ - i64 iKey = sqlite3VdbeIntValue(pIn3); - if( pOp->p2==0 ){ - assert( pOp->opcode==OP_MoveGe ); - pC->movetoTarget = iKey; - pC->rowidIsValid = 0; - pC->deferredMoveto = 1; - break; - } - rc = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)iKey, 0, &res); + /* 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. */ + applyNumericAffinity(pIn3); + iKey = sqlite3VdbeIntValue(pIn3); + pC->rowidIsValid = 0; + + /* If the P3 value could not be converted into an integer without + ** loss of information, then special processing is required... */ + if( (pIn3->flags & MEM_Int)==0 ){ + 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; + break; + } + /* If we reach this point, then the P3 value must be a floating + ** point number. */ + assert( (pIn3->flags & MEM_Real)!=0 ); + + if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){ + /* The P3 value is too large in magnitude to be expressed as an + ** integer. */ + res = 1; + if( pIn3->r<0 ){ + if( oc==OP_SeekGt || oc==OP_SeekGe ){ + rc = sqlite3BtreeFirst(pC->pCursor, &res); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + }else{ + if( oc==OP_SeekLt || oc==OP_SeekLe ){ + rc = sqlite3BtreeLast(pC->pCursor, &res); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + } + if( res ){ + pc = pOp->p2 - 1; + } + break; + }else if( oc==OP_SeekLt || oc==OP_SeekGe ){ + /* Use the ceiling() function to convert real->int */ + if( pIn3->r > (double)iKey ) iKey++; + }else{ + /* Use the floor() function to convert real->int */ + assert( oc==OP_SeekLe || oc==OP_SeekGt ); + if( pIn3->r < (double)iKey ) iKey--; + } + } + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - pC->lastRowid = iKey; - pC->rowidIsValid = res==0; + if( res==0 ){ + pC->rowidIsValid = 1; + pC->lastRowid = iKey; + } }else{ - UnpackedRecord r; - int nField = pOp->p4.i; + nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); assert( nField>0 ); r.pKeyInfo = pC->pKeyInfo; - r.nField = nField; - r.needFree = 0; - r.needDestroy = 0; + r.nField = (u16)nField; + if( oc==OP_SeekGt || oc==OP_SeekLe ){ + r.flags = UNPACKED_INCRKEY; + }else{ + r.flags = 0; + } r.aMem = &p->aMem[pOp->p3]; - rc = sqlite3BtreeMoveto(pC->pCursor, 0, &r, 0, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -2977,12 +3220,11 @@ case OP_MoveGt: { /* jump, in3 */ } pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; - *pC->pIncrKey = 0; #ifdef SQLITE_TEST sqlite3_search_count++; #endif - if( oc==OP_MoveGe || oc==OP_MoveGt ){ - if( res<0 ){ + if( oc==OP_SeekGe || oc==OP_SeekGt ){ + if( res<0 || (res==0 && oc==OP_SeekGt) ){ rc = sqlite3BtreeNext(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; pC->rowidIsValid = 0; @@ -2990,8 +3232,8 @@ case OP_MoveGt: { /* jump, in3 */ res = 0; } }else{ - assert( oc==OP_MoveLt || oc==OP_MoveLe ); - if( res>=0 ){ + assert( oc==OP_SeekLt || oc==OP_SeekLe ); + if( res>0 || (res==0 && oc==OP_SeekLt) ){ rc = sqlite3BtreePrevious(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; pC->rowidIsValid = 0; @@ -3006,7 +3248,7 @@ case OP_MoveGt: { /* jump, in3 */ if( res ){ pc = pOp->p2 - 1; } - }else if( !pC->pseudoTable ){ + }else{ /* This happens when attempting to open the sqlite3_master table ** for read access returns SQLITE_EMPTY. In this case always ** take the jump (since there are no records in the table). @@ -3016,6 +3258,32 @@ case OP_MoveGt: { /* jump, in3 */ break; } +/* Opcode: Seek P1 P2 * * * +** +** P1 is an open table cursor and P2 is a rowid integer. Arrange +** for P1 to move so that it points to the rowid given by P2. +** +** This is actually a deferred seek. Nothing actually happens until +** the cursor is used to read a record. That way, if no reads +** occur, no unnecessary I/O happens. +*/ +case OP_Seek: { /* in2 */ + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( ALWAYS(pC->pCursor!=0) ){ + assert( pC->isTable ); + pC->nullRow = 0; + pC->movetoTarget = sqlite3VdbeIntValue(pIn2); + pC->rowidIsValid = 0; + pC->deferredMoveto = 1; + } + break; +} + + /* Opcode: Found P1 P2 P3 * * ** ** Register P3 holds a blob constructed by MakeRecord. P1 is an index. @@ -3035,7 +3303,7 @@ case OP_MoveGt: { /* jump, in3 */ ** in the record in register P3, where N is the total number of values in ** the P3 record (the P3 record is a prefix of the P1 record). ** -** See also: NotFound, MoveTo, IsUnique, NotExists +** See also: NotFound, IsUnique, NotExists */ /* Opcode: NotFound P1 P2 P3 * * ** @@ -3044,24 +3312,35 @@ case OP_MoveGt: { /* jump, in3 */ ** to P2. If an entry does existing, fall through. The cursor is left ** pointing to the entry that matches. ** -** See also: Found, MoveTo, NotExists, IsUnique +** See also: Found, NotExists, IsUnique */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ - int i = pOp->p1; - int alreadyExists = 0; - Cursor *pC; - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - if( (pC = p->apCsr[i])->pCursor!=0 ){ - int res; + int alreadyExists; + VdbeCursor *pC; + int res; + UnpackedRecord *pIdxKey; + char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; + + alreadyExists = 0; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( ALWAYS(pC->pCursor!=0) ){ + assert( pC->isTable==0 ); assert( pIn3->flags & MEM_Blob ); + ExpandBlob(pIn3); + pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, + aTempRec, sizeof(aTempRec)); + if( pIdxKey==0 ){ + goto no_mem; + } if( pOp->opcode==OP_Found ){ - pC->pKeyInfo->prefixIsEqual = 1; + pIdxKey->flags |= UNPACKED_PREFIX_MATCH; } - rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, 0, pIn3->n, 0, &res); - pC->pKeyInfo->prefixIsEqual = 0; + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); + sqlite3VdbeDeleteUnpackedRecord(pIdxKey); if( rc!=SQLITE_OK ){ break; } @@ -3079,109 +3358,82 @@ case OP_Found: { /* jump, in3 */ /* Opcode: IsUnique P1 P2 P3 P4 * ** -** The P3 register contains an integer record number. Call this -** record number R. The P4 register contains an index key created -** using MakeIdxRec. Call it K. -** -** P1 is an index. So it has no data and its key consists of a -** record generated by OP_MakeRecord where the last field is the +** Cursor P1 is open on an index. So it has no data and its key consists +** of a record generated by OP_MakeRecord where the last field is the ** rowid of the entry that the index refers to. -** -** This instruction asks if there is an entry in P1 where the -** fields matches K but the rowid is different from R. -** If there is no such entry, then there is an immediate -** jump to P2. If any entry does exist where the index string -** matches K but the record number is not R, then the record -** number for that entry is written into P3 and control -** falls through to the next instruction. +** +** The P3 register contains an integer record number. Call this record +** number R. Register P4 is the first in a set of N contiguous registers +** that make up an unpacked index key that can be used with cursor P1. +** The value of N can be inferred from the cursor. N includes the rowid +** value appended to the end of the index record. This rowid value may +** or may not be the same as R. +** +** If any of the N registers beginning with register P4 contains a NULL +** value, jump immediately to P2. +** +** Otherwise, this instruction checks if cursor P1 contains an entry +** where the first (N-1) fields match but the rowid value at the end +** of the index entry is not R. If there is no such entry, control jumps +** to instruction P2. Otherwise, the rowid of the conflicting index +** entry is copied to register P3 and control falls through to the next +** instruction. ** ** See also: NotFound, NotExists, Found */ case OP_IsUnique: { /* jump, in3 */ - int i = pOp->p1; - Cursor *pCx; + u16 ii; + VdbeCursor *pCx; BtCursor *pCrsr; - Mem *pK; - i64 R; + u16 nField; + Mem *aMem; + UnpackedRecord r; /* B-Tree index search key */ + i64 R; /* Rowid stored in register P3 */ - /* Pop the value R off the top of the stack - */ + aMem = &p->aMem[pOp->p4.i]; + /* Assert that the values of parameters P1 and P4 are in range. */ assert( pOp->p4type==P4_INT32 ); assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); - pK = &p->aMem[pOp->p4.i]; - sqlite3VdbeMemIntegerify(pIn3); - R = pIn3->u.i; - assert( i>=0 && i<p->nCursor ); - pCx = p->apCsr[i]; - assert( pCx!=0 ); + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + + /* Find the index cursor. */ + pCx = p->apCsr[pOp->p1]; + assert( pCx->deferredMoveto==0 ); + pCx->seekResult = 0; + pCx->cacheStatus = CACHE_STALE; pCrsr = pCx->pCursor; - if( pCrsr!=0 ){ - int res; - i64 v; /* The record number on the P1 entry that matches K */ - char *zKey; /* The value of K */ - int nKey; /* Number of bytes in K */ - int len; /* Number of bytes in K without the rowid at the end */ - int szRowid; /* Size of the rowid column at the end of zKey */ - - /* Make sure K is a string and make zKey point to K - */ - assert( pK->flags & MEM_Blob ); - zKey = pK->z; - nKey = pK->n; - - /* sqlite3VdbeIdxRowidLen() only returns other than SQLITE_OK when the - ** record passed as an argument corrupt. Since the record in this case - ** has just been created by an OP_MakeRecord instruction, and not loaded - ** from the database file, it is not possible for it to be corrupt. - ** Therefore, assert(rc==SQLITE_OK). - */ - rc = sqlite3VdbeIdxRowidLen((u8*)zKey, nKey, &szRowid); - assert(rc==SQLITE_OK); - len = nKey-szRowid; - /* Search for an entry in P1 where all but the last four bytes match K. - ** If there is no such entry, jump immediately to P2. - */ - assert( pCx->deferredMoveto==0 ); - pCx->cacheStatus = CACHE_STALE; - rc = sqlite3BtreeMoveto(pCrsr, zKey, 0, len, 0, &res); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - if( res<0 ){ - rc = sqlite3BtreeNext(pCrsr, &res); - if( res ){ - pc = pOp->p2 - 1; - break; - } - } - rc = sqlite3VdbeIdxKeyCompare(pCx, 0, len, (u8*)zKey, &res); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - if( res>0 ){ + /* If any of the values are NULL, take the jump. */ + nField = pCx->pKeyInfo->nField; + for(ii=0; ii<nField; ii++){ + if( aMem[ii].flags & MEM_Null ){ pc = pOp->p2 - 1; + pCrsr = 0; break; } + } + assert( (aMem[nField].flags & MEM_Null)==0 ); - /* At this point, pCrsr is pointing to an entry in P1 where all but - ** the final entry (the rowid) matches K. Check to see if the - ** final rowid column is different from R. If it equals R then jump - ** immediately to P2. - */ - rc = sqlite3VdbeIdxRowid(pCrsr, &v); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - if( v==R ){ + if( pCrsr!=0 ){ + /* Populate the index search key. */ + r.pKeyInfo = pCx->pKeyInfo; + r.nField = nField + 1; + r.flags = UNPACKED_PREFIX_SEARCH; + r.aMem = aMem; + + /* Extract the value of R from register P3. */ + sqlite3VdbeMemIntegerify(pIn3); + R = pIn3->u.i; + + /* Search the B-Tree index. If no conflicting record is found, jump + ** to P2. Otherwise, copy the rowid of the conflicting record to + ** register P3 and fall through to the next instruction. */ + rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &pCx->seekResult); + if( (r.flags & UNPACKED_PREFIX_SEARCH) || r.rowid==R ){ pc = pOp->p2 - 1; - break; + }else{ + pIn3->u.i = r.rowid; } - - /* The final varint of the key is different from R. Store it back - ** into register R3. (The record number of an entry that violates - ** a UNIQUE constraint.) - */ - pIn3->u.i = v; - assert( pIn3->flags&MEM_Int ); } break; } @@ -3198,41 +3450,42 @@ case OP_IsUnique: { /* jump, in3 */ ** NotFound assumes key is a blob constructed from MakeRecord and ** P1 is an index. ** -** See also: Found, MoveTo, NotFound, IsUnique +** See also: Found, NotFound, IsUnique */ case OP_NotExists: { /* jump, in3 */ - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; BtCursor *pCrsr; - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ - int res; - u64 iKey; - assert( pIn3->flags & MEM_Int ); - assert( p->apCsr[i]->isTable ); - iKey = intToKey(pIn3->u.i); - rc = sqlite3BtreeMoveto(pCrsr, 0, 0, iKey, 0,&res); + int res; + u64 iKey; + + assert( pIn3->flags & MEM_Int ); + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->isTable ); + assert( pC->pseudoTableReg==0 ); + pCrsr = pC->pCursor; + if( pCrsr!=0 ){ + res = 0; + iKey = pIn3->u.i; + rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); pC->lastRowid = pIn3->u.i; - pC->rowidIsValid = res==0; + pC->rowidIsValid = res==0 ?1:0; pC->nullRow = 0; pC->cacheStatus = CACHE_STALE; - /* res might be uninitialized if rc!=SQLITE_OK. But if rc!=SQLITE_OK - ** processing is about to abort so we really do not care whether or not - ** the following jump is taken. (In other words, do not stress over - ** the error that valgrind sometimes shows on the next statement when - ** running ioerr.test and similar failure-recovery test scripts.) */ + pC->deferredMoveto = 0; if( res!=0 ){ pc = pOp->p2 - 1; assert( pC->rowidIsValid==0 ); } - }else if( !pC->pseudoTable ){ + pC->seekResult = res; + }else{ /* This happens when an attempt to open a read cursor on the ** sqlite_master table returns SQLITE_EMPTY. */ - assert( pC->isTable ); pc = pOp->p2 - 1; assert( pC->rowidIsValid==0 ); + pC->seekResult = 0; } break; } @@ -3245,10 +3498,9 @@ case OP_NotExists: { /* jump, in3 */ ** instruction. */ case OP_Sequence: { /* out2-prerelease */ - int i = pOp->p1; - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - pOut->u.i = p->apCsr[i]->seqCount++; + 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; } @@ -3261,20 +3513,27 @@ case OP_Sequence: { /* out2-prerelease */ ** table that cursor P1 points to. The new record number is written ** written to register P2. ** -** If P3>0 then P3 is a register that holds the largest previously -** generated record number. No new record numbers are allowed to be less -** than this value. When this value reaches its maximum, a SQLITE_FULL -** error is generated. The P3 register is updated with the generated -** record number. This P3 mechanism is used to help implement the +** If P3>0 then P3 is a register in the root frame of this VDBE that holds +** the largest previously generated record number. No new record numbers are +** allowed to be less than this value. When this value reaches its maximum, +** a SQLITE_FULL error is generated. The P3 register is updated with the ' +** generated record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRowid: { /* out2-prerelease */ - int i = pOp->p1; - i64 v = 0; - Cursor *pC; - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - if( (pC = p->apCsr[i])->pCursor==0 ){ + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ + VdbeFrame *pFrame; /* Root frame of VDBE */ + + v = 0; + res = 0; + 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{ /* The next rowid or record number (different terms for the same @@ -3288,36 +3547,10 @@ case OP_NewRowid: { /* out2-prerelease */ ** The second algorithm is to select a rowid at random and see if ** it already exists in the table. If it does not exist, we have ** succeeded. If the random rowid does exist, we select a new one - ** and try again, up to 1000 times. - ** - ** For a table with less than 2 billion entries, the probability - ** of not finding a unused rowid is about 1.0e-300. This is a - ** non-zero probability, but it is still vanishingly small and should - ** never cause a problem. You are much, much more likely to have a - ** hardware failure than for this algorithm to fail. - ** - ** The analysis in the previous paragraph assumes that you have a good - ** source of random numbers. Is a library function like lrand48() - ** good enough? Maybe. Maybe not. It's hard to know whether there - ** might be subtle bugs is some implementations of lrand48() that - ** could cause problems. To avoid uncertainty, SQLite uses its own - ** random number generator based on the RC4 algorithm. - ** - ** To promote locality of reference for repetitive inserts, the - ** first few attempts at choosing a random rowid pick values just a little - ** larger than the previous rowid. This has been shown experimentally - ** to double the speed of the COPY operation. + ** and try again, up to 100 times. */ - int res, rx=SQLITE_OK, cnt; - i64 x; + assert( pC->isTable ); cnt = 0; - if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) != - BTREE_INTKEY ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 ); - assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 ); #ifdef SQLITE_32BIT_ROWID # define MAX_ROWID 0x7fffffff @@ -3326,13 +3559,12 @@ case OP_NewRowid: { /* out2-prerelease */ ** Others complain about 0x7ffffffffffffffffLL. The following macro seems ** to provide the constant while making all compilers happy. */ -# define MAX_ROWID ( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) +# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) #endif if( !pC->useRandomRowid ){ - if( pC->nextRowidValid ){ - v = pC->nextRowid; - }else{ + v = sqlite3BtreeGetCachedRowid(pC->pCursor); + if( v==0 ){ rc = sqlite3BtreeLast(pC->pCursor, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -3340,8 +3572,9 @@ case OP_NewRowid: { /* out2-prerelease */ if( res ){ v = 1; }else{ - sqlite3BtreeKeySize(pC->pCursor, &v); - v = keyToInt(v); + assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); + rc = sqlite3BtreeKeySize(pC->pCursor, &v); + assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ if( v==MAX_ROWID ){ pC->useRandomRowid = 1; }else{ @@ -3352,10 +3585,20 @@ case OP_NewRowid: { /* out2-prerelease */ #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ - Mem *pMem; - assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */ - pMem = &p->aMem[pOp->p3]; - REGISTER_TRACE(pOp->p3, pMem); + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3>0 ); + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=pFrame->nMem ); + pMem = &pFrame->aMem[pOp->p3]; + }else{ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=p->nMem ); + pMem = &p->aMem[pOp->p3]; + } + + REGISTER_TRACE(pOp->p3, pMem); sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ @@ -3369,16 +3612,12 @@ case OP_NewRowid: { /* out2-prerelease */ } #endif - if( v<MAX_ROWID ){ - pC->nextRowidValid = 1; - pC->nextRowid = v+1; - }else{ - pC->nextRowidValid = 0; - } + sqlite3BtreeSetCachedRowid(pC->pCursor, v<MAX_ROWID ? v+1 : 0); } if( pC->useRandomRowid ){ - assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */ - v = db->priorNewRowid; + assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is + ** an AUTOINCREMENT table. */ + v = db->lastRowid; cnt = 0; do{ if( cnt==0 && (v&0xffffff)==v ){ @@ -3387,13 +3626,10 @@ case OP_NewRowid: { /* out2-prerelease */ sqlite3_randomness(sizeof(v), &v); if( cnt<5 ) v &= 0xffffff; } - if( v==0 ) continue; - x = intToKey(v); - rx = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)x, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v, 0, &res); cnt++; - }while( cnt<100 && rx==SQLITE_OK && res==0 ); - db->priorNewRowid = v; - if( rx==SQLITE_OK && res==0 ){ + }while( cnt<100 && rc==SQLITE_OK && res==0 ); + if( rc==SQLITE_OK && res==0 ){ rc = SQLITE_FULL; goto abort_due_to_error; } @@ -3411,15 +3647,28 @@ case OP_NewRowid: { /* out2-prerelease */ ** ** Write an entry into the table of cursor P1. A new entry is ** created if it doesn't already exist or the data for an existing -** entry is overwritten. The data is the value stored register +** entry is overwritten. The data is the value MEM_Blob stored in register ** number P2. The key is stored in register P3. The key must -** be an integer. +** be a MEM_Int. ** ** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is ** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, ** then rowid is stored for subsequent return by the ** sqlite3_last_insert_rowid() function (otherwise it is unmodified). ** +** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of +** the last seek operation (OP_NotExists) was a success, then this +** operation will not attempt to find the appropriate row before doing +** the insert but will instead overwrite the row that the cursor is +** currently pointing to. Presumably, the prior OP_NotExists opcode +** has already positioned the cursor correctly. This is an optimization +** that boosts performance by avoiding redundant seeks. +** +** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an +** UPDATE operation. Otherwise (if the flag is clear) then this opcode +** is part of an INSERT operation. The difference is only important to +** the update hook. +** ** Parameter P4 may point to a string containing the table-name, or ** may be NULL. If it is not NULL, then the update-hook ** (sqlite3.xUpdateCallback) is invoked following a successful insert. @@ -3434,75 +3683,57 @@ case OP_NewRowid: { /* out2-prerelease */ ** for indices is OP_IdxInsert. */ case OP_Insert: { - Mem *pData = &p->aMem[pOp->p2]; - Mem *pKey = &p->aMem[pOp->p3]; - - i64 iKey; /* The integer ROWID or key for the record to be inserted */ - int i = pOp->p1; - Cursor *pC; - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + Mem *pData; /* MEM cell holding data for the record to be inserted */ + Mem *pKey; /* MEM cell holding key for the record */ + i64 iKey; /* The integer ROWID or key for the record to be inserted */ + VdbeCursor *pC; /* Cursor to table into which insert is written */ + int nZero; /* Number of zero-bytes to append */ + int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + const char *zDb; /* database name - used by the update hook */ + const char *zTbl; /* Table name - used by the opdate hook */ + int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ + + pData = &p->aMem[pOp->p2]; + pKey = &p->aMem[pOp->p3]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pCursor!=0 || pC->pseudoTable ); + assert( pC->pCursor!=0 ); + assert( pC->pseudoTableReg==0 ); assert( pKey->flags & MEM_Int ); assert( pC->isTable ); REGISTER_TRACE(pOp->p2, pData); REGISTER_TRACE(pOp->p3, pKey); - iKey = intToKey(pKey->u.i); + iKey = pKey->u.i; if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i; - if( pC->nextRowidValid && pKey->u.i>=pC->nextRowid ){ - pC->nextRowidValid = 0; - } if( pData->flags & MEM_Null ){ pData->z = 0; pData->n = 0; }else{ assert( pData->flags & (MEM_Blob|MEM_Str) ); } - if( pC->pseudoTable ){ - if( !pC->ephemPseudoTable ){ - sqlite3DbFree(db, pC->pData); - } - pC->iKey = iKey; - pC->nData = pData->n; - if( pData->z==pData->zMalloc || pC->ephemPseudoTable ){ - pC->pData = pData->z; - if( !pC->ephemPseudoTable ){ - pData->flags &= ~MEM_Dyn; - pData->flags |= MEM_Ephem; - pData->zMalloc = 0; - } - }else{ - pC->pData = sqlite3Malloc( pC->nData+2 ); - if( !pC->pData ) goto no_mem; - memcpy(pC->pData, pData->z, pC->nData); - pC->pData[pC->nData] = 0; - pC->pData[pC->nData+1] = 0; - } - pC->nullRow = 0; + seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); + if( pData->flags & MEM_Zero ){ + nZero = pData->u.nZero; }else{ - int nZero; - if( pData->flags & MEM_Zero ){ - nZero = pData->u.i; - }else{ - nZero = 0; - } - rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, - pData->z, pData->n, nZero, - pOp->p5 & OPFLAG_APPEND); + nZero = 0; } - + sqlite3BtreeSetCachedRowid(pC->pCursor, 0); + rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, + pData->z, pData->n, nZero, + pOp->p5 & OPFLAG_APPEND, seekResult + ); pC->rowidIsValid = 0; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - const char *zDb = db->aDb[pC->iDb].zName; - const char *zTbl = pOp->p4.z; - int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); + zDb = db->aDb[pC->iDb].zName; + zTbl = pOp->p4.z; + op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); assert( pC->isTable ); db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey); assert( pC->iDb>=0 ); @@ -3531,12 +3762,12 @@ case OP_Insert: { ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { - int i = pOp->p1; i64 iKey; - Cursor *pC; + VdbeCursor *pC; - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + iKey = 0; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ @@ -3549,10 +3780,19 @@ case OP_Delete: { iKey = pC->lastRowid; } + /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or + ** OP_Column on the same table without any intervening operations that + ** might move or invalidate the cursor. Hence cursor pC is always pointing + ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation + ** below is always a no-op and cannot fail. We will run it anyhow, though, + ** to guard against future changes to the code generator. + **/ + assert( pC->deferredMoveto==0 ); rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + + sqlite3BtreeSetCachedRowid(pC->pCursor, 0); rc = sqlite3BtreeDelete(pC->pCursor); - pC->nextRowidValid = 0; pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ @@ -3565,18 +3805,15 @@ case OP_Delete: { if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; break; } - -/* Opcode: ResetCount P1 * * +/* Opcode: ResetCount * * * * * ** -** This opcode resets the VMs internal change counter to 0. If P1 is true, -** then the value of the change counter is copied to the database handle -** change counter (returned by subsequent calls to sqlite3_changes()) -** before it is reset. This is used by trigger programs. +** The value of the change counter is copied to the database handle +** change counter (returned by subsequent calls to sqlite3_changes()). +** Then the VMs internal change counter resets to 0. +** This is used by trigger programs. */ case OP_ResetCount: { - if( pOp->p1 ){ - sqlite3VdbeSetChanges(db, p->nChange); - } + sqlite3VdbeSetChanges(db, p->nChange); p->nChange = 0; break; } @@ -3603,36 +3840,46 @@ case OP_ResetCount: { */ case OP_RowKey: case OP_RowData: { - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; BtCursor *pCrsr; u32 n; + i64 n64; pOut = &p->aMem[pOp->p2]; /* Note that RowKey and RowData are really exactly the same instruction */ - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC->isTable || pOp->opcode==OP_RowKey ); assert( pC->isIndex || pOp->opcode==OP_RowData ); assert( pC!=0 ); assert( pC->nullRow==0 ); - assert( pC->pseudoTable==0 ); + assert( pC->pseudoTableReg==0 ); assert( pC->pCursor!=0 ); pCrsr = pC->pCursor; + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + + /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or + ** OP_Rewind/Op_Next with no intervening instructions that might invalidate + ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always + ** a no-op and can never fail. But we leave it in place as a safety. + */ + assert( pC->deferredMoveto==0 ); rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + if( pC->isIndex ){ - i64 n64; assert( !pC->isTable ); - sqlite3BtreeKeySize(pCrsr, &n64); + rc = sqlite3BtreeKeySize(pCrsr, &n64); + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - n = n64; + n = (u32)n64; }else{ - sqlite3BtreeDataSize(pCrsr, &n); - if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + rc = sqlite3BtreeDataSize(pCrsr, &n); + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ + if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } } @@ -3655,28 +3902,48 @@ case OP_RowData: { ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. +** +** P1 can be either an ordinary table or a virtual table. There used to +** 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 */ - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; i64 v; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; - if( pC->rowidIsValid ){ - v = pC->lastRowid; - }else if( pC->pseudoTable ){ - v = keyToInt(pC->iKey); - }else if( pC->nullRow ){ - /* Leave the rowid set to a NULL */ + assert( pC->pseudoTableReg==0 ); + if( pC->nullRow ){ + /* Do nothing so that reg[P2] remains NULL */ break; + }else if( pC->deferredMoveto ){ + v = pC->movetoTarget; +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( pC->pVtabCursor ){ + pVtab = pC->pVtabCursor->pVtab; + pModule = pVtab->pModule; + assert( pModule->xRowid ); + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + rc = pModule->xRowid(pC->pVtabCursor, &v); + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = pVtab->zErrMsg; + pVtab->zErrMsg = 0; + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ }else{ assert( pC->pCursor!=0 ); - sqlite3BtreeKeySize(pC->pCursor, &v); - v = keyToInt(v); + rc = sqlite3VdbeCursorMoveto(pC); + if( rc ) goto abort_due_to_error; + if( pC->rowidIsValid ){ + v = pC->lastRowid; + }else{ + rc = sqlite3BtreeKeySize(pC->pCursor, &v); + assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ + } } pOut->u.i = v; MemSetTypeFlag(pOut, MEM_Int); @@ -3690,14 +3957,16 @@ case OP_Rowid: { /* out2-prerelease */ ** write a NULL. */ case OP_NullRow: { - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pC->nullRow = 1; pC->rowidIsValid = 0; + if( pC->pCursor ){ + sqlite3BtreeClearCursor(pC->pCursor); + } break; } @@ -3710,21 +3979,24 @@ case OP_NullRow: { ** to the following instruction. */ case OP_Last: { /* jump */ - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; BtCursor *pCrsr; int res; - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; - assert( pCrsr!=0 ); - rc = sqlite3BtreeLast(pCrsr, &res); - pC->nullRow = res; + if( pCrsr==0 ){ + res = 1; + }else{ + rc = sqlite3BtreeLast(pCrsr, &res); + } + pC->nullRow = (u8)res; pC->deferredMoveto = 0; + pC->rowidIsValid = 0; pC->cacheStatus = CACHE_STALE; - if( res && pOp->p2>0 ){ + if( pOp->p2>0 && res ){ pc = pOp->p2 - 1; } break; @@ -3748,6 +4020,7 @@ case OP_Sort: { /* jump */ sqlite3_sort_count++; sqlite3_search_count--; #endif + p->aCounter[SQLITE_STMTSTATUS_SORT-1]++; /* Fall through into OP_Rewind */ } /* Opcode: Rewind P1 P2 * * * @@ -3759,23 +4032,23 @@ case OP_Sort: { /* jump */ ** to the following instruction. */ case OP_Rewind: { /* jump */ - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; BtCursor *pCrsr; int res; - assert( i>=0 && i<p->nCursor ); - pC = p->apCsr[i]; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); if( (pCrsr = pC->pCursor)!=0 ){ rc = sqlite3BtreeFirst(pCrsr, &res); - pC->atFirst = res==0; + pC->atFirst = res==0 ?1:0; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; + pC->rowidIsValid = 0; }else{ res = 1; } - pC->nullRow = res; + pC->nullRow = (u8)res; assert( pOp->p2>0 && pOp->p2<p->nOp ); if( res ){ pc = pOp->p2 - 1; @@ -3805,7 +4078,7 @@ case OP_Rewind: { /* jump */ */ case OP_Prev: /* jump */ case OP_Next: { /* jump */ - Cursor *pC; + VdbeCursor *pC; BtCursor *pCrsr; int res; @@ -3816,15 +4089,19 @@ case OP_Next: { /* jump */ break; /* See ticket #2273 */ } pCrsr = pC->pCursor; - assert( pCrsr ); + if( pCrsr==0 ){ + pC->nullRow = 1; + break; + } res = 1; assert( pC->deferredMoveto==0 ); rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) : sqlite3BtreePrevious(pCrsr, &res); - pC->nullRow = res; + pC->nullRow = (u8)res; pC->cacheStatus = CACHE_STALE; if( res==0 ){ pc = pOp->p2 - 1; + if( pOp->p5 ) p->aCounter[pOp->p5-1]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif @@ -3833,10 +4110,10 @@ case OP_Next: { /* jump */ break; } -/* Opcode: IdxInsert P1 P2 P3 * * +/* Opcode: IdxInsert P1 P2 P3 * P5 ** ** Register P2 holds a SQL index key made using the -** MakeIdxRec instructions. This opcode writes that key +** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** ** P3 is a flag that provides a hint to the b-tree layer that this @@ -3846,19 +4123,25 @@ case OP_Next: { /* jump */ ** for tables is OP_Insert. */ case OP_IdxInsert: { /* in2 */ - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; BtCursor *pCrsr; - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); + int nKey; + const char *zKey; + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); assert( pIn2->flags & MEM_Blob ); - if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ + pCrsr = pC->pCursor; + if( ALWAYS(pCrsr!=0) ){ assert( pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ - int nKey = pIn2->n; - const char *zKey = pIn2->z; - rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3); + nKey = pIn2->n; + zKey = pIn2->z; + rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3, + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) + ); assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; } @@ -3866,29 +4149,30 @@ case OP_IdxInsert: { /* in2 */ break; } -/* Opcode: IdxDeleteM P1 P2 P3 * * +/* Opcode: IdxDelete P1 P2 P3 * * ** ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { - int i = pOp->p1; - Cursor *pC; + VdbeCursor *pC; BtCursor *pCrsr; + int res; + UnpackedRecord r; + assert( pOp->p3>0 ); - assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem ); - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ - int res; - UnpackedRecord r; + assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->pCursor; + if( ALWAYS(pCrsr!=0) ){ r.pKeyInfo = pC->pKeyInfo; - r.nField = pOp->p3; - r.needFree = 0; - r.needDestroy = 0; + r.nField = (u16)pOp->p3; + r.flags = 0; r.aMem = &p->aMem[pOp->p2]; - rc = sqlite3BtreeMoveto(pCrsr, 0, &r, 0, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); if( rc==SQLITE_OK && res==0 ){ rc = sqlite3BtreeDelete(pCrsr); } @@ -3904,22 +4188,24 @@ case OP_IdxDelete: { ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** -** See also: Rowid, MakeIdxRec. +** See also: Rowid, MakeRecord. */ case OP_IdxRowid: { /* out2-prerelease */ - int i = pOp->p1; BtCursor *pCrsr; - Cursor *pC; - - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ - i64 rowid; + VdbeCursor *pC; + i64 rowid; + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->pCursor; + if( ALWAYS(pCrsr!=0) ){ + rc = sqlite3VdbeCursorMoveto(pC); + if( NEVER(rc) ) goto abort_due_to_error; assert( pC->deferredMoveto==0 ); assert( pC->isTable==0 ); if( !pC->nullRow ){ - rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); + rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -3958,25 +4244,26 @@ case OP_IdxRowid: { /* out2-prerelease */ */ case OP_IdxLT: /* jump, in3 */ case OP_IdxGE: { /* jump, in3 */ - int i= pOp->p1; - Cursor *pC; - - assert( i>=0 && i<p->nCursor ); - assert( p->apCsr[i]!=0 ); - if( (pC = p->apCsr[i])->pCursor!=0 ){ - int res; - UnpackedRecord r; + VdbeCursor *pC; + int res; + UnpackedRecord r; + + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( ALWAYS(pC->pCursor!=0) ){ assert( pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); r.pKeyInfo = pC->pKeyInfo; - r.nField = pOp->p4.i; - r.needFree = 0; - r.needDestroy = 0; + r.nField = (u16)pOp->p4.i; + if( pOp->p5 ){ + r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; + }else{ + r.flags = UNPACKED_IGNORE_ROWID; + } r.aMem = &p->aMem[pOp->p3]; - *pC->pIncrKey = pOp->p5; - rc = sqlite3VdbeIdxKeyCompare(pC, &r, 0, 0, &res); - *pC->pIncrKey = 0; + rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res); if( pOp->opcode==OP_IdxLT ){ res = -res; }else{ @@ -4013,10 +4300,11 @@ case OP_IdxGE: { /* jump, in3 */ case OP_Destroy: { /* out2-prerelease */ int iMoved; int iCnt; -#ifndef SQLITE_OMIT_VIRTUALTABLE Vdbe *pVdbe; + int iDb; +#ifndef SQLITE_OMIT_VIRTUALTABLE iCnt = 0; - for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ + for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){ if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){ iCnt++; } @@ -4028,7 +4316,7 @@ case OP_Destroy: { /* out2-prerelease */ rc = SQLITE_LOCKED; p->errorAction = OE_Abort; }else{ - int iDb = pOp->p3; + iDb = pOp->p3; assert( iCnt==1 ); assert( (p->btreeMask & (1<<iDb))!=0 ); rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); @@ -4043,7 +4331,7 @@ case OP_Destroy: { /* out2-prerelease */ break; } -/* Opcode: Clear P1 P2 * +/* Opcode: Clear P1 P2 P3 ** ** Delete all contents of the database table or index whose root page ** in the database file is given by P1. But, unlike Destroy, do not @@ -4053,11 +4341,28 @@ case OP_Destroy: { /* out2-prerelease */ ** P2==1 then the table to be clear is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** +** If the P3 value is non-zero, then the table referred to must be an +** intkey table (an SQL table, not an index). In this case the row change +** count is incremented by the number of rows in the table being cleared. +** If P3 is greater than zero, then the value stored in register P3 is +** also incremented by the number of rows in the table being cleared. +** ** See also: Destroy */ case OP_Clear: { + int nChange; + + nChange = 0; assert( (p->btreeMask & (1<<pOp->p2))!=0 ); - rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1); + rc = sqlite3BtreeClearTable( + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) + ); + if( pOp->p3 ){ + p->nChange += nChange; + if( pOp->p3>0 ){ + p->aMem[pOp->p3].u.i += nChange; + } + } break; } @@ -4088,6 +4393,8 @@ case OP_CreateTable: { /* out2-prerelease */ int pgno; int flags; Db *pDb; + + pgno = 0; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); pDb = &db->aDb[pOp->p1]; @@ -4099,10 +4406,8 @@ case OP_CreateTable: { /* out2-prerelease */ flags = BTREE_ZERODATA; } rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); - if( rc==SQLITE_OK ){ - pOut->u.i = pgno; - MemSetTypeFlag(pOut, MEM_Int); - } + pOut->u.i = pgno; + MemSetTypeFlag(pOut, MEM_Int); break; } @@ -4119,39 +4424,68 @@ case OP_CreateTable: { /* out2-prerelease */ ** then runs the new virtual machine. It is thus a re-entrant opcode. */ case OP_ParseSchema: { - char *zSql; - int iDb = pOp->p1; + int iDb; const char *zMaster; + char *zSql; InitData initData; + iDb = pOp->p1; assert( iDb>=0 && iDb<db->nDb ); - if( !pOp->p2 && !DbHasProperty(db, iDb, DB_SchemaLoaded) ){ - break; + + /* If pOp->p2 is 0, then this opcode is being executed to read a + ** single row, for example the row corresponding to a new index + ** created by this VDBE, from the sqlite_master table. It only + ** does this if the corresponding in-memory schema is currently + ** loaded. Otherwise, the new index definition can be loaded along + ** with the rest of the schema when it is required. + ** + ** Although the mutex on the BtShared object that corresponds to + ** database iDb (the database containing the sqlite_master table + ** read by this instruction) is currently held, it is necessary to + ** obtain the mutexes on all attached databases before checking if + ** the schema of iDb is loaded. This is because, at the start of + ** the sqlite3_exec() call below, SQLite will invoke + ** sqlite3BtreeEnterAll(). If all mutexes are not already held, the + ** iDb mutex may be temporarily released to avoid deadlock. If + ** this happens, then some other thread may delete the in-memory + ** schema of database iDb before the SQL statement runs. The schema + ** will not be reloaded becuase the db->init.busy flag is set. This + ** can result in a "no such table: sqlite_master" or "malformed + ** database schema" error being returned to the user. + */ + assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + sqlite3BtreeEnterAll(db); + if( pOp->p2 || DbHasProperty(db, iDb, DB_SchemaLoaded) ){ + zMaster = SCHEMA_TABLE(iDb); + initData.db = db; + initData.iDb = pOp->p1; + initData.pzErrMsg = &p->zErrMsg; + zSql = sqlite3MPrintf(db, + "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", + db->aDb[iDb].zName, zMaster, pOp->p4.z); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + (void)sqlite3SafetyOff(db); + assert( db->init.busy==0 ); + db->init.busy = 1; + initData.rc = SQLITE_OK; + assert( !db->mallocFailed ); + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); + if( rc==SQLITE_OK ) rc = initData.rc; + sqlite3DbFree(db, zSql); + db->init.busy = 0; + (void)sqlite3SafetyOn(db); + } } - zMaster = SCHEMA_TABLE(iDb); - initData.db = db; - initData.iDb = pOp->p1; - initData.pzErrMsg = &p->zErrMsg; - zSql = sqlite3MPrintf(db, - "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", - db->aDb[iDb].zName, zMaster, pOp->p4.z); - if( zSql==0 ) goto no_mem; - (void)sqlite3SafetyOff(db); - assert( db->init.busy==0 ); - db->init.busy = 1; - assert( !db->mallocFailed ); - rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); - if( rc==SQLITE_ABORT ) rc = initData.rc; - sqlite3DbFree(db, zSql); - db->init.busy = 0; - (void)sqlite3SafetyOn(db); + sqlite3BtreeLeaveAll(db); if( rc==SQLITE_NOMEM ){ goto no_mem; } break; } -#if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) +#if !defined(SQLITE_OMIT_ANALYZE) /* Opcode: LoadAnalysis P1 * * * * ** ** Read the sqlite_stat1 table for database P1 and load the content @@ -4159,12 +4493,11 @@ case OP_ParseSchema: { ** the analysis to be used when preparing all subsequent queries. */ case OP_LoadAnalysis: { - int iDb = pOp->p1; - assert( iDb>=0 && iDb<db->nDb ); - rc = sqlite3AnalysisLoad(db, iDb); + assert( pOp->p1>=0 && pOp->p1<db->nDb ); + rc = sqlite3AnalysisLoad(db, pOp->p1); break; } -#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */ +#endif /* !defined(SQLITE_OMIT_ANALYZE) */ /* Opcode: DropTable P1 * * P4 * ** @@ -4242,13 +4575,13 @@ case OP_IntegrityCk: { assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &p->aMem[pOp->p1]; for(j=0; j<nRoot; j++){ - aRoot[j] = sqlite3VdbeIntValue(&pIn1[j]); + aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); } aRoot[j] = 0; assert( pOp->p5<db->nDb ); assert( (p->btreeMask & (1<<pOp->p5))!=0 ); z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, - pnErr->u.i, &nErr); + (int)pnErr->u.i, &nErr); sqlite3DbFree(db, aRoot); pnErr->u.i -= nErr; sqlite3VdbeMemSetNull(pIn1); @@ -4265,90 +4598,270 @@ case OP_IntegrityCk: { } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ -/* Opcode: FifoWrite P1 * * * * +/* Opcode: RowSetAdd P1 P2 * * * +** +** Insert the integer value held by register P2 into a boolean index +** held in register P1. ** -** Write the integer from register P1 into the Fifo. +** An assertion fails if P2 is not an integer. */ -case OP_FifoWrite: { /* in1 */ - p->sFifo.db = db; - if( sqlite3VdbeFifoPush(&p->sFifo, sqlite3VdbeIntValue(pIn1))==SQLITE_NOMEM ){ - goto no_mem; - } +case OP_RowSetAdd: { /* in2 */ + Mem *pIdx; + Mem *pVal; + assert( pOp->p1>0 && pOp->p1<=p->nMem ); + pIdx = &p->aMem[pOp->p1]; + assert( pOp->p2>0 && pOp->p2<=p->nMem ); + pVal = &p->aMem[pOp->p2]; + assert( (pVal->flags & MEM_Int)!=0 ); + if( (pIdx->flags & MEM_RowSet)==0 ){ + sqlite3VdbeMemSetRowSet(pIdx); + if( (pIdx->flags & MEM_RowSet)==0 ) goto no_mem; + } + sqlite3RowSetInsert(pIdx->u.pRowSet, pVal->u.i); break; } -/* Opcode: FifoRead P1 P2 * * * +/* Opcode: RowSetRead P1 P2 P3 * * ** -** Attempt to read a single integer from the Fifo. Store that -** integer in register P1. -** -** If the Fifo is empty jump to P2. +** Extract the smallest value from boolean index P1 and put that value into +** register P3. Or, if boolean index P1 is initially empty, leave P3 +** unchanged and jump to instruction P2. */ -case OP_FifoRead: { /* jump */ - CHECK_FOR_INTERRUPT; +case OP_RowSetRead: { /* jump, out3 */ + Mem *pIdx; + i64 val; assert( pOp->p1>0 && pOp->p1<=p->nMem ); - pOut = &p->aMem[pOp->p1]; - MemSetTypeFlag(pOut, MEM_Int); - if( sqlite3VdbeFifoPop(&p->sFifo, &pOut->u.i)==SQLITE_DONE ){ + CHECK_FOR_INTERRUPT; + pIdx = &p->aMem[pOp->p1]; + pOut = &p->aMem[pOp->p3]; + if( (pIdx->flags & MEM_RowSet)==0 + || sqlite3RowSetNext(pIdx->u.pRowSet, &val)==0 + ){ + /* The boolean index is empty */ + sqlite3VdbeMemSetNull(pIdx); pc = pOp->p2 - 1; + }else{ + /* A value was pulled from the index */ + assert( pOp->p3>0 && pOp->p3<=p->nMem ); + sqlite3VdbeMemSetInt64(pOut, val); + } + break; +} + +/* Opcode: RowSetTest P1 P2 P3 P4 +** +** Register P3 is assumed to hold a 64-bit integer value. If register P1 +** contains a RowSet object and that RowSet object contains +** the value held in P3, jump to register P2. Otherwise, insert the +** integer in P3 into the RowSet and continue on to the +** next opcode. +** +** The RowSet object is optimized for the case where successive sets +** of integers, where each set contains no duplicates. Each set +** of values is identified by a unique P4 value. The first set +** must have P4==0, the final set P4=-1. P4 must be either -1 or +** non-negative. For non-negative values of P4 only the lower 4 +** bits are significant. +** +** This allows optimizations: (a) when P4==0 there is no need to test +** the rowset object for P3, as it is guaranteed not to contain it, +** (b) when P4==-1 there is no need to insert the value, as it will +** never be tested for, and (c) when a value that is part of set X is +** inserted, there is no need to search to see if the same value was +** previously inserted as part of set X (only if it was previously +** inserted as part of some other set). +*/ +case OP_RowSetTest: { /* jump, in1, in3 */ + int iSet; + int exists; + + iSet = pOp->p4.i; + assert( pIn3->flags&MEM_Int ); + + /* If there is anything other than a rowset object in memory cell P1, + ** delete it now and initialize P1 with an empty rowset + */ + if( (pIn1->flags & MEM_RowSet)==0 ){ + sqlite3VdbeMemSetRowSet(pIn1); + if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; + } + + assert( pOp->p4type==P4_INT32 ); + assert( iSet==-1 || iSet>=0 ); + if( iSet ){ + exists = sqlite3RowSetTest(pIn1->u.pRowSet, + (u8)(iSet>=0 ? iSet & 0xf : 0xff), + pIn3->u.i); + if( exists ){ + pc = pOp->p2 - 1; + break; + } + } + if( iSet>=0 ){ + sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); } break; } + #ifndef SQLITE_OMIT_TRIGGER -/* Opcode: ContextPush * * * -** -** Save the current Vdbe context such that it can be restored by a ContextPop -** opcode. The context stores the last insert row id, the last statement change -** count, and the current statement change count. -*/ -case OP_ContextPush: { - int i = p->contextStackTop++; - Context *pContext; - - assert( i>=0 ); - /* FIX ME: This should be allocated as part of the vdbe at compile-time */ - if( i>=p->contextStackDepth ){ - p->contextStackDepth = i+1; - p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack, - sizeof(Context)*(i+1)); - if( p->contextStack==0 ) goto no_mem; - } - pContext = &p->contextStack[i]; - pContext->lastRowid = db->lastRowid; - pContext->nChange = p->nChange; - pContext->sFifo = p->sFifo; - sqlite3VdbeFifoInit(&p->sFifo, db); + +/* Opcode: Program P1 P2 P3 P4 * +** +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). +** +** P1 contains the address of the memory cell that contains the first memory +** cell in an array of values used as arguments to the sub-program. P2 +** contains the address to jump to if the sub-program throws an IGNORE +** exception using the RAISE() function. Register P3 contains the address +** of a memory cell in this (the parent) VM that is used to allocate the +** memory required by the sub-vdbe at runtime. +** +** P4 is a pointer to the VM containing the trigger program. +*/ +case OP_Program: { /* jump */ + int nMem; /* Number of memory registers for sub-program */ + int nByte; /* Bytes of runtime space required for sub-program */ + Mem *pRt; /* Register to allocate runtime space */ + Mem *pMem; /* Used to iterate through memory cells */ + Mem *pEnd; /* Last memory cell in new array */ + VdbeFrame *pFrame; /* New vdbe frame to execute in */ + SubProgram *pProgram; /* Sub-program to execute */ + void *t; /* Token identifying trigger */ + + pProgram = pOp->p4.pProgram; + pRt = &p->aMem[pOp->p3]; + assert( pProgram->nOp>0 ); + + /* If the SQLITE_RecTriggers flag is clear, then recursive invocation of + ** triggers is disabled for backwards compatibility (flag set/cleared by + ** the "PRAGMA recursive_triggers" command). + ** + ** It is recursive invocation of triggers, at the SQL level, that is + ** disabled. In some cases a single trigger may generate more than one + ** SubProgram (if the trigger may be executed with more than one different + ** ON CONFLICT algorithm). SubProgram structures associated with a + ** single trigger all have the same value for the SubProgram.token + ** variable. + */ + if( 0==(db->flags&SQLITE_RecTriggers) ){ + t = pProgram->token; + for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent); + if( pFrame ) break; + } + + if( p->nFrame>db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ + rc = SQLITE_ERROR; + sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); + break; + } + + /* Register pRt is used to store the memory required to save the state + ** of the current program, and the memory required at runtime to execute + ** the trigger program. If this trigger has been fired before, then pRt + ** is already allocated. Otherwise, it must be initialized. */ + if( (pRt->flags&MEM_Frame)==0 ){ + /* SubProgram.nMem is set to the number of memory cells used by the + ** program stored in SubProgram.aOp. As well as these, one memory + ** cell is required for each cursor used by the program. Set local + ** variable nMem (and later, VdbeFrame.nChildMem) to this value. + */ + nMem = pProgram->nMem + pProgram->nCsr; + nByte = ROUND8(sizeof(VdbeFrame)) + + nMem * sizeof(Mem) + + pProgram->nCsr * sizeof(VdbeCursor *); + pFrame = sqlite3DbMallocZero(db, nByte); + if( !pFrame ){ + goto no_mem; + } + sqlite3VdbeMemRelease(pRt); + pRt->flags = MEM_Frame; + pRt->u.pFrame = pFrame; + + pFrame->v = p; + pFrame->nChildMem = nMem; + pFrame->nChildCsr = pProgram->nCsr; + pFrame->pc = pc; + pFrame->aMem = p->aMem; + pFrame->nMem = p->nMem; + pFrame->apCsr = p->apCsr; + pFrame->nCursor = p->nCursor; + pFrame->aOp = p->aOp; + pFrame->nOp = p->nOp; + pFrame->token = pProgram->token; + + pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; + for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ + pMem->flags = MEM_Null; + pMem->db = db; + } + }else{ + pFrame = pRt->u.pFrame; + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); + assert( pProgram->nCsr==pFrame->nChildCsr ); + assert( pc==pFrame->pc ); + } + + p->nFrame++; + pFrame->pParent = p->pFrame; + pFrame->lastRowid = db->lastRowid; + pFrame->nChange = p->nChange; + p->nChange = 0; + p->pFrame = pFrame; + p->aMem = &VdbeFrameMem(pFrame)[-1]; + p->nMem = pFrame->nChildMem; + p->nCursor = (u16)pFrame->nChildCsr; + p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1]; + p->aOp = pProgram->aOp; + p->nOp = pProgram->nOp; + pc = -1; + break; } -/* Opcode: ContextPop * * * +/* Opcode: Param P1 P2 * * * ** -** Restore the Vdbe context to the state it was in when contextPush was last -** executed. The context stores the last insert row id, the last statement -** change count, and the current statement change count. +** This opcode is only ever present in sub-programs called via the +** OP_Program instruction. Copy a value currently stored in a memory +** cell of the calling (parent) frame to cell P2 in the current frames +** address space. This is used by trigger programs to access the new.* +** and old.* values. +** +** The address of the cell in the parent frame is determined by adding +** the value of the P1 argument to the value of the P1 argument to the +** calling OP_Program instruction. */ -case OP_ContextPop: { - Context *pContext = &p->contextStack[--p->contextStackTop]; - assert( p->contextStackTop>=0 ); - db->lastRowid = pContext->lastRowid; - p->nChange = pContext->nChange; - sqlite3VdbeFifoClear(&p->sFifo); - p->sFifo = pContext->sFifo; +case OP_Param: { /* out2-prerelease */ + VdbeFrame *pFrame; + Mem *pIn; + pFrame = p->pFrame; + pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; + sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); break; } + #endif /* #ifndef SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_AUTOINCREMENT /* Opcode: MemMax P1 P2 * * * ** -** Set the value of register P1 to the maximum of its current value -** and the value in register P2. +** P1 is a register in the root frame of this VM (the root frame is +** different from the current frame if this instruction is being executed +** within a sub-program). Set the value of register P1 to the maximum of +** its current value and the value in register P2. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ -case OP_MemMax: { /* in1, in2 */ +case OP_MemMax: { /* in2 */ + Mem *pIn1; + VdbeFrame *pFrame; + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + pIn1 = &pFrame->aMem[pOp->p1]; + }else{ + pIn1 = &p->aMem[pOp->p1]; + } sqlite3VdbeMemIntegerify(pIn1); sqlite3VdbeMemIntegerify(pIn2); if( pIn1->u.i<pIn2->u.i){ @@ -4414,12 +4927,14 @@ case OP_IfZero: { /* jump, in1 */ ** successors. */ case OP_AggStep: { - int n = pOp->p5; + int n; int i; - Mem *pMem, *pRec; + Mem *pMem; + Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; + n = pOp->p5; assert( n>=0 ); pRec = &p->aMem[pOp->p2]; apVal = p->apArg; @@ -4439,7 +4954,7 @@ case OP_AggStep: { ctx.s.db = db; ctx.isError = 0; ctx.pColl = 0; - if( ctx.pFunc->needCollSeq ){ + if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); @@ -4472,7 +4987,7 @@ case OP_AggFinal: { pMem = &p->aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); - if( rc==SQLITE_ERROR ){ + if( rc ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem)); } sqlite3VdbeChangeEncoding(pMem, encoding); @@ -4545,7 +5060,7 @@ case OP_Expire: { ** Obtain a lock on a particular table. This instruction is only used when ** the shared-cache feature is enabled. ** -** If P1 is the index of the database in sqlite3.aDb[] of the database +** P1 is the index of the database in sqlite3.aDb[] of the database ** on which the lock is acquired. A readlock is obtained if P3==0 or ** a write lock if P3==1. ** @@ -4555,15 +5070,17 @@ case OP_Expire: { ** used to generate an error message if the lock cannot be obtained. */ case OP_TableLock: { - int p1 = pOp->p1; - u8 isWriteLock = pOp->p3; - assert( p1>=0 && p1<db->nDb ); - assert( (p->btreeMask & (1<<p1))!=0 ); - assert( isWriteLock==0 || isWriteLock==1 ); - rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); - if( rc==SQLITE_LOCKED ){ - const char *z = pOp->p4.z; - sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); + u8 isWriteLock = (u8)pOp->p3; + if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ + int p1 = pOp->p1; + assert( p1>=0 && p1<db->nDb ); + assert( (p->btreeMask & (1<<p1))!=0 ); + assert( isWriteLock==0 || isWriteLock==1 ); + 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); + } } break; } @@ -4576,16 +5093,17 @@ case OP_TableLock: { ** xBegin method for that table. ** ** Also, whether or not P4 is set, check that this is not being called from -** within a callback to a virtual table xSync() method. If it is, set the -** error code to SQLITE_LOCKED. +** within a callback to a virtual table xSync() method. If it is, the error +** code will be set to SQLITE_LOCKED. */ case OP_VBegin: { - sqlite3_vtab *pVtab = pOp->p4.pVtab; - rc = sqlite3VtabBegin(db, pVtab); - if( pVtab ){ + VTable *pVTab; + pVTab = pOp->p4.pVtab; + rc = sqlite3VtabBegin(db, pVTab); + if( pVTab ){ sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = pVtab->zErrMsg; - pVtab->zErrMsg = 0; + p->zErrMsg = pVTab->pVtab->zErrMsg; + pVTab->pVtab->zErrMsg = 0; } break; } @@ -4625,12 +5143,15 @@ case OP_VDestroy: { ** table and stores that cursor in P1. */ case OP_VOpen: { - Cursor *pCur = 0; - sqlite3_vtab_cursor *pVtabCursor = 0; - - sqlite3_vtab *pVtab = pOp->p4.pVtab; - sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule; + VdbeCursor *pCur; + sqlite3_vtab_cursor *pVtabCursor; + sqlite3_vtab *pVtab; + sqlite3_module *pModule; + pCur = 0; + pVtabCursor = 0; + pVtab = pOp->p4.pVtab->pVtab; + pModule = (sqlite3_module *)pVtab->pModule; assert(pVtab && pModule); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xOpen(pVtab, &pVtabCursor); @@ -4643,7 +5164,7 @@ case OP_VOpen: { pVtabCursor->pVtab = pVtab; /* Initialise vdbe cursor object */ - pCur = allocateCursor(p, pOp->p1, &pOp[-1], -1, 0); + pCur = allocateCursor(p, pOp->p1, 0, -1, 0); if( pCur ){ pCur->pVtabCursor = pVtabCursor; pCur->pModule = pVtabCursor->pVtab->pModule; @@ -4679,13 +5200,18 @@ case OP_VFilter: { /* jump */ int nArg; int iQuery; const sqlite3_module *pModule; - Mem *pQuery = &p->aMem[pOp->p3]; - Mem *pArgc = &pQuery[1]; + Mem *pQuery; + Mem *pArgc; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; + VdbeCursor *pCur; + int res; + int i; + Mem **apArg; - Cursor *pCur = p->apCsr[pOp->p1]; - + pQuery = &p->aMem[pOp->p3]; + pArgc = &pQuery[1]; + pCur = p->apCsr[pOp->p1]; REGISTER_TRACE(pOp->p3, pQuery); assert( pCur->pVtabCursor ); pVtabCursor = pCur->pVtabCursor; @@ -4694,28 +5220,25 @@ case OP_VFilter: { /* jump */ /* Grab the index number and argc parameters */ assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); - nArg = pArgc->u.i; - iQuery = pQuery->u.i; + nArg = (int)pArgc->u.i; + iQuery = (int)pQuery->u.i; /* Invoke the xFilter method */ { - int res = 0; - int i; - Mem **apArg = p->apArg; + res = 0; + apArg = p->apArg; for(i = 0; i<nArg; i++){ apArg[i] = &pArgc[i+1]; storeTypeInfo(apArg[i], 0); } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(pVtab); p->inVtabMethod = 1; rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); p->inVtabMethod = 0; sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = pVtab->zErrMsg; pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, pVtab); if( rc==SQLITE_OK ){ res = pModule->xEof(pVtabCursor); } @@ -4732,37 +5255,6 @@ case OP_VFilter: { /* jump */ #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VRowid P1 P2 * * * -** -** Store into register P2 the rowid of -** the virtual-table that the P1 cursor is pointing to. -*/ -case OP_VRowid: { /* out2-prerelease */ - sqlite3_vtab *pVtab; - const sqlite3_module *pModule; - sqlite_int64 iRow; - Cursor *pCur = p->apCsr[pOp->p1]; - - assert( pCur->pVtabCursor ); - if( pCur->nullRow ){ - break; - } - pVtab = pCur->pVtabCursor->pVtab; - pModule = pVtab->pModule; - assert( pModule->xRowid ); - if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - rc = pModule->xRowid(pCur->pVtabCursor, &iRow); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = pVtab->zErrMsg; - pVtab->zErrMsg = 0; - if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = iRow; - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VColumn P1 P2 P3 * * ** ** Store the value of the P2-th column of @@ -4775,7 +5267,7 @@ case OP_VColumn: { Mem *pDest; sqlite3_context sContext; - Cursor *pCur = p->apCsr[pOp->p1]; + VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); pDest = &p->aMem[pOp->p3]; @@ -4801,9 +5293,12 @@ case OP_VColumn: { sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = pVtab->zErrMsg; pVtab->zErrMsg = 0; + if( sContext.isError ){ + rc = sContext.isError; + } /* Copy the result of the function to the P3 register. We - ** do this regardless of whether or not an error occured to ensure any + ** do this regardless of whether or not an error occurred to ensure any ** dynamic allocation in sContext.s (a Mem struct) is released. */ sqlite3VdbeChangeEncoding(&sContext.s, encoding); @@ -4831,9 +5326,11 @@ case OP_VColumn: { case OP_VNext: { /* jump */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; - int res = 0; + int res; + VdbeCursor *pCur; - Cursor *pCur = p->apCsr[pOp->p1]; + res = 0; + pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); if( pCur->nullRow ){ break; @@ -4849,14 +5346,12 @@ case OP_VNext: { /* jump */ ** some other method is next invoked on the save virtual table cursor. */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(pVtab); p->inVtabMethod = 1; rc = pModule->xNext(pCur->pVtabCursor); p->inVtabMethod = 0; sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = pVtab->zErrMsg; pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, pVtab); if( rc==SQLITE_OK ){ res = pModule->xEof(pCur->pVtabCursor); } @@ -4878,20 +5373,19 @@ case OP_VNext: { /* jump */ ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { - sqlite3_vtab *pVtab = pOp->p4.pVtab; - Mem *pName = &p->aMem[pOp->p1]; + sqlite3_vtab *pVtab; + Mem *pName; + + pVtab = pOp->p4.pVtab->pVtab; + pName = &p->aMem[pOp->p1]; assert( pVtab->pModule->xRename ); REGISTER_TRACE(pOp->p1, pName); - - Stringify(pName, encoding); - + assert( pName->flags & MEM_Str ); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(pVtab); rc = pVtab->pModule->xRename(pVtab, pName->z); sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = pVtab->zErrMsg; pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, pVtab); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; break; @@ -4923,32 +5417,33 @@ case OP_VRename: { ** is set to the value of the rowid for the row just inserted. */ case OP_VUpdate: { - sqlite3_vtab *pVtab = pOp->p4.pVtab; - sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule; - int nArg = pOp->p2; + sqlite3_vtab *pVtab; + sqlite3_module *pModule; + int nArg; + int i; + sqlite_int64 rowid; + Mem **apArg; + Mem *pX; + + pVtab = pOp->p4.pVtab->pVtab; + pModule = (sqlite3_module *)pVtab->pModule; + nArg = pOp->p2; assert( pOp->p4type==P4_VTAB ); - if( pModule->xUpdate==0 ){ - sqlite3SetString(&p->zErrMsg, db, "read-only table"); - rc = SQLITE_ERROR; - }else{ - int i; - sqlite_int64 rowid; - Mem **apArg = p->apArg; - Mem *pX = &p->aMem[pOp->p3]; + if( ALWAYS(pModule->xUpdate) ){ + apArg = p->apArg; + pX = &p->aMem[pOp->p3]; for(i=0; i<nArg; i++){ storeTypeInfo(pX, 0); apArg[i] = pX; pX++; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(pVtab); rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = pVtab->zErrMsg; pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, pVtab); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( pOp->p1 && rc==SQLITE_OK ){ + if( rc==SQLITE_OK && pOp->p1 ){ assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); db->lastRowid = rowid; } @@ -4964,12 +5459,17 @@ case OP_VUpdate: { ** Write the current number of pages in database P1 to memory cell P2. */ case OP_Pagecount: { /* out2-prerelease */ - int p1 = pOp->p1; + int p1; int nPage; - Pager *pPager = sqlite3BtreePager(db->aDb[p1].pBt); + Pager *pPager; + p1 = pOp->p1; + pPager = sqlite3BtreePager(db->aDb[p1].pBt); rc = sqlite3PagerPagecount(pPager, &nPage); - if( rc==SQLITE_OK ){ + /* OP_Pagecount is always called from within a read transaction. The + ** 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; } @@ -4984,13 +5484,16 @@ case OP_Pagecount: { /* out2-prerelease */ ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { - if( pOp->p4.z ){ + char *zTrace; + + zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); + if( zTrace ){ if( db->xTrace ){ - db->xTrace(db->pTraceArg, pOp->p4.z); + db->xTrace(db->pTraceArg, zTrace); } #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 ){ - sqlite3DebugPrintf("SQL-trace: %s\n", pOp->p4.z); + sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); } #endif /* SQLITE_DEBUG */ } |