diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/vdbe.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/src/vdbe.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/vdbe.c b/ext/pdo_sqlite/sqlite/src/vdbe.c index cab35069cc..9bbc65a2eb 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbe.c +++ b/ext/pdo_sqlite/sqlite/src/vdbe.c @@ -2521,7 +2521,23 @@ 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); + /* If the schema-cookie from the database file matches the cookie + ** stored with the in-memory representation of the schema, do + ** not reload the schema from the database file. + ** + ** If virtual-tables are in use, this is not just an optimisation. + ** Often, v-tables store their data in other SQLite tables, which + ** are queried from within xNext() and other v-table methods using + ** prepared queries. If such a query is out-of-date, we do not want to + ** discard the database schema, as the user code implementing the + ** v-table would have to be ready for the sqlite3_vtab structure itself + ** to be invalidated whenever sqlite3_step() is called from within + ** a v-table method. + */ + if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ + sqlite3ResetInternalSchema(db, pOp->p1); + } + sqlite3ExpirePreparedStatements(db); rc = SQLITE_SCHEMA; } @@ -4881,7 +4897,7 @@ case OP_VUpdate: { /* no-push */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; sqlite3VtabLock(pVtab); rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); - sqlite3VtabUnlock(pVtab); + sqlite3VtabUnlock(db, 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) ); |
