First the shadow table mechanism so that it works even if the shadow table
comes before the virtual table in the sqlite_schema table, as can happen after a VACUUM. FossilOrigin-Name: 005a8642773556825fe4c5d0b2c12517d35289308a30df0151ef7f080acb0172
This commit is contained in:
+39
-6
@@ -2492,6 +2492,40 @@ int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
|
||||
}
|
||||
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/*
|
||||
** Table pTab is a virtual table. If it the virtual table implementation
|
||||
** exists and has an xShadowName method, then loop over all other ordinary
|
||||
** tables within the same schema looking for shadow tables of pTab, and mark
|
||||
** any shadow tables seen using the TF_Shadow flag.
|
||||
*/
|
||||
void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){
|
||||
int nName; /* Length of pTab->zName */
|
||||
Module *pMod; /* Module for the virtual table */
|
||||
HashElem *k; /* For looping through the symbol table */
|
||||
|
||||
assert( IsVirtual(pTab) );
|
||||
pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]);
|
||||
if( pMod==0 ) return;
|
||||
if( NEVER(pMod->pModule==0) ) return;
|
||||
if( pMod->pModule->xShadowName==0 ) return;
|
||||
assert( pTab->zName!=0 );
|
||||
nName = sqlite3Strlen30(pTab->zName);
|
||||
for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){
|
||||
Table *pOther = sqliteHashData(k);
|
||||
assert( pOther->zName!=0 );
|
||||
if( !IsOrdinaryTable(pOther) ) continue;
|
||||
if( pOther->tabFlags & TF_Shadow ) continue;
|
||||
if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0
|
||||
&& pOther->zName[nName]=='_'
|
||||
&& pMod->pModule->xShadowName(pOther->zName+nName+1)
|
||||
){
|
||||
pOther->tabFlags |= TF_Shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/*
|
||||
** Return true if zName is a shadow table name in the current database
|
||||
@@ -3006,13 +3040,12 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
assert( pTable );
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
db->nSchemaLock++;
|
||||
rc = sqlite3VtabCallConnect(pParse, pTable);
|
||||
db->nSchemaLock--;
|
||||
if( rc ){
|
||||
return 1;
|
||||
if( IsVirtual(pTable) ){
|
||||
db->nSchemaLock++;
|
||||
rc = sqlite3VtabCallConnect(pParse, pTable);
|
||||
db->nSchemaLock--;
|
||||
return rc;
|
||||
}
|
||||
if( IsVirtual(pTable) ) return 0;
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_VIEW
|
||||
|
||||
@@ -5050,9 +5050,11 @@ int sqlite3ReadOnlyShadowTables(sqlite3 *db);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
|
||||
int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
|
||||
void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*);
|
||||
#else
|
||||
# define sqlite3ShadowTableName(A,B) 0
|
||||
# define sqlite3IsShadowTableOf(A,B,C) 0
|
||||
# define sqlite3MarkAllShadowTablesOf(A,B)
|
||||
#endif
|
||||
int sqlite3VtabEponymousTableInit(Parse*,Module*);
|
||||
void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
|
||||
|
||||
+5
-9
@@ -505,18 +505,14 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
||||
iReg = ++pParse->nMem;
|
||||
sqlite3VdbeLoadString(v, iReg, pTab->zName);
|
||||
sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
|
||||
}
|
||||
|
||||
/* If we are rereading the sqlite_schema table create the in-memory
|
||||
** record of the table. The xConnect() method is not called until
|
||||
** the first time the virtual table is used in an SQL statement. This
|
||||
** allows a schema that contains virtual tables to be loaded before
|
||||
** the required virtual table implementations are registered. */
|
||||
else {
|
||||
}else{
|
||||
/* If we are rereading the sqlite_schema table create the in-memory
|
||||
** record of the table. */
|
||||
Table *pOld;
|
||||
Schema *pSchema = pTab->pSchema;
|
||||
const char *zName = pTab->zName;
|
||||
assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
|
||||
assert( zName!=0 );
|
||||
sqlite3MarkAllShadowTablesOf(db, pTab);
|
||||
pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
|
||||
if( pOld ){
|
||||
sqlite3OomFault(db);
|
||||
|
||||
Reference in New Issue
Block a user