aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pragma.c18
-rw-r--r--src/sqlite.h.in3
-rw-r--r--src/vdbe.c40
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)
**