diff options
author | drh <drh@noemail.net> | 2010-04-24 14:02:59 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2010-04-24 14:02:59 +0000 |
commit | 545f587fc8564075dafeb6a324fde43079b87a11 (patch) | |
tree | a181c9e2d9078412105b37c69e6a95e2a1df31b0 /src | |
parent | 9a6e897328371a17f4ead1cd72c12240d372a81a (diff) | |
download | sqlite-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.c | 29 | ||||
-rw-r--r-- | src/callback.c | 7 | ||||
-rw-r--r-- | src/func.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/vacuum.c | 2 |
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; |