diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pragma.c | 18 | ||||
-rw-r--r-- | src/sqlite.h.in | 3 | ||||
-rw-r--r-- | src/vdbe.c | 40 |
3 files changed, 60 insertions, 1 deletions
diff --git a/src/pragma.c b/src/pragma.c index f15c1be27..a4e05bbdf 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1757,8 +1757,24 @@ void sqlite3Pragma( int r2; /* Previous key for WITHOUT ROWID tables */ int mxCol; /* Maximum non-virtual column number */ - if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; + if( !IsOrdinaryTable(pTab) ){ + sqlite3_vtab *pVTab; + int a1; + if( !IsVirtual(pTab) ) continue; + if( pTab->u.vtab.p==0 ) continue; + pVTab = pTab->u.vtab.p->pVtab; + if( NEVER(pVTab==0) ) continue; + if( NEVER(pVTab->pModule==0) ) continue; + if( pVTab->pModule->iVersion<4 ) continue; + if( pVTab->pModule->xIntegrity==0 ) continue; + sqlite3VdbeAddOp2(v, OP_VCheck, 0, 3); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + continue; + } if( isQuick || HasRowid(pTab) ){ pPk = 0; r2 = 0; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 48009b145..9ffbb63b2 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7217,6 +7217,9 @@ struct sqlite3_module { /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); + /* The methods above are in versions 1 through 3 of the sqlite_module object. + ** Those below are for version 4 and greater. */ + int (*xIntegrity)(sqlite3_vtab *pVTab, char**); }; /* diff --git a/src/vdbe.c b/src/vdbe.c index 4e681d41c..eccd5291e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -8129,6 +8129,46 @@ case OP_VOpen: { /* ncycle */ #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCheck * P2 * P4 * +** +** P4 is a pointer to a Table object that is a virtual table that +** supports the xIntegrity() method. This opcode runs the xIntegrity() +** method for that virtual table. If an error is reported back, the error +** message is stored in register P2. If no errors are seen, register P2 +** is set to NULL. +*/ +case OP_VCheck: { /* out2 */ + Table *pTab; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + char *zErr = 0; + + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ + assert( pOp->p4type==P4_TABLE ); + pTab = pOp->p4.pTab; + assert( pTab!=0 ); + assert( IsVirtual(pTab) ); + assert( pTab->u.vtab.p!=0 ); + pVtab = pTab->u.vtab.p->pVtab; + assert( pVtab!=0 ); + pModule = pVtab->pModule; + assert( pModule!=0 ); + assert( pModule->iVersion>=4 ); + assert( pModule->xIntegrity!=0 ); + rc = pModule->xIntegrity(pVtab, &zErr); + if( rc ){ + sqlite3_free(zErr); + goto abort_due_to_error; + } + if( zErr ){ + sqlite3VdbeMemSetStr(pOut, zErr, -1, SQLITE_UTF8, sqlite3_free); + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VInitIn P1 P2 P3 * * ** Synopsis: r[P2]=ValueList(P1,P3) ** |