Upgrade SQLite to 3.40 (#699)

This commit is contained in:
Paul Kulchenko 2022-11-28 12:54:48 -08:00 committed by GitHub
parent bcae817215
commit 0dc0758574
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
151 changed files with 27917 additions and 22169 deletions

View file

@ -12,8 +12,7 @@
** This file contains code used to help implement virtual tables.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "third_party/sqlite3/sqliteInt.inc"
/* clang-format off */
#include "third_party/sqlite3/sqliteInt.h"
/*
** Before a virtual table xCreate() or xConnect() method is invoked, the
@ -193,7 +192,7 @@ void sqlite3VtabLock(VTable *pVTab){
VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
VTable *pVtab;
assert( IsVirtual(pTab) );
for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
for(pVtab=pTab->u.vtab.p; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
return pVtab;
}
@ -206,7 +205,8 @@ void sqlite3VtabUnlock(VTable *pVTab){
assert( db );
assert( pVTab->nRef>0 );
assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE );
assert( db->eOpenState==SQLITE_STATE_OPEN
|| db->eOpenState==SQLITE_STATE_ZOMBIE );
pVTab->nRef--;
if( pVTab->nRef==0 ){
@ -221,21 +221,24 @@ void sqlite3VtabUnlock(VTable *pVTab){
/*
** Table p is a virtual table. This function moves all elements in the
** p->pVTable list to the sqlite3.pDisconnect lists of their associated
** p->u.vtab.p list to the sqlite3.pDisconnect lists of their associated
** database connections to be disconnected at the next opportunity.
** Except, if argument db is not NULL, then the entry associated with
** connection db is left in the p->pVTable list.
** connection db is left in the p->u.vtab.p list.
*/
static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
VTable *pRet = 0;
VTable *pVTable = p->pVTable;
p->pVTable = 0;
VTable *pVTable;
assert( IsVirtual(p) );
pVTable = p->u.vtab.p;
p->u.vtab.p = 0;
/* Assert that the mutex (if any) associated with the BtShared database
** that contains table p is held by the caller. See header comments
** above function sqlite3VtabUnlockList() for an explanation of why
** this makes it safe to access the sqlite3.pDisconnect list of any
** database connection that may have an entry in the p->pVTable list.
** database connection that may have an entry in the p->u.vtab.p list.
*/
assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
@ -245,7 +248,7 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
assert( db2 );
if( db2==db ){
pRet = pVTable;
p->pVTable = pRet;
p->u.vtab.p = pRet;
pRet->pNext = 0;
}else{
pVTable->pNext = db2->pDisconnect;
@ -273,7 +276,7 @@ void sqlite3VtabDisconnect(sqlite3 *db, Table *p){
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3_mutex_held(db->mutex) );
for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){
for(ppVTab=&p->u.vtab.p; *ppVTab; ppVTab=&(*ppVTab)->pNext){
if( (*ppVTab)->db==db ){
VTable *pVTab = *ppVTab;
*ppVTab = pVTab->pNext;
@ -336,37 +339,42 @@ void sqlite3VtabUnlockList(sqlite3 *db){
** database connection.
*/
void sqlite3VtabClear(sqlite3 *db, Table *p){
if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
if( p->azModuleArg ){
assert( IsVirtual(p) );
assert( db!=0 );
if( db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
if( p->u.vtab.azArg ){
int i;
for(i=0; i<p->nModuleArg; i++){
if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
for(i=0; i<p->u.vtab.nArg; i++){
if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]);
}
sqlite3DbFree(db, p->azModuleArg);
sqlite3DbFree(db, p->u.vtab.azArg);
}
}
/*
** Add a new module argument to pTable->azModuleArg[].
** Add a new module argument to pTable->u.vtab.azArg[].
** The string is not copied - the pointer is stored. The
** string will be freed automatically when the table is
** deleted.
*/
static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){
sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg);
sqlite3_int64 nBytes;
char **azModuleArg;
sqlite3 *db = pParse->db;
if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
assert( IsVirtual(pTable) );
nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg);
if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName);
}
azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes);
if( azModuleArg==0 ){
sqlite3DbFree(db, zArg);
}else{
int i = pTable->nModuleArg++;
int i = pTable->u.vtab.nArg++;
azModuleArg[i] = zArg;
azModuleArg[i+1] = 0;
pTable->azModuleArg = azModuleArg;
pTable->u.vtab.azArg = azModuleArg;
}
}
@ -389,10 +397,11 @@ void sqlite3VtabBeginParse(
pTable = pParse->pNewTable;
if( pTable==0 ) return;
assert( 0==pTable->pIndex );
pTable->eTabType = TABTYP_VTAB;
db = pParse->db;
assert( pTable->nModuleArg==0 );
assert( pTable->u.vtab.nArg==0 );
addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(pParse, pTable, 0);
addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName));
@ -409,11 +418,11 @@ void sqlite3VtabBeginParse(
** sqlite_schema table, has already been made by sqlite3StartTable().
** The second call, to obtain permission to create the table, is made now.
*/
if( pTable->azModuleArg ){
if( pTable->u.vtab.azArg ){
int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
assert( iDb>=0 ); /* The database the table is being created in */
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
pTable->u.vtab.azArg[0], pParse->db->aDb[iDb].zDbSName);
}
#endif
}
@ -441,9 +450,10 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
sqlite3 *db = pParse->db; /* The database connection */
if( pTab==0 ) return;
assert( IsVirtual(pTab) );
addArgumentToVtab(pParse);
pParse->sArg.z = 0;
if( pTab->nModuleArg<1 ) return;
if( pTab->u.vtab.nArg<1 ) return;
/* If the CREATE VIRTUAL TABLE statement is being entered for the
** first time (in other words if the virtual table is actually being
@ -476,7 +486,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
*/
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3NestedParse(pParse,
"UPDATE %Q." DFLT_SCHEMA_TABLE " "
"UPDATE %Q." LEGACY_SCHEMA_TABLE " "
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
"WHERE rowid=#%d",
db->aDb[iDb].zDbSName,
@ -496,18 +506,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);
@ -558,13 +564,16 @@ static int vtabCallConstructor(
VtabCtx sCtx;
VTable *pVTable;
int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg;
const char *const*azArg;
int nArg = pTab->u.vtab.nArg;
char *zErr = 0;
char *zModuleName;
int iDb;
VtabCtx *pCtx;
assert( IsVirtual(pTab) );
azArg = (const char *const*)pTab->u.vtab.azArg;
/* Check that the virtual-table is not already being initialized */
for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
if( pCtx->pTab==pTab ){
@ -591,7 +600,7 @@ static int vtabCallConstructor(
pVTable->eVtabRisk = SQLITE_VTABRISK_Normal;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pTab->azModuleArg[1] = db->aDb[iDb].zDbSName;
pTab->u.vtab.azArg[1] = db->aDb[iDb].zDbSName;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
@ -630,12 +639,12 @@ static int vtabCallConstructor(
int iCol;
u16 oooHidden = 0;
/* If everything went according to plan, link the new VTable structure
** into the linked list headed by pTab->pVTable. Then loop through the
** into the linked list headed by pTab->u.vtab.p. Then loop through the
** columns of the table to see if any of them contain the token "hidden".
** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
** the type string. */
pVTable->pNext = pTab->pVTable;
pTab->pVTable = pVTable;
pVTable->pNext = pTab->u.vtab.p;
pTab->u.vtab.p = pVTable;
for(iCol=0; iCol<pTab->nCol; iCol++){
char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
@ -688,16 +697,17 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
int rc;
assert( pTab );
if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
assert( IsVirtual(pTab) );
if( sqlite3GetVTable(db, pTab) ){
return SQLITE_OK;
}
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
zMod = pTab->u.vtab.azArg[0];
pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
if( !pMod ){
const char *zModule = pTab->azModuleArg[0];
const char *zModule = pTab->u.vtab.azArg[0];
sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
rc = SQLITE_ERROR;
}else{
@ -760,10 +770,10 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
const char *zMod;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
assert( pTab && IsVirtual(pTab) && !pTab->u.vtab.p );
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
zMod = pTab->u.vtab.azArg[0];
pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
/* If the module has been registered and includes a Create method,
@ -798,8 +808,8 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
VtabCtx *pCtx;
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
Parse sParse;
int initBusy;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
@ -816,20 +826,27 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
pTab = pCtx->pTab;
assert( IsVirtual(pTab) );
memset(&sParse, 0, sizeof(sParse));
sqlite3ParseObjectInit(&sParse, db);
sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
sParse.db = db;
sParse.disableTriggers = 1;
/* We should never be able to reach this point while loading the
** schema. Nevertheless, defend against that (turn off db->init.busy)
** in case a bug arises. */
assert( db->init.busy==0 );
initBusy = db->init.busy;
db->init.busy = 0;
sParse.nQueryLoop = 1;
if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr)
&& sParse.pNewTable
&& !db->mallocFailed
&& !sParse.pNewTable->pSelect
&& !IsVirtual(sParse.pNewTable)
if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable)
&& ALWAYS(sParse.pNewTable!=0)
&& ALWAYS(!db->mallocFailed)
&& IsOrdinaryTable(sParse.pNewTable)
){
assert( sParse.zErrMsg==0 );
if( !pTab->aCol ){
Table *pNew = sParse.pNewTable;
Index *pIdx;
pTab->aCol = pNew->aCol;
sqlite3ExprListDelete(db, pNew->u.tab.pDfltList);
pTab->nNVCol = pTab->nCol = pNew->nCol;
pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
pNew->nCol = 0;
@ -854,8 +871,9 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
}
pCtx->bDeclared = 1;
}else{
sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
sqlite3ErrorWithMsg(db, SQLITE_ERROR,
(sParse.zErrMsg ? "%s" : 0), sParse.zErrMsg);
sqlite3DbFree(db, sParse.zErrMsg);
rc = SQLITE_ERROR;
}
sParse.eParseMode = PARSE_MODE_NORMAL;
@ -864,7 +882,8 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
sqlite3VdbeFinalize(sParse.pVdbe);
}
sqlite3DeleteTable(db, sParse.pNewTable);
sqlite3ParserReset(&sParse);
sqlite3ParseObjectReset(&sParse);
db->init.busy = initBusy;
assert( (rc&0xff)==rc );
rc = sqlite3ApiExit(db, rc);
@ -884,10 +903,13 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
Table *pTab;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){
if( ALWAYS(pTab!=0)
&& ALWAYS(IsVirtual(pTab))
&& ALWAYS(pTab->u.vtab.p!=0)
){
VTable *p;
int (*xDestroy)(sqlite3_vtab *);
for(p=pTab->pVTable; p; p=p->pNext){
for(p=pTab->u.vtab.p; p; p=p->pNext){
assert( p->pVtab );
if( p->pVtab->nRef>0 ){
return SQLITE_LOCKED;
@ -901,9 +923,9 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
assert( pTab->pVTable==p && p->pNext==0 );
assert( pTab->u.vtab.p==p && p->pNext==0 );
p->pVtab = 0;
pTab->pVTable = 0;
pTab->u.vtab.p = 0;
sqlite3VtabUnlock(p);
}
sqlite3DeleteTable(db, pTab);
@ -1117,8 +1139,9 @@ FuncDef *sqlite3VtabOverloadFunction(
/* Check to see the left operand is a column in a virtual table */
if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab;
if( pTab==0 ) return pDef;
if( NEVER(pTab==0) ) return pDef;
if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
assert( pVtab!=0 );
@ -1191,8 +1214,9 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
/*
** Check to see if virtual table 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.
** exist. Return non-zero if either the eponymous virtual table instance
** exists when this routine returns or if an attempt to create it failed
** and an error message was left in pParse.
**
** An eponymous virtual table instance is one that is named after its
** module, and more importantly, does not require a CREATE VIRTUAL TABLE
@ -1219,9 +1243,11 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
}
pMod->pEpoTab = pTab;
pTab->nTabRef = 1;
pTab->eTabType = TABTYP_VTAB;
pTab->pSchema = db->aDb[0].pSchema;
assert( pTab->nModuleArg==0 );
assert( pTab->u.vtab.nArg==0 );
pTab->iPKey = -1;
pTab->tabFlags |= TF_Eponymous;
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(pParse, pTab, 0);
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
@ -1230,7 +1256,6 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
sqlite3ErrorMsg(pParse, "%s", zErr);
sqlite3DbFree(db, zErr);
sqlite3VtabEponymousTableClear(db, pMod);
return 0;
}
return 1;
}