99 lines
3.5 KiB
Diff
99 lines
3.5 KiB
Diff
|
Subject: [PATCH] Do not allow a virtual table to be renamed into the name of
|
||
|
one of its shadows.
|
||
|
|
||
|
---
|
||
|
src/alter.c | 5 ++++-
|
||
|
src/build.c | 29 +++++++++++++++++++++++------
|
||
|
src/sqliteInt.h | 5 +++++
|
||
|
3 files changed, 32 insertions(+), 7 deletions(-)
|
||
|
|
||
|
diff --git a/src/alter.c b/src/alter.c
|
||
|
index 1280e90..0fa24c0 100644
|
||
|
--- a/src/alter.c
|
||
|
+++ b/src/alter.c
|
||
|
@@ -117,7 +117,10 @@ void sqlite3AlterRenameTable(
|
||
|
/* Check that a table or index named 'zName' does not already exist
|
||
|
** in database iDb. If so, this is an error.
|
||
|
*/
|
||
|
- if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
|
||
|
+ if( sqlite3FindTable(db, zName, zDb)
|
||
|
+ || sqlite3FindIndex(db, zName, zDb)
|
||
|
+ || sqlite3IsShadowTableOf(db, pTab, zName)
|
||
|
+ ){
|
||
|
sqlite3ErrorMsg(pParse,
|
||
|
"there is already another table or index with this name: %s", zName);
|
||
|
goto exit_rename_table;
|
||
|
diff --git a/src/build.c b/src/build.c
|
||
|
index e0fed8a..afe4171 100644
|
||
|
--- a/src/build.c
|
||
|
+++ b/src/build.c
|
||
|
@@ -1899,6 +1899,28 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||
|
recomputeColumnsNotIndexed(pPk);
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||
|
+/*
|
||
|
+** Return true if pTab is a virtual table and zName is a shadow table name
|
||
|
+** for that virtual table.
|
||
|
+*/
|
||
|
+int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
|
||
|
+ int nName; /* Length of zName */
|
||
|
+ Module *pMod; /* Module for the virtual table */
|
||
|
+
|
||
|
+ if( !IsVirtual(pTab) ) return 0;
|
||
|
+ nName = sqlite3Strlen30(pTab->zName);
|
||
|
+ if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0;
|
||
|
+ if( zName[nName]!='_' ) return 0;
|
||
|
+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
|
||
|
+ if( pMod==0 ) return 0;
|
||
|
+ if( pMod->pModule->iVersion<3 ) return 0;
|
||
|
+ if( pMod->pModule->xShadowName==0 ) return 0;
|
||
|
+ return pMod->pModule->xShadowName(zName+nName+1);
|
||
|
+}
|
||
|
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
|
||
|
+
|
||
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||
|
/*
|
||
|
** Return true if zName is a shadow table name in the current database
|
||
|
@@ -1910,7 +1932,6 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||
|
static int isShadowTableName(sqlite3 *db, char *zName){
|
||
|
char *zTail; /* Pointer to the last "_" in zName */
|
||
|
Table *pTab; /* Table that zName is a shadow of */
|
||
|
- Module *pMod; /* Module for the virtual table */
|
||
|
|
||
|
zTail = strrchr(zName, '_');
|
||
|
if( zTail==0 ) return 0;
|
||
|
@@ -1919,11 +1940,7 @@ static int isShadowTableName(sqlite3 *db, char *zName){
|
||
|
*zTail = '_';
|
||
|
if( pTab==0 ) return 0;
|
||
|
if( !IsVirtual(pTab) ) return 0;
|
||
|
- pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
|
||
|
- if( pMod==0 ) return 0;
|
||
|
- if( pMod->pModule->iVersion<3 ) return 0;
|
||
|
- if( pMod->pModule->xShadowName==0 ) return 0;
|
||
|
- return pMod->pModule->xShadowName(zTail+1);
|
||
|
+ return sqlite3IsShadowTableOf(db, pTab, zName);
|
||
|
}
|
||
|
#else
|
||
|
# define isShadowTableName(x,y) 0
|
||
|
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
|
||
|
index b7d3571..76337f7 100644
|
||
|
--- a/src/sqliteInt.h
|
||
|
+++ b/src/sqliteInt.h
|
||
|
@@ -4407,6 +4407,11 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||
|
);
|
||
|
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
|
||
|
#endif
|
||
|
+#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||
|
+ int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
|
||
|
+#else
|
||
|
+# define sqlite3IsShadowTableOf(A,B,C) 0
|
||
|
+#endif
|
||
|
int sqlite3VtabEponymousTableInit(Parse*,Module*);
|
||
|
void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
|
||
|
void sqlite3VtabMakeWritable(Parse*,Table*);
|
||
|
--
|
||
|
2.24.1
|
||
|
|