summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/vdbe.c
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2007-02-09 03:17:47 +0000
committerIlia Alshanetsky <iliaa@php.net>2007-02-09 03:17:47 +0000
commitd35449bbfb0c4feac3057c9aa3583f2bfc92782a (patch)
treefd693b43275b710fc88e6710b90007691fc9bca1 /ext/pdo_sqlite/sqlite/src/vdbe.c
parent7aa2282124fe2b024cb4f7ec0353c7943ce15505 (diff)
downloadphp-git-d35449bbfb0c4feac3057c9aa3583f2bfc92782a.tar.gz
Upgraded SQLite 3 to version 3.3.12
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/vdbe.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/vdbe.c151
1 files changed, 81 insertions, 70 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/vdbe.c b/ext/pdo_sqlite/sqlite/src/vdbe.c
index 98b9916abe..2e5b3957b9 100644
--- a/ext/pdo_sqlite/sqlite/src/vdbe.c
+++ b/ext/pdo_sqlite/sqlite/src/vdbe.c
@@ -454,6 +454,21 @@ int sqlite3VdbeExec(
p->resOnStack = 0;
db->busyHandler.nBusy = 0;
CHECK_FOR_INTERRUPT;
+#ifdef SQLITE_DEBUG
+ if( (p->db->flags & SQLITE_VdbeListing)!=0
+ || sqlite3OsFileExists("vdbe_explain")
+ ){
+ int i;
+ printf("VDBE Program Listing:\n");
+ sqlite3VdbePrintSql(p);
+ for(i=0; i<p->nOp; i++){
+ sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
+ }
+ }
+ if( sqlite3OsFileExists("vdbe_trace") ){
+ p->trace = stdout;
+ }
+#endif
for(pc=p->pc; rc==SQLITE_OK; pc++){
assert( pc>=0 && pc<p->nOp );
assert( pTos<=&p->aStack[pc] );
@@ -1812,32 +1827,31 @@ case OP_IfNot: { /* no-push */
/* Opcode: IsNull P1 P2 *
**
-** If any of the top abs(P1) values on the stack are NULL, then jump
-** to P2. Pop the stack P1 times if P1>0. If P1<0 leave the stack
-** unchanged.
+** Check the top of the stack and jump to P2 if the top of the stack
+** is NULL. If P1 is positive, then pop P1 elements from the stack
+** regardless of whether or not the jump is taken. If P1 is negative,
+** pop -P1 elements from the stack only if the jump is taken and leave
+** the stack unchanged if the jump is not taken.
*/
case OP_IsNull: { /* same as TK_ISNULL, no-push */
- int i, cnt;
- Mem *pTerm;
- cnt = pOp->p1;
- if( cnt<0 ) cnt = -cnt;
- pTerm = &pTos[1-cnt];
- assert( pTerm>=p->aStack );
- for(i=0; i<cnt; i++, pTerm++){
- if( pTerm->flags & MEM_Null ){
- pc = pOp->p2-1;
- break;
+ if( pTos->flags & MEM_Null ){
+ pc = pOp->p2-1;
+ if( pOp->p1<0 ){
+ popStack(&pTos, -pOp->p1);
}
}
- if( pOp->p1>0 ) popStack(&pTos, cnt);
+ if( pOp->p1>0 ){
+ popStack(&pTos, pOp->p1);
+ }
break;
}
/* Opcode: NotNull P1 P2 *
**
-** Jump to P2 if the top P1 values on the stack are all not NULL. Pop the
-** stack if P1 times if P1 is greater than zero. If P1 is less than
-** zero then leave the stack unchanged.
+** Jump to P2 if the top abs(P1) values on the stack are all not NULL.
+** Regardless of whether or not the jump is taken, pop the stack
+** P1 times if P1 is greater than zero. But if P1 is negative,
+** leave the stack unchanged.
*/
case OP_NotNull: { /* same as TK_NOTNULL, no-push */
int i, cnt;
@@ -2010,7 +2024,9 @@ case OP_Column: {
pC->aRow = 0;
}
}
- assert( zRec!=0 || avail>=payloadSize || avail>=9 );
+ /* 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 = GetVarint((u8*)zData, offset);
/* The KeyFetch() or DataFetch() above are fast and will get the entire
@@ -2501,6 +2517,8 @@ case OP_VerifyCookie: { /* no-push */
}
if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0);
+ sqlite3ResetInternalSchema(db, pOp->p1);
+ sqlite3ExpirePreparedStatements(db);
rc = SQLITE_SCHEMA;
}
break;
@@ -2907,7 +2925,7 @@ case OP_MoveGt: { /* no-push */
**
** The top of the stack holds a blob constructed by MakeRecord. P1 is
** an index. If no entry exists in P1 that matches the blob then jump
-** to P1. If an entry does existing, fall through. The cursor is left
+** to P2. If an entry does existing, fall through. The cursor is left
** pointing to the entry that matches. The blob is popped from the stack.
**
** The difference between this operation and Distinct is that
@@ -2980,7 +2998,7 @@ case OP_IsUnique: { /* no-push */
R = pTos->i;
assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
- assert( i>=0 && i<=p->nCursor );
+ assert( i>=0 && i<p->nCursor );
pCx = p->apCsr[i];
assert( pCx!=0 );
pCrsr = pCx->pCursor;
@@ -3081,6 +3099,9 @@ case OP_NotExists: { /* no-push */
pC->rowidIsValid = res==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. */
if( res!=0 ){
pc = pOp->p2 - 1;
pC->rowidIsValid = 0;
@@ -3852,38 +3873,6 @@ case OP_IdxGE: { /* no-push */
break;
}
-/* Opcode: IdxIsNull P1 P2 *
-**
-** The top of the stack contains an index entry such as might be generated
-** by the MakeIdxRec opcode. This routine looks at the first P1 fields of
-** that key. If any of the first P1 fields are NULL, then a jump is made
-** to address P2. Otherwise we fall straight through.
-**
-** The index entry is always popped from the stack.
-*/
-case OP_IdxIsNull: { /* no-push */
- int i = pOp->p1;
- int k, n;
- const char *z;
- u32 serial_type;
-
- assert( pTos>=p->aStack );
- assert( pTos->flags & MEM_Blob );
- z = pTos->z;
- n = pTos->n;
- k = sqlite3GetVarint32((u8*)z, &serial_type);
- for(; k<n && i>0; i--){
- k += sqlite3GetVarint32((u8*)&z[k], &serial_type);
- if( serial_type==0 ){ /* Serial type 0 is a NULL */
- pc = pOp->p2-1;
- break;
- }
- }
- Release(pTos);
- pTos--;
- break;
-}
-
/* Opcode: Destroy P1 P2 *
**
** Delete an entire database table or index whose root page in the database
@@ -3906,9 +3895,9 @@ case OP_IdxIsNull: { /* no-push */
*/
case OP_Destroy: {
int iMoved;
- Vdbe *pVdbe;
int iCnt;
#ifndef SQLITE_OMIT_VIRTUALTABLE
+ Vdbe *pVdbe;
iCnt = 0;
for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){
@@ -4032,10 +4021,14 @@ case OP_CreateTable: {
break;
}
-/* Opcode: ParseSchema P1 * P3
+/* Opcode: ParseSchema P1 P2 P3
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
-** that match the WHERE clause P3.
+** that match the WHERE clause P3. P2 is the "force" flag. Always do
+** the parsing if P2 is true. If P2 is false, then this routine is a
+** no-op if the schema is not currently loaded. In other words, if P2
+** is false, the SQLITE_MASTER table is only parsed if the rest of the
+** schema is already loaded into the symbol table.
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine. It is thus a reentrant opcode.
@@ -4047,13 +4040,16 @@ case OP_ParseSchema: { /* no-push */
InitData initData;
assert( iDb>=0 && iDb<db->nDb );
- if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
+ if( !pOp->p2 && !DbHasProperty(db, iDb, DB_SchemaLoaded) ){
+ break;
+ }
zMaster = SCHEMA_TABLE(iDb);
initData.db = db;
+ initData.iDb = pOp->p1;
initData.pzErrMsg = &p->zErrMsg;
zSql = sqlite3MPrintf(
- "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
- pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
+ "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
+ db->aDb[iDb].zName, zMaster, pOp->p3);
if( zSql==0 ) goto no_mem;
sqlite3SafetyOff(db);
assert( db->init.busy==0 );
@@ -4124,11 +4120,16 @@ case OP_DropTrigger: { /* no-push */
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/* Opcode: IntegrityCk * P2 *
+/* Opcode: IntegrityCk P1 P2 *
**
** Do an analysis of the currently open database. Push onto the
** stack the text of an error message describing any problems.
-** If there are no errors, push a "ok" onto the stack.
+** If no problems are found, push a NULL onto the stack.
+**
+** P1 is the address of a memory cell that contains the maximum
+** number of allowed errors. At most mem[P1] errors will be reported.
+** In other words, the analysis stops as soon as mem[P1] errors are
+** seen. Mem[P1] is updated with the number of errors remaining.
**
** The root page numbers of all tables in the database are integer
** values on the stack. This opcode pulls as many integers as it
@@ -4137,13 +4138,15 @@ case OP_DropTrigger: { /* no-push */
** If P2 is not zero, the check is done on the auxiliary database
** file, not the main database file.
**
-** This opcode is used for testing purposes only.
+** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
int nRoot;
int *aRoot;
int j;
+ int nErr;
char *z;
+ Mem *pnErr;
for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){
if( (pTos[-nRoot].flags & MEM_Int)==0 ) break;
@@ -4151,6 +4154,10 @@ case OP_IntegrityCk: {
assert( nRoot>0 );
aRoot = sqliteMallocRaw( sizeof(int*)*(nRoot+1) );
if( aRoot==0 ) goto no_mem;
+ j = pOp->p1;
+ assert( j>=0 && j<p->nMem );
+ pnErr = &p->aMem[j];
+ assert( (pnErr->flags & MEM_Int)!=0 );
for(j=0; j<nRoot; j++){
Mem *pMem = &pTos[-j];
aRoot[j] = pMem->i;
@@ -4158,12 +4165,12 @@ case OP_IntegrityCk: {
aRoot[j] = 0;
popStack(&pTos, nRoot);
pTos++;
- z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
- if( z==0 || z[0]==0 ){
- if( z ) sqliteFree(z);
- pTos->z = "ok";
- pTos->n = 2;
- pTos->flags = MEM_Str | MEM_Static | MEM_Term;
+ z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot,
+ pnErr->i, &nErr);
+ pnErr->i -= nErr;
+ if( nErr==0 ){
+ assert( z==0 );
+ pTos->flags = MEM_Null;
}else{
pTos->z = z;
pTos->n = strlen(z);
@@ -4499,6 +4506,7 @@ case OP_AggFinal: { /* no-push */
}
+#ifndef SQLITE_OMIT_VACUUM
/* Opcode: Vacuum * * *
**
** Vacuum the entire database. This opcode will cause other virtual
@@ -4511,6 +4519,7 @@ case OP_Vacuum: { /* no-push */
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
break;
}
+#endif
/* Opcode: Expire P1 * *
**
@@ -4672,9 +4681,9 @@ case OP_VFilter: { /* no-push */
assert( (pTos[0].flags&MEM_Int)!=0 && pTos[-1].flags==MEM_Int );
nArg = pTos[-1].i;
- /* Invoke the xFilter method if one is defined. */
- if( pModule->xFilter ){
- int res;
+ /* Invoke the xFilter method */
+ {
+ int res = 0;
int i;
Mem **apArg = p->apArg;
for(i = 0; i<nArg; i++){
@@ -4857,7 +4866,9 @@ case OP_VUpdate: { /* no-push */
apArg[i] = pX;
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
+ sqlite3VtabLock(pVtab);
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
+ sqlite3VtabUnlock(pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( pOp->p1 && rc==SQLITE_OK ){
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );