From 9ccd8659ff397dc03dd2c40f8d13e12d5445c01f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Sep 2013 16:36:46 +0000 Subject: [PATCH] Change the PRAGMA parser to use a binary search for the pragma name. Also: Minor performance enhancement to sqlite3DbFree() and to the token dequoter. FossilOrigin-Name: 870c030b4e1854e6e0d39907fadbd82774c16f56 --- manifest | 19 +- manifest.uuid | 2 +- src/malloc.c | 1 + src/pragma.c | 634 ++++++++++++++++++++++++++++--------------- src/util.c | 3 +- tool/mkpragmatab.tcl | 335 +++++++++++++++++++++++ 6 files changed, 768 insertions(+), 226 deletions(-) create mode 100644 tool/mkpragmatab.tcl diff --git a/manifest b/manifest index aed27695f1..8364ee9131 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sthe\sfts4\sunicode61\stokenchars\sand\sseparators\soptions. -D 2013-09-13T12:10:09.872 +C Change\sthe\sPRAGMA\sparser\sto\suse\sa\sbinary\ssearch\sfor\sthe\spragma\sname.\nAlso:\s\sMinor\sperformance\senhancement\sto\ssqlite3DbFree()\sand\sto\sthe\ntoken\sdequoter. +D 2013-09-13T16:36:46.969 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -186,7 +186,7 @@ F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 F src/main.c 35931467ec026b05babb279cb8a573e62f6fe1a3 -F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 +F src/malloc.c 543a8eb5508eaf4cadf55a9b503379eba2088128 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f @@ -210,7 +210,7 @@ F src/parse.y 27c6b4138497d6f8360ba7847da6ed48033f957f F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 -F src/pragma.c 3aa3d8c8623b7b71c5b1bfb72dcc31fb0c25665f +F src/pragma.c 49612a5c35fe0139a4b2e5fb0b7ee74d8a3a42b9 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 @@ -275,7 +275,7 @@ F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2 F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e F src/update.c f5182157f5d0d0a97bc5f5e3c9bdba0dfbe08f08 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 +F src/util.c 7f3e35432d6888d1e770c488c35bd98970c44eec F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 F src/vdbe.c a393a94c0d77b86c7c4ad2cfb43ec4ba278d9596 F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4 @@ -1080,6 +1080,7 @@ F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkpragmatab.tcl b45b0770c9be2b693911d19adc6056c6d9c9276b F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 F tool/mksqlite3c.tcl d344cc3144a0271cd853c5e3df36e9f31d78d619 @@ -1112,7 +1113,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 73634ca463f46027bfa8ea23f18abaa530460e24 -R 4220c723ebfba5175f5b35a4f736cee8 -U dan -Z ceac464bf6cfcc5f50757139a5d63046 +P 9ce6f40dfb54b35cecba3cc9c1ec0d111f6e9f11 +R eb0f561b34214cdc0ff256f03a4cb3be +U drh +Z 21cd5712344a4e80033620b1f645dca4 diff --git a/manifest.uuid b/manifest.uuid index 1700974c76..bfbcc6abb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ce6f40dfb54b35cecba3cc9c1ec0d111f6e9f11 \ No newline at end of file +870c030b4e1854e6e0d39907fadbd82774c16f56 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 35a44e5f61..799f0485d4 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -484,6 +484,7 @@ void sqlite3_free(void *p){ */ void sqlite3DbFree(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( p==0 ) return; if( db ){ if( db->pnBytesFreed ){ *db->pnBytesFreed += sqlite3DbMallocSize(db, p); diff --git a/src/pragma.c b/src/pragma.c index d4cf597ff8..a73c59a078 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -13,6 +13,232 @@ */ #include "sqliteInt.h" +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/*************************************************************************** +** The next block of code, including the PragTyp_XXXX macro definitions and +** the aPragmaName[] object is composed of generated code. DO NOT EDIT. +** +** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun +** that script. Then copy/paste the output in place of the following: +*/ +#define PragTyp_HEADER_VALUE 0 +#define PragTyp_AUTO_VACUUM 1 +#define PragTyp_FLAG 2 +#define PragTyp_BUSY_TIMEOUT 3 +#define PragTyp_CACHE_SIZE 4 +#define PragTyp_CASE_SENSITIVE_LIKE 5 +#define PragTyp_COLLATION_LIST 6 +#define PragTyp_COMPILE_OPTIONS 7 +#define PragTyp_DATA_STORE_DIRECTORY 8 +#define PragTyp_DATABASE_LIST 9 +#define PragTyp_DEFAULT_CACHE_SIZE 10 +#define PragTyp_ENCODING 11 +#define PragTyp_FOREIGN_KEY_CHECK 12 +#define PragTyp_FOREIGN_KEY_LIST 13 +#define PragTyp_INCREMENTAL_VACUUM 14 +#define PragTyp_INDEX_INFO 15 +#define PragTyp_INDEX_LIST 16 +#define PragTyp_INTEGRITY_CHECK 17 +#define PragTyp_JOURNAL_MODE 18 +#define PragTyp_JOURNAL_SIZE_LIMIT 19 +#define PragTyp_LOCK_PROXY_FILE 20 +#define PragTyp_LOCKING_MODE 21 +#define PragTyp_PAGE_COUNT 22 +#define PragTyp_MMAP_SIZE 23 +#define PragTyp_PAGE_SIZE 24 +#define PragTyp_SECURE_DELETE 25 +#define PragTyp_SHRINK_MEMORY 26 +#define PragTyp_SYNCHRONOUS 27 +#define PragTyp_TABLE_INFO 28 +#define PragTyp_TEMP_STORE 29 +#define PragTyp_TEMP_STORE_DIRECTORY 30 +#define PragTyp_WAL_AUTOCHECKPOINT 31 +#define PragTyp_WAL_CHECKPOINT 32 +#define PragTyp_ACTIVATE_EXTENSIONS 33 +#define PragTyp_HEXKEY 34 +#define PragTyp_KEY 35 +#define PragTyp_REKEY 36 +#define PragTyp_LOCK_STATUS 37 +#define PragTyp_PARSER_TRACE 38 +static const struct sPragmaNames { + const char const *zName; /* Name of pragma */ + int ePragTyp; /* PragTyp_XXX value */ + u32 iArg; /* Extra argument */ +} aPragmaNames[] = { +#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) + { "activate_extensions", PragTyp_ACTIVATE_EXTENSIONS, 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { "application_id", PragTyp_HEADER_VALUE, 0 }, +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + { "auto_vacuum", PragTyp_AUTO_VACUUM, 0 }, +#endif +#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) + { "automatic_index", PragTyp_FLAG, + SQLITE_AutoIndex }, +#endif + { "busy_timeout", PragTyp_BUSY_TIMEOUT, 0 }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { "cache_size", PragTyp_CACHE_SIZE, 0 }, +#endif + { "cache_spill", PragTyp_FLAG, + SQLITE_CacheSpill }, + { "case_sensitive_like", PragTyp_CASE_SENSITIVE_LIKE, 0 }, + { "checkpoint_fullfsync", PragTyp_FLAG, + SQLITE_CkptFullFSync }, +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { "collation_list", PragTyp_COLLATION_LIST, 0 }, +#endif +#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) + { "compile_options", PragTyp_COMPILE_OPTIONS, 0 }, +#endif + { "count_changes", PragTyp_FLAG, + SQLITE_CountRows }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN + { "data_store_directory", PragTyp_DATA_STORE_DIRECTORY, 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { "database_list", PragTyp_DATABASE_LIST, 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + { "default_cache_size", PragTyp_DEFAULT_CACHE_SIZE, 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { "defer_foreign_keys", PragTyp_FLAG, + SQLITE_DeferFKs }, +#endif + { "empty_result_callbacks", PragTyp_FLAG, + SQLITE_NullCallback }, +#if !defined(SQLITE_OMIT_UTF16) + { "encoding", PragTyp_ENCODING, 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { "foreign_key_check", PragTyp_FOREIGN_KEY_CHECK, 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) + { "foreign_key_list", PragTyp_FOREIGN_KEY_LIST, 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { "foreign_keys", PragTyp_FLAG, + SQLITE_ForeignKeys }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { "freelist_count", PragTyp_HEADER_VALUE, 0 }, +#endif + { "full_column_names", PragTyp_FLAG, + SQLITE_FullColNames }, + { "fullfsync", PragTyp_FLAG, + SQLITE_FullFSync }, +#if defined(SQLITE_HAS_CODEC) + { "hexkey", PragTyp_HEXKEY, 0 }, +#endif +#if !defined(SQLITE_OMIT_CHECK) + { "ignore_check_constraints", PragTyp_FLAG, + SQLITE_IgnoreChecks }, +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + { "incremental_vacuum", PragTyp_INCREMENTAL_VACUUM, 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { "index_info", PragTyp_INDEX_INFO, 0 }, + { "index_list", PragTyp_INDEX_LIST, 0 }, +#endif +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + { "integrity_check", PragTyp_INTEGRITY_CHECK, 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { "journal_mode", PragTyp_JOURNAL_MODE, 0 }, + { "journal_size_limit", PragTyp_JOURNAL_SIZE_LIMIT, 0 }, +#endif +#if defined(SQLITE_HAS_CODEC) + { "key", PragTyp_KEY, 0 }, +#endif + { "legacy_file_format", PragTyp_FLAG, + SQLITE_LegacyFileFmt }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE + { "lock_proxy_file", PragTyp_LOCK_PROXY_FILE, 0 }, +#endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + { "lock_status", PragTyp_LOCK_STATUS, 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { "locking_mode", PragTyp_LOCKING_MODE, 0 }, + { "max_page_count", PragTyp_PAGE_COUNT, 0 }, + { "mmap_size", PragTyp_MMAP_SIZE, 0 }, + { "page_count", PragTyp_PAGE_COUNT, 0 }, + { "page_size", PragTyp_PAGE_SIZE, 0 }, +#endif +#if defined(SQLITE_DEBUG) + { "parser_trace", PragTyp_PARSER_TRACE, 0 }, +#endif + { "query_only", PragTyp_FLAG, + SQLITE_QueryOnly }, +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + { "quick_check", PragTyp_INTEGRITY_CHECK, 0 }, +#endif + { "read_uncommitted", PragTyp_FLAG, + SQLITE_ReadUncommitted }, + { "recursive_triggers", PragTyp_FLAG, + SQLITE_RecTriggers }, +#if defined(SQLITE_HAS_CODEC) + { "rekey", PragTyp_REKEY, 0 }, +#endif + { "reverse_unordered_selects", PragTyp_FLAG, + SQLITE_ReverseOrder }, +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { "schema_version", PragTyp_HEADER_VALUE, 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { "secure_delete", PragTyp_SECURE_DELETE, 0 }, +#endif + { "short_column_names", PragTyp_FLAG, + SQLITE_ShortColNames }, + { "shrink_memory", PragTyp_SHRINK_MEMORY, 0 }, +#if defined(SQLITE_DEBUG) + { "sql_trace", PragTyp_FLAG, + SQLITE_SqlTrace }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { "synchronous", PragTyp_SYNCHRONOUS, 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { "table_info", PragTyp_TABLE_INFO, 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { "temp_store", PragTyp_TEMP_STORE, 0 }, + { "temp_store_directory", PragTyp_TEMP_STORE_DIRECTORY, 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { "user_version", PragTyp_HEADER_VALUE, 0 }, +#endif +#if defined(SQLITE_DEBUG) + { "vdbe_addoptrace", PragTyp_FLAG, + SQLITE_VdbeAddopTrace }, + { "vdbe_debug", PragTyp_FLAG, + SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, + { "vdbe_listing", PragTyp_FLAG, + SQLITE_VdbeListing }, + { "vdbe_trace", PragTyp_FLAG, + SQLITE_VdbeTrace }, +#endif +#if !defined(SQLITE_OMIT_WAL) + { "wal_autocheckpoint", PragTyp_WAL_AUTOCHECKPOINT, 0 }, + { "wal_checkpoint", PragTyp_WAL_CHECKPOINT, 0 }, +#endif + { "writable_schema", PragTyp_FLAG, + SQLITE_WriteSchema|SQLITE_RecoveryMode }, +}; +/* End of the automatically generated pragma table. +***************************************************************************/ + /* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or @@ -188,97 +414,6 @@ static void setAllPagerFlags(sqlite3 *db){ #endif -#ifndef SQLITE_OMIT_FLAG_PRAGMAS -/* -** Check to see if zRight and zLeft refer to a pragma that queries -** or changes one of the flags in db->flags. Return 1 if so and 0 if not. -** Also, implement the pragma. -*/ -static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ - static const struct sPragmaType { - const char *zName; /* Name of the pragma */ - int mask; /* Mask for the db->flags value */ - } aPragma[] = { - { "full_column_names", SQLITE_FullColNames }, - { "short_column_names", SQLITE_ShortColNames }, - { "count_changes", SQLITE_CountRows }, - { "empty_result_callbacks", SQLITE_NullCallback }, - { "legacy_file_format", SQLITE_LegacyFileFmt }, - { "fullfsync", SQLITE_FullFSync }, - { "checkpoint_fullfsync", SQLITE_CkptFullFSync }, - { "cache_spill", SQLITE_CacheSpill }, - { "reverse_unordered_selects", SQLITE_ReverseOrder }, - { "query_only", SQLITE_QueryOnly }, -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX - { "automatic_index", SQLITE_AutoIndex }, -#endif -#ifdef SQLITE_DEBUG - { "sql_trace", SQLITE_SqlTrace }, - { "vdbe_listing", SQLITE_VdbeListing }, - { "vdbe_trace", SQLITE_VdbeTrace }, - { "vdbe_addoptrace", SQLITE_VdbeAddopTrace}, - { "vdbe_debug", SQLITE_SqlTrace | SQLITE_VdbeListing - | SQLITE_VdbeTrace }, -#endif -#ifndef SQLITE_OMIT_CHECK - { "ignore_check_constraints", SQLITE_IgnoreChecks }, -#endif - /* The following is VERY experimental */ - { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode }, - - /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted - ** flag if there are any active statements. */ - { "read_uncommitted", SQLITE_ReadUncommitted }, - { "recursive_triggers", SQLITE_RecTriggers }, - - /* This flag may only be set if both foreign-key and trigger support - ** are present in the build. */ -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { "foreign_keys", SQLITE_ForeignKeys }, - { "defer_foreign_keys", SQLITE_DeferFKs }, -#endif - }; - int i; - const struct sPragmaType *p; - for(i=0, p=aPragma; izName)==0 ){ - sqlite3 *db = pParse->db; - Vdbe *v; - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); /* Already allocated by sqlite3Pragma() */ - if( ALWAYS(v) ){ - if( zRight==0 ){ - returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); - }else{ - int mask = p->mask; /* Mask of bits to set or clear. */ - if( db->autoCommit==0 ){ - /* Foreign key support may not be enabled or disabled while not - ** in auto-commit mode. */ - mask &= ~(SQLITE_ForeignKeys); - } - - if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= mask; - }else{ - db->flags &= ~mask; - if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; - } - - /* Many of the flag-pragmas modify the code generated by the SQL - ** compiler (eg. count_changes). So add an opcode to expire all - ** compiled SQL statements after modifying a pragma value. - */ - sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); - } - } - - return 1; - } - } - return 0; -} -#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ - /* ** Return a human-readable name for a constraint resolution action. */ @@ -348,8 +483,9 @@ void sqlite3Pragma( char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ const char *zDb = 0; /* The database name */ Token *pId; /* Pointer to token */ - int iDb; /* Database index for */ char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ + int iDb; /* Database index for */ + int lwr, upr, mid; /* Binary search bounds */ int rc; /* return value form SQLITE_FCNTL_PRAGMA */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ @@ -405,16 +541,36 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); sqlite3_free(aFcntl[0]); } - }else if( rc!=SQLITE_NOTFOUND ){ + goto pragma_out; + } + if( rc!=SQLITE_NOTFOUND ){ if( aFcntl[0] ){ sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); sqlite3_free(aFcntl[0]); } pParse->nErr++; pParse->rc = rc; - }else - - + goto pragma_out; + } + + /* Locate the pragma in the lookup table */ + lwr = 0; + upr = ArraySize(aPragmaNames)-1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName); + if( rc==0 ) break; + if( rc<0 ){ + upr = mid - 1; + }else{ + lwr = mid + 1; + } + } + if( lwr>upr ) goto pragma_out; + + /* Jump to the appropriate pragma handler */ + switch( aPragmaNames[mid].ePragTyp ){ + #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [database.]default_cache_size @@ -432,7 +588,7 @@ void sqlite3Pragma( ** size. But continue to take the absolute value of the default cache ** size of historical compatibility. */ - if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ + case PragTyp_DEFAULT_CACHE_SIZE: { static const VdbeOpList getCacheSize[] = { { OP_Transaction, 0, 0, 0}, /* 0 */ { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ @@ -464,7 +620,8 @@ void sqlite3Pragma( pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } - }else + break; + } #endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -477,7 +634,7 @@ void sqlite3Pragma( ** database page size value. The value can only be set if ** the database has not yet been created. */ - if( sqlite3StrICmp(zLeft,"page_size")==0 ){ + case PragTyp_PAGE_SIZE: { Btree *pBt = pDb->pBt; assert( pBt!=0 ); if( !zRight ){ @@ -492,7 +649,8 @@ void sqlite3Pragma( db->mallocFailed = 1; } } - }else + break; + } /* ** PRAGMA [database.]secure_delete @@ -502,7 +660,7 @@ void sqlite3Pragma( ** secure_delete flag. The second form changes the secure_delete ** flag setting and reports thenew value. */ - if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){ + case PragTyp_SECURE_DELETE: { Btree *pBt = pDb->pBt; int b = -1; assert( pBt!=0 ); @@ -517,7 +675,8 @@ void sqlite3Pragma( } b = sqlite3BtreeSecureDelete(pBt, b); returnSingleInt(pParse, "secure_delete", b); - }else + break; + } /* ** PRAGMA [database.]max_page_count @@ -536,9 +695,7 @@ void sqlite3Pragma( ** ** Return the number of pages in the specified database. */ - if( sqlite3StrICmp(zLeft,"page_count")==0 - || sqlite3StrICmp(zLeft,"max_page_count")==0 - ){ + case PragTyp_PAGE_COUNT: { int iReg; if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3CodeVerifySchema(pParse, iDb); @@ -552,13 +709,14 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); - }else + break; + } /* ** PRAGMA [database.]locking_mode ** PRAGMA [database.]locking_mode = (normal|exclusive) */ - if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){ + case PragTyp_LOCKING_MODE: { const char *zRet = "normal"; int eMode = getLockingMode(zRight); @@ -591,7 +749,8 @@ void sqlite3Pragma( eMode = sqlite3PagerLockingMode(pPager, eMode); } - assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE); + assert( eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ zRet = "exclusive"; } @@ -599,14 +758,15 @@ void sqlite3Pragma( sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC); sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); - }else + break; + } /* ** PRAGMA [database.]journal_mode ** PRAGMA [database.]journal_mode = ** (delete|persist|off|truncate|memory|wal|off) */ - if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ + case PragTyp_JOURNAL_MODE: { int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ int ii; /* Loop counter */ @@ -649,7 +809,8 @@ void sqlite3Pragma( } } sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); - }else + break; + } /* ** PRAGMA [database.]journal_size_limit @@ -657,7 +818,7 @@ void sqlite3Pragma( ** ** Get or set the size limit on rollback journal files. */ - if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ + case PragTyp_JOURNAL_SIZE_LIMIT: { Pager *pPager = sqlite3BtreePager(pDb->pBt); i64 iLimit = -2; if( zRight ){ @@ -666,7 +827,8 @@ void sqlite3Pragma( } iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); returnSingleInt(pParse, "journal_size_limit", iLimit); - }else + break; + } #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ @@ -678,7 +840,7 @@ void sqlite3Pragma( ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL */ #ifndef SQLITE_OMIT_AUTOVACUUM - if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ + case PragTyp_AUTO_VACUUM: { Btree *pBt = pDb->pBt; assert( pBt!=0 ); if( sqlite3ReadSchema(pParse) ){ @@ -728,7 +890,8 @@ void sqlite3Pragma( } } } - }else + break; + } #endif /* @@ -737,7 +900,7 @@ void sqlite3Pragma( ** Do N steps of incremental vacuuming on a database. */ #ifndef SQLITE_OMIT_AUTOVACUUM - if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){ + case PragTyp_INCREMENTAL_VACUUM: { int iLimit, addr; if( sqlite3ReadSchema(pParse) ){ goto pragma_out; @@ -752,7 +915,8 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); sqlite3VdbeJumpHere(v, addr); - }else + break; + } #endif #ifndef SQLITE_OMIT_PAGER_PRAGMAS @@ -767,7 +931,7 @@ void sqlite3Pragma( ** number of pages is adjusted so that the cache uses -N kibibytes ** of memory. */ - if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ + case PragTyp_CACHE_SIZE: { if( sqlite3ReadSchema(pParse) ) goto pragma_out; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ @@ -777,7 +941,8 @@ void sqlite3Pragma( pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } - }else + break; + } /* ** PRAGMA [database.]mmap_size(N) @@ -793,7 +958,7 @@ void sqlite3Pragma( ** as little or as much as it wants. Except, if N is set to 0 then the ** upper layers will never invoke the xFetch interfaces to the VFS. */ - if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ + case PragTyp_MMAP_SIZE: { sqlite3_int64 sz; #if SQLITE_MAX_MMAP_SIZE>0 assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); @@ -820,7 +985,8 @@ void sqlite3Pragma( pParse->nErr++; pParse->rc = rc; } - }else + break; + } /* ** PRAGMA temp_store @@ -833,13 +999,14 @@ void sqlite3Pragma( ** Note that it is possible for the library compile-time options to ** override this setting */ - if( sqlite3StrICmp(zLeft, "temp_store")==0 ){ + case PragTyp_TEMP_STORE: { if( !zRight ){ returnSingleInt(pParse, "temp_store", db->temp_store); }else{ changeTempStorage(pParse, zRight); } - }else + break; + } /* ** PRAGMA temp_store_directory @@ -851,7 +1018,7 @@ void sqlite3Pragma( ** If temporary directory is changed, then invalidateTempStorage. ** */ - if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ + case PragTyp_TEMP_STORE_DIRECTORY: { if( !zRight ){ if( sqlite3_temp_directory ){ sqlite3VdbeSetNumCols(v, 1); @@ -884,7 +1051,8 @@ void sqlite3Pragma( } #endif /* SQLITE_OMIT_WSD */ } - }else + break; + } #if SQLITE_OS_WIN /* @@ -900,7 +1068,7 @@ void sqlite3Pragma( ** by this setting, regardless of its value. ** */ - if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){ + case PragTyp_DATA_STORE_DIRECTORY: { if( !zRight ){ if( sqlite3_data_directory ){ sqlite3VdbeSetNumCols(v, 1); @@ -927,26 +1095,20 @@ void sqlite3Pragma( } #endif /* SQLITE_OMIT_WSD */ } - }else + break; + } #endif -#if !defined(SQLITE_ENABLE_LOCKING_STYLE) -# if defined(__APPLE__) -# define SQLITE_ENABLE_LOCKING_STYLE 1 -# else -# define SQLITE_ENABLE_LOCKING_STYLE 0 -# endif -#endif #if SQLITE_ENABLE_LOCKING_STYLE /* - ** PRAGMA [database.]lock_proxy_file - ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path" - ** - ** Return or set the value of the lock_proxy_file flag. Changing - ** the value sets a specific file to be used for database access locks. - ** - */ - if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){ + ** PRAGMA [database.]lock_proxy_file + ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path" + ** + ** Return or set the value of the lock_proxy_file flag. Changing + ** the value sets a specific file to be used for database access locks. + ** + */ + case PragTyp_LOCK_PROXY_FILE: { if( !zRight ){ Pager *pPager = sqlite3BtreePager(pDb->pBt); char *proxy_file_path = NULL; @@ -977,7 +1139,8 @@ void sqlite3Pragma( goto pragma_out; } } - }else + break; + } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* @@ -989,7 +1152,7 @@ void sqlite3Pragma( ** default value will be restored the next time the database is ** opened. */ - if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ + case PragTyp_SYNCHRONOUS: { if( sqlite3ReadSchema(pParse) ) goto pragma_out; if( !zRight ){ returnSingleInt(pParse, "synchronous", pDb->safety_level-1); @@ -1002,13 +1165,39 @@ void sqlite3Pragma( setAllPagerFlags(db); } } - }else + break; + } #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ #ifndef SQLITE_OMIT_FLAG_PRAGMAS - if( flagPragma(pParse, zLeft, zRight) ){ - setAllPagerFlags(db); - }else + case PragTyp_FLAG: { + if( zRight==0 ){ + returnSingleInt(pParse, aPragmaNames[mid].zName, + (db->flags & aPragmaNames[mid].iArg)!=0 ); + }else{ + int mask = aPragmaNames[mid].iArg; /* Mask of bits to set or clear. */ + if( db->autoCommit==0 ){ + /* Foreign key support may not be enabled or disabled while not + ** in auto-commit mode. */ + mask &= ~(SQLITE_ForeignKeys); + } + + if( sqlite3GetBoolean(zRight, 0) ){ + db->flags |= mask; + }else{ + db->flags &= ~mask; + if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; + } + + /* Many of the flag-pragmas modify the code generated by the SQL + ** compiler (eg. count_changes). So add an opcode to expire all + ** compiled SQL statements after modifying a pragma value. + */ + sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); + setAllPagerFlags(db); + } + break; + } #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS @@ -1024,7 +1213,7 @@ void sqlite3Pragma( ** notnull: True if 'NOT NULL' is part of column declaration ** dflt_value: The default value for the column, if any. */ - if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){ + case PragTyp_TABLE_INFO: if( zRight ){ Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, zDb); @@ -1070,9 +1259,10 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); } } - }else + } + break; - if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ + case PragTyp_INDEX_INFO: if( zRight ){ Index *pIdx; Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; @@ -1095,9 +1285,10 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); } } - }else + } + break; - if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){ + case PragTyp_INDEX_LIST: if( zRight ){ Index *pIdx; Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; @@ -1123,9 +1314,10 @@ void sqlite3Pragma( } } } - }else + } + break; - if( sqlite3StrICmp(zLeft, "database_list")==0 ){ + case PragTyp_DATABASE_LIST: { int i; if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 3); @@ -1142,9 +1334,10 @@ void sqlite3Pragma( sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); } - }else + } + break; - if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ + case PragTyp_COLLATION_LIST: { int i = 0; HashElem *p; sqlite3VdbeSetNumCols(v, 2); @@ -1157,11 +1350,12 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } - }else + } + break; #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ #ifndef SQLITE_OMIT_FOREIGN_KEY - if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ + case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ FKey *pFK; Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; @@ -1204,12 +1398,13 @@ void sqlite3Pragma( } } } - }else + } + break; #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef SQLITE_OMIT_FOREIGN_KEY #ifndef SQLITE_OMIT_TRIGGER - if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){ + case PragTyp_FOREIGN_KEY_CHECK: { FKey *pFK; /* A foreign key constraint */ Table *pTab; /* Child table contain "REFERENCES" keyword */ Table *pParent; /* Parent table that child points to */ @@ -1319,12 +1514,13 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); sqlite3VdbeJumpHere(v, addrTop); } - }else + } + break; #endif /* !defined(SQLITE_OMIT_TRIGGER) */ #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef NDEBUG - if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ + case PragTyp_PARSER_TRACE: { if( zRight ){ if( sqlite3GetBoolean(zRight, 0) ){ sqlite3ParserTrace(stderr, "parser: "); @@ -1332,17 +1528,19 @@ void sqlite3Pragma( sqlite3ParserTrace(0, 0); } } - }else + } + break; #endif /* Reinstall the LIKE and GLOB functions. The variant of LIKE ** used will be case sensitive or not depending on the RHS. */ - if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ + case PragTyp_CASE_SENSITIVE_LIKE: { if( zRight ){ sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); } - }else + } + break; #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 @@ -1353,9 +1551,7 @@ void sqlite3Pragma( ** integrity_check designed to detect most database corruption ** without most of the overhead of a full integrity-check. */ - if( sqlite3StrICmp(zLeft, "integrity_check")==0 - || sqlite3StrICmp(zLeft, "quick_check")==0 - ){ + case PragTyp_INTEGRITY_CHECK: { int i, j, addr, mxErr; /* Code that appears at the end of the integrity check. If no error @@ -1515,7 +1711,8 @@ void sqlite3Pragma( sqlite3VdbeChangeP2(v, addr, -mxErr); sqlite3VdbeJumpHere(v, addr+1); sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); - }else + } + break; #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_UTF16 @@ -1541,7 +1738,7 @@ void sqlite3Pragma( ** new database files created using this database handle. It is only ** useful if invoked immediately after the main database i */ - if( sqlite3StrICmp(zLeft, "encoding")==0 ){ + case PragTyp_ENCODING: { static const struct EncName { char *zName; u8 enc; @@ -1588,7 +1785,8 @@ void sqlite3Pragma( } } } - }else + } + break; #endif /* SQLITE_OMIT_UTF16 */ #ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS @@ -1622,11 +1820,7 @@ void sqlite3Pragma( ** The user-version is not used internally by SQLite. It may be used by ** applications for any purpose. */ - if( sqlite3StrICmp(zLeft, "schema_version")==0 - || sqlite3StrICmp(zLeft, "user_version")==0 - || sqlite3StrICmp(zLeft, "freelist_count")==0 - || sqlite3StrICmp(zLeft, "application_id")==0 - ){ + case PragTyp_HEADER_VALUE: { int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */ sqlite3VdbeUsesBtree(v, iDb); switch( zLeft[0] ){ @@ -1670,7 +1864,8 @@ void sqlite3Pragma( sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); } - }else + } + break; #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS @@ -1680,7 +1875,7 @@ void sqlite3Pragma( ** Return the names of all compile-time options used in this build, ** one option per row. */ - if( sqlite3StrICmp(zLeft, "compile_options")==0 ){ + case PragTyp_COMPILE_OPTIONS: { int i = 0; const char *zOpt; sqlite3VdbeSetNumCols(v, 1); @@ -1690,7 +1885,8 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } - }else + } + break; #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ #ifndef SQLITE_OMIT_WAL @@ -1699,7 +1895,7 @@ void sqlite3Pragma( ** ** Checkpoint the database. */ - if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){ + case PragTyp_WAL_CHECKPOINT: { int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); int eMode = SQLITE_CHECKPOINT_PASSIVE; if( zRight ){ @@ -1718,7 +1914,8 @@ void sqlite3Pragma( sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); - }else + } + break; /* ** PRAGMA wal_autocheckpoint @@ -1728,14 +1925,15 @@ void sqlite3Pragma( ** after accumulating N frames in the log. Or query for the current value ** of N. */ - if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){ + case PragTyp_WAL_AUTOCHECKPOINT: { if( zRight ){ sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); } returnSingleInt(pParse, "wal_autocheckpoint", db->xWalCallback==sqlite3WalDefaultHook ? SQLITE_PTR_TO_INT(db->pWalArg) : 0); - }else + } + break; #endif /* @@ -1744,9 +1942,10 @@ void sqlite3Pragma( ** This pragma attempts to free as much memory as possible from the ** current database connection. */ - if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){ + case PragTyp_SHRINK_MEMORY: { sqlite3_db_release_memory(db); - }else + break; + } /* ** PRAGMA busy_timeout @@ -1757,18 +1956,19 @@ void sqlite3Pragma( ** then 0 is returned. Setting the busy_timeout to 0 or negative ** disables the timeout. */ - if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){ + case PragTyp_BUSY_TIMEOUT: { if( zRight ){ sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); } returnSingleInt(pParse, "timeout", db->busyTimeout); - }else + break; + } #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases */ - if( sqlite3StrICmp(zLeft, "lock_status")==0 ){ + case PragTyp_LOCK_STATUS: { static const char *const azLockName[] = { "unlocked", "shared", "reserved", "pending", "exclusive" }; @@ -1793,35 +1993,39 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } - - }else + break; + } #endif #ifdef SQLITE_HAS_CODEC - if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){ - sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); - }else - if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){ - sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); - }else - if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 || - sqlite3StrICmp(zLeft, "hexrekey")==0) ){ - int i, h1, h2; - char zKey[40]; - for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){ - h1 += 9*(1&(h1>>6)); - h2 += 9*(1&(h2>>6)); - zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4); + case PragTyp_KEY: { + if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); + break; + } + case PragTyp_REKEY: { + if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); + break; + } + case PragTyp_HEXKEY: { + if( zRight ){ + int i, h1, h2; + char zKey[40]; + for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){ + h1 += 9*(1&(h1>>6)); + h2 += 9*(1&(h2>>6)); + zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4); + } + if( (zLeft[3] & 0xf)==0xb ){ + sqlite3_key_v2(db, zDb, zKey, i/2); + }else{ + sqlite3_rekey_v2(db, zDb, zKey, i/2); + } } - if( (zLeft[3] & 0xf)==0xb ){ - sqlite3_key_v2(db, zDb, zKey, i/2); - }else{ - sqlite3_rekey_v2(db, zDb, zKey, i/2); - } - }else + break; + } #endif #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) - if( sqlite3StrICmp(zLeft, "activate_extensions")==0 && zRight ){ + case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){ #ifdef SQLITE_HAS_CODEC if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ sqlite3_activate_see(&zRight[4]); @@ -1832,11 +2036,11 @@ void sqlite3Pragma( sqlite3_activate_cerod(&zRight[6]); } #endif - }else + } + break; #endif - - {/* Empty ELSE clause */} + } /* End of the PRAGMA switch */ pragma_out: sqlite3DbFree(db, zLeft); diff --git a/src/util.c b/src/util.c index d83a63015f..7ccf2a1fd0 100644 --- a/src/util.c +++ b/src/util.c @@ -193,7 +193,8 @@ int sqlite3Dequote(char *z){ case '[': quote = ']'; break; /* For MS SqlServer compatibility */ default: return -1; } - for(i=1, j=0; ALWAYS(z[i]); i++){ + for(i=1, j=0;; i++){ + assert( z[i] ); if( z[i]==quote ){ if( z[i+1]==quote ){ z[j++] = quote; diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl new file mode 100644 index 0000000000..09d3a11cfa --- /dev/null +++ b/tool/mkpragmatab.tcl @@ -0,0 +1,335 @@ +#!/usr/bin/tclsh +# +# Run this script to generate the pragma name lookup table C code. +# +# To add new pragmas, first add the name and other relevant attributes +# of the pragma to the "pragma_def" object below. Then run this script +# to generate the C-code for the lookup table and copy/paste the output +# of this script into the appropriate spot in the pragma.c source file. +# Then add the extra "case PragTyp_XXXXX:" and subsequent code for the +# new pragma. +# + +set pragma_def { + NAME: full_column_names + TYPE: FLAG + ARG: SQLITE_FullColNames + + NAME: short_column_names + TYPE: FLAG + ARG: SQLITE_ShortColNames + + NAME: count_changes + TYPE: FLAG + ARG: SQLITE_CountRows + + NAME: empty_result_callbacks + TYPE: FLAG + ARG: SQLITE_NullCallback + + NAME: legacy_file_format + TYPE: FLAG + ARG: SQLITE_LegacyFileFmt + + NAME: fullfsync + TYPE: FLAG + ARG: SQLITE_FullFSync + + NAME: checkpoint_fullfsync + TYPE: FLAG + ARG: SQLITE_CkptFullFSync + + NAME: cache_spill + TYPE: FLAG + ARG: SQLITE_CacheSpill + + NAME: reverse_unordered_selects + TYPE: FLAG + ARG: SQLITE_ReverseOrder + + NAME: query_only + TYPE: FLAG + ARG: SQLITE_QueryOnly + + NAME: automatic_index + TYPE: FLAG + ARG: SQLITE_AutoIndex + IF: !defined(SQLITE_OMIT_AUTOMATIC_INDEX) + + NAME: sql_trace + TYPE: FLAG + ARG: SQLITE_SqlTrace + IF: defined(SQLITE_DEBUG) + + NAME: vdbe_listing + TYPE: FLAG + ARG: SQLITE_VdbeListing + IF: defined(SQLITE_DEBUG) + + NAME: vdbe_trace + TYPE: FLAG + ARG: SQLITE_VdbeTrace + IF: defined(SQLITE_DEBUG) + + NAME: vdbe_addoptrace + TYPE: FLAG + ARG: SQLITE_VdbeAddopTrace + IF: defined(SQLITE_DEBUG) + + NAME: vdbe_debug + TYPE: FLAG + ARG: SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace + IF: defined(SQLITE_DEBUG) + + NAME: ignore_check_constraints + TYPE: FLAG + ARG: SQLITE_IgnoreChecks + IF: !defined(SQLITE_OMIT_CHECK) + + NAME: writable_schema + TYPE: FLAG + ARG: SQLITE_WriteSchema|SQLITE_RecoveryMode + + NAME: read_uncommitted + TYPE: FLAG + ARG: SQLITE_ReadUncommitted + + NAME: recursive_triggers + TYPE: FLAG + ARG: SQLITE_RecTriggers + + NAME: foreign_keys + TYPE: FLAG + ARG: SQLITE_ForeignKeys + IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + + NAME: defer_foreign_keys + TYPE: FLAG + ARG: SQLITE_DeferFKs + IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + + NAME: default_cache_size + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + + NAME: page_size + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: secure_delete + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: page_count + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: max_page_count + TYPE: PAGE_COUNT + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: locking_mode + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: journal_mode + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: journal_size_limit + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: cache_size + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: mmap_size + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: auto_vacuum + IF: !defined(SQLITE_OMIT_AUTOVACUUM) + + NAME: incremental_vacuum + IF: !defined(SQLITE_OMIT_AUTOVACUUM) + + NAME: temp_store + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: temp_store_directory + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: data_store_directory + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN + + NAME: lock_proxy_file + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE + + NAME: synchronous + IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) + + NAME: table_info + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + + NAME: index_info + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + + NAME: index_list + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + + NAME: database_list + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + + NAME: collation_list + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + + NAME: foreign_key_list + IF: !defined(SQLITE_OMIT_FOREIGN_KEY) + + NAME: foreign_key_check + IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + + NAME: parser_trace + IF: defined(SQLITE_DEBUG) + + NAME: case_sensitive_like + + NAME: integrity_check + IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) + + NAME: quick_check + TYPE: INTEGRITY_CHECK + IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) + + NAME: encoding + IF: !defined(SQLITE_OMIT_UTF16) + + NAME: schema_version + TYPE: HEADER_VALUE + IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + + NAME: user_version + TYPE: HEADER_VALUE + IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + + NAME: freelist_count + TYPE: HEADER_VALUE + IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + + NAME: application_id + TYPE: HEADER_VALUE + IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + + NAME: compile_options + IF: !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) + + NAME: wal_checkpoint + IF: !defined(SQLITE_OMIT_WAL) + + NAME: wal_autocheckpoint + IF: !defined(SQLITE_OMIT_WAL) + + NAME: shrink_memory + + NAME: busy_timeout + + NAME: lock_status + IF: defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + + NAME: key + IF: defined(SQLITE_HAS_CODEC) + + NAME: rekey + IF: defined(SQLITE_HAS_CODEC) + + NAME: hexkey + IF: defined(SQLITE_HAS_CODEC) + + NAME: activate_extensions + IF: defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) +} +set name {} +set type {} +set if {} +set arg 0 +proc record_one {} { + global name type if arg allbyname typebyif + if {$name==""} return + set allbyname($name) [list $type $arg $if] + set name {} + set type {} + set if {} + set arg 0 +} +foreach line [split $pragma_def \n] { + set line [string trim $line] + if {$line==""} continue + foreach {id val} [split $line :] break + set val [string trim $val] + if {$id=="NAME"} { + record_one + set name $val + set type [string toupper $val] + } elseif {$id=="TYPE"} { + set type $val + } elseif {$id=="ARG"} { + set arg $val + } elseif {$id=="IF"} { + set if $val + } else { + error "bad pragma_def line: $line" + } +} +record_one +set allnames [lsort [array names allbyname]] + +# Generate #defines for all pragma type names. Group the pragmas that are +# omit in default builds (defined(SQLITE_DEBUG) and defined(SQLITE_HAS_CODEC)) +# at the end. +# +set pnum 0 +foreach name $allnames { + set type [lindex $allbyname($name) 0] + if {[info exists seentype($type)]} continue + set if [lindex $allbyname($name) 2] + if {[regexp SQLITE_DEBUG $if] || [regexp SQLITE_HAS_CODEC $if]} continue + set seentype($type) 1 + puts [format {#define %-35s %4d} PragTyp_$type $pnum] + incr pnum +} +foreach name $allnames { + set type [lindex $allbyname($name) 0] + if {[info exists seentype($type)]} continue + set if [lindex $allbyname($name) 2] + if {[regexp SQLITE_DEBUG $if]} continue + set seentype($type) 1 + puts [format {#define %-35s %4d} PragTyp_$type $pnum] + incr pnum +} +foreach name $allnames { + set type [lindex $allbyname($name) 0] + if {[info exists seentype($type)]} continue + set seentype($type) 1 + puts [format {#define %-35s %4d} PragTyp_$type $pnum] + incr pnum +} + +# Generate the lookup table +# +puts "static const struct sPragmaNames \173" +puts " const char const *zName; /* Name of pragma */" +puts " int ePragTyp; /* PragTyp_XXX value */" +puts " u32 iArg; /* Extra argument */" +puts "\175 aPragmaNames\[\] = \173" + +set current_if {} +set spacer [format { %26s } {}] +foreach name $allnames { + foreach {type arg if} $allbyname($name) break + if {$if!=$current_if} { + if {$current_if!=""} {puts "#endif"} + set current_if $if + if {$current_if!=""} {puts "#if $current_if"} + } + set namex [format %-26s \"$name\",] + set typex [format PragTyp_%-23s $type,] + if {[string length $arg]>10} { + puts " \173 $namex $typex\n$spacer$arg \175," + } else { + puts " \173 $namex $typex $arg \175," + } +} +if {$current_if!=""} {puts "#endif"} +puts "\175;"