mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Initial implementation of eponymous virtual table instances.
FossilOrigin-Name: c1f43a7799a9298abea01b2f8531fc7cdadc4594
This commit is contained in:
62
src/vtab.c
62
src/vtab.c
@@ -58,6 +58,7 @@ static int createModule(
|
||||
pMod->pModule = pModule;
|
||||
pMod->pAux = pAux;
|
||||
pMod->xDestroy = xDestroy;
|
||||
pMod->pEpoTab = 0;
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
|
||||
assert( pDel==0 || pDel==pMod );
|
||||
if( pDel ){
|
||||
@@ -275,6 +276,7 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){
|
||||
if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
|
||||
}
|
||||
sqlite3DbFree(db, p->azModuleArg);
|
||||
p->azModuleArg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1092,6 +1094,66 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if virtual tale module pMod can be have an eponymous
|
||||
** virtual table instance. If it can, create one if one does not already
|
||||
** exist. Return non-zero if the eponymous virtual table instance exists
|
||||
** when this routine returns, and return zero if it does not exist.
|
||||
**
|
||||
** An eponymous virtual table instance is one that is named after its
|
||||
** module, and more importantly, does not require a CREATE VIRTUAL TABLE
|
||||
** statement in order to come into existance. Eponymous virtual table
|
||||
** instances always exist. They cannot be DROP-ed.
|
||||
**
|
||||
** Any virtual table module for which xConnect and xCreate are the same
|
||||
** method can have an eponymous virtual table instance.
|
||||
*/
|
||||
int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
|
||||
const sqlite3_module *pModule = pMod->pModule;
|
||||
Table *pTab;
|
||||
char *zErr = 0;
|
||||
int nName;
|
||||
int rc;
|
||||
sqlite3 *db = pParse->db;
|
||||
if( pMod->pEpoTab ) return 1;
|
||||
if( pModule->xCreate!=pModule->xConnect ) return 0;
|
||||
nName = sqlite3Strlen30(pMod->zName) + 1;
|
||||
pTab = sqlite3DbMallocZero(db, sizeof(Table) + nName);
|
||||
if( pTab==0 ) return 0;
|
||||
pMod->pEpoTab = pTab;
|
||||
pTab->zName = (char*)&pTab[1];
|
||||
memcpy(pTab->zName, pMod->zName, nName);
|
||||
pTab->nRef = 1;
|
||||
pTab->pSchema = db->aDb[0].pSchema;
|
||||
pTab->tabFlags |= TF_Virtual;
|
||||
pTab->nModuleArg = 0;
|
||||
addModuleArgument(db, pTab, pTab->zName);
|
||||
addModuleArgument(db, pTab, 0);
|
||||
addModuleArgument(db, pTab, pTab->zName);
|
||||
rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
|
||||
if( rc ){
|
||||
sqlite3ErrorMsg(pParse, "%s", zErr);
|
||||
sqlite3DbFree(db, zErr);
|
||||
sqlite3VtabEponymousTableClear(db, pMod);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Erase the eponymous virtual table instance associated with
|
||||
** virtual table module pMod, if it exists.
|
||||
*/
|
||||
void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
|
||||
Table *pTab = pMod->pEpoTab;
|
||||
if( (pTab = pMod->pEpoTab)!=0 ){
|
||||
sqlite3DeleteColumnNames(db, pTab);
|
||||
sqlite3DbFree(db, pTab->azModuleArg);
|
||||
sqlite3DbFree(db, pTab);
|
||||
pMod->pEpoTab = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the ON CONFLICT resolution mode in effect for the virtual
|
||||
** table update operation currently in progress.
|
||||
|
Reference in New Issue
Block a user