]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the PRAGMA parser to use a binary search for the pragma name.
authordrh <drh@noemail.net>
Fri, 13 Sep 2013 16:36:46 +0000 (16:36 +0000)
committerdrh <drh@noemail.net>
Fri, 13 Sep 2013 16:36:46 +0000 (16:36 +0000)
Also:  Minor performance enhancement to sqlite3DbFree() and to the
token dequoter.

FossilOrigin-Name: 870c030b4e1854e6e0d39907fadbd82774c16f56

manifest
manifest.uuid
src/malloc.c
src/pragma.c
src/util.c
tool/mkpragmatab.tcl [new file with mode: 0644]

index aed27695f14259b61602f2e3f552b1532e9aac1f..8364ee9131f59b8136c439cf3d82f9a3122477e9 100644 (file)
--- 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
index 1700974c763729c3178bd385ff7bf928a9db5d08..bfbcc6abb816f45cae5a8248b155f1259d6ef479 100644 (file)
@@ -1 +1 @@
-9ce6f40dfb54b35cecba3cc9c1ec0d111f6e9f11
\ No newline at end of file
+870c030b4e1854e6e0d39907fadbd82774c16f56
\ No newline at end of file
index 35a44e5f61c2e44c481c6251bd0aae7acda4de0b..799f0485d4c905616c0afcb4fecc06c671a3dc12 100644 (file)
@@ -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);
index d4cf597ff8db03046273597531adfdd02fe01ede..a73c59a0786bb2e757c59cdd51f8d558196575fb 100644 (file)
 */
 #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; i<ArraySize(aPragma); i++, p++){
-    if( sqlite3StrICmp(zLeft, p->zName)==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 <value>, or NULL */
   const char *zDb = 0;   /* The database name */
   Token *pId;            /* Pointer to <id> token */
-  int iDb;               /* Database index for <database> */
   char *aFcntl[4];       /* Argument to SQLITE_FCNTL_PRAGMA */
+  int iDb;               /* Database index for <database> */
+  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);
-    }
-    if( (zLeft[3] & 0xf)==0xb ){
-      sqlite3_key_v2(db, zDb, zKey, i/2);
-    }else{
-      sqlite3_rekey_v2(db, zDb, zKey, i/2);
+  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);
+      }
     }
-  }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);
index d83a63015fd87dcc4fb44166fabf2e9bc9671eb8..7ccf2a1fd02455581e66a36c3e9c4aeefa3d70d4 100644 (file)
@@ -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 (file)
index 0000000..09d3a11
--- /dev/null
@@ -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;"