aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2010-04-24 14:02:59 +0000
committerdrh <drh@noemail.net>2010-04-24 14:02:59 +0000
commit545f587fc8564075dafeb6a324fde43079b87a11 (patch)
treea181c9e2d9078412105b37c69e6a95e2a1df31b0 /src
parent9a6e897328371a17f4ead1cd72c12240d372a81a (diff)
downloadsqlite-545f587fc8564075dafeb6a324fde43079b87a11.tar.gz
sqlite-545f587fc8564075dafeb6a324fde43079b87a11.zip
When commands such as ALTER TABLE and VACUUM use SQL internally, make sure
they use only the built-in functions and not application-defined overrides for those functions. FossilOrigin-Name: 0291ed974d5bf1e344e2c38422530cc961b897da
Diffstat (limited to 'src')
-rw-r--r--src/alter.c29
-rw-r--r--src/callback.c7
-rw-r--r--src/func.c6
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/vacuum.c2
5 files changed, 33 insertions, 14 deletions
diff --git a/src/alter.c b/src/alter.c
index 694b243bd..359c4e737 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -226,17 +226,23 @@ static void renameTriggerFunc(
/*
** Register built-in functions used to help implement ALTER TABLE
*/
-void sqlite3AlterFunctions(sqlite3 *db){
- sqlite3CreateFunc(db, "sqlite_rename_table", 2, SQLITE_UTF8, 0,
- renameTableFunc, 0, 0);
+void sqlite3AlterFunctions(void){
+ static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
+ FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
#ifndef SQLITE_OMIT_TRIGGER
- sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0,
- renameTriggerFunc, 0, 0);
+ FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
- sqlite3CreateFunc(db, "sqlite_rename_parent", 3, SQLITE_UTF8, 0,
- renameParentFunc, 0, 0);
+ FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
#endif
+ };
+ int i;
+ FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+ FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
+
+ for(i=0; i<ArraySize(aAlterTableFuncs); i++){
+ sqlite3FuncDefInsert(pHash, &aFunc[i]);
+ }
}
/*
@@ -380,7 +386,9 @@ void sqlite3AlterRenameTable(
char *zWhere = 0; /* Where clause to locate temp triggers */
#endif
VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */
-
+ int savedDbFlags; /* Saved value of db->flags */
+
+ savedDbFlags = db->flags;
if( NEVER(db->mallocFailed) ) goto exit_rename_table;
assert( pSrc->nSrc==1 );
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
@@ -389,6 +397,7 @@ void sqlite3AlterRenameTable(
if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
zDb = db->aDb[iDb].zName;
+ db->flags |= SQLITE_PreferBuiltin;
/* Get a NULL terminated version of the new table name. */
zName = sqlite3NameFromToken(db, pName);
@@ -556,6 +565,7 @@ void sqlite3AlterRenameTable(
exit_rename_table:
sqlite3SrcListDelete(db, pSrc);
sqlite3DbFree(db, zName);
+ db->flags = savedDbFlags;
}
@@ -675,9 +685,11 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
char *zEnd = &zCol[pColDef->n-1];
+ int savedDbFlags = db->flags;
while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
*zEnd-- = '\0';
}
+ db->flags |= SQLITE_PreferBuiltin;
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
@@ -686,6 +698,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
zTab
);
sqlite3DbFree(db, zCol);
+ db->flags = savedDbFlags;
}
/* If the default value of the new column is NULL, then set the file
diff --git a/src/callback.c b/src/callback.c
index e6c51bccd..c016959fd 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -353,14 +353,19 @@ FuncDef *sqlite3FindFunction(
/* If no match is found, search the built-in functions.
**
+ ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
+ ** functions even if a prior app-defined function was found. And give
+ ** priority to built-in functions.
+ **
** Except, if createFlag is true, that means that we are trying to
** install a new function. Whatever FuncDef structure is returned will
** have fields overwritten with new information appropriate for the
** new function. But the FuncDefs for built-in functions are read-only.
** So we must not search for built-ins when creating a new function.
*/
- if( !createFlag && !pBest ){
+ if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+ bestScore = 0;
p = functionSearch(pHash, h, zName, nName);
while( p ){
int score = matchQuality(p, nArg, enc);
diff --git a/src/func.c b/src/func.c
index 7ff1fecb0..7bd3d58fa 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1416,9 +1416,6 @@ static void groupConcatFinalize(sqlite3_context *context){
** external linkage.
*/
void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
-#ifndef SQLITE_OMIT_ALTERTABLE
- sqlite3AlterFunctions(db);
-#endif
if( !db->mallocFailed ){
int rc = sqlite3_overload_function(db, "MATCH", 2);
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
@@ -1592,4 +1589,7 @@ void sqlite3RegisterGlobalFunctions(void){
sqlite3FuncDefInsert(pHash, &aFunc[i]);
}
sqlite3RegisterDateTimeFunctions();
+#ifndef SQLITE_OMIT_ALTERTABLE
+ sqlite3AlterFunctions();
+#endif
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 6007b8af9..6e6ec72ac 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -913,6 +913,7 @@ struct sqlite3 {
#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */
+#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */
/*
** Bits of the sqlite3.flags field that are used by the
@@ -2881,7 +2882,7 @@ extern int sqlite3PendingByte;
#endif
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
-void sqlite3AlterFunctions(sqlite3*);
+void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
diff --git a/src/vacuum.c b/src/vacuum.c
index 1d3b998c6..12a07e9c8 100644
--- a/src/vacuum.c
+++ b/src/vacuum.c
@@ -117,7 +117,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_xTrace = db->xTrace;
- db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
db->xTrace = 0;