| Index: third_party/sqlite/src/src/pragma.c | 
| diff --git a/third_party/sqlite/src/src/pragma.c b/third_party/sqlite/src/src/pragma.c | 
| index 75ab26d441a0463a1d15e16b160d7c338f592596..543f265ba9ea1ae5e8e0fff897f91f76aa334450 100644 | 
| --- a/third_party/sqlite/src/src/pragma.c | 
| +++ b/third_party/sqlite/src/src/pragma.c | 
| @@ -13,21 +13,479 @@ | 
| */ | 
| #include "sqliteInt.h" | 
|  | 
| -/* Ignore this whole file if pragmas are disabled | 
| +#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: | 
| */ | 
| -#if !defined(SQLITE_OMIT_PRAGMA) | 
| +#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_SOFT_HEAP_LIMIT               27 | 
| +#define PragTyp_STATS                         28 | 
| +#define PragTyp_SYNCHRONOUS                   29 | 
| +#define PragTyp_TABLE_INFO                    30 | 
| +#define PragTyp_TEMP_STORE                    31 | 
| +#define PragTyp_TEMP_STORE_DIRECTORY          32 | 
| +#define PragTyp_THREADS                       33 | 
| +#define PragTyp_WAL_AUTOCHECKPOINT            34 | 
| +#define PragTyp_WAL_CHECKPOINT                35 | 
| +#define PragTyp_ACTIVATE_EXTENSIONS           36 | 
| +#define PragTyp_HEXKEY                        37 | 
| +#define PragTyp_KEY                           38 | 
| +#define PragTyp_REKEY                         39 | 
| +#define PragTyp_LOCK_STATUS                   40 | 
| +#define PragTyp_PARSER_TRACE                  41 | 
| +#define PragFlag_NeedSchema           0x01 | 
| +static const struct sPragmaNames { | 
| +  const char *const zName;  /* Name of pragma */ | 
| +  u8 ePragTyp;              /* PragTyp_XXX value */ | 
| +  u8 mPragFlag;             /* Zero or more PragFlag_XXX values */ | 
| +  u32 iArg;                 /* Extra argument */ | 
| +} aPragmaNames[] = { | 
| +#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) | 
| +  { /* zName:     */ "activate_extensions", | 
| +    /* ePragTyp:  */ PragTyp_ACTIVATE_EXTENSIONS, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) | 
| +  { /* zName:     */ "application_id", | 
| +    /* ePragTyp:  */ PragTyp_HEADER_VALUE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_AUTOVACUUM) | 
| +  { /* zName:     */ "auto_vacuum", | 
| +    /* ePragTyp:  */ PragTyp_AUTO_VACUUM, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) | 
| +  { /* zName:     */ "automatic_index", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_AutoIndex }, | 
| +#endif | 
| +#endif | 
| +  { /* zName:     */ "busy_timeout", | 
| +    /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) | 
| +  { /* zName:     */ "cache_size", | 
| +    /* ePragTyp:  */ PragTyp_CACHE_SIZE, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "cache_spill", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_CacheSpill }, | 
| +#endif | 
| +  { /* zName:     */ "case_sensitive_like", | 
| +    /* ePragTyp:  */ PragTyp_CASE_SENSITIVE_LIKE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "checkpoint_fullfsync", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_CkptFullFSync }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) | 
| +  { /* zName:     */ "collation_list", | 
| +    /* ePragTyp:  */ PragTyp_COLLATION_LIST, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) | 
| +  { /* zName:     */ "compile_options", | 
| +    /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "count_changes", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_CountRows }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN | 
| +  { /* zName:     */ "data_store_directory", | 
| +    /* ePragTyp:  */ PragTyp_DATA_STORE_DIRECTORY, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) | 
| +  { /* zName:     */ "database_list", | 
| +    /* ePragTyp:  */ PragTyp_DATABASE_LIST, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) | 
| +  { /* zName:     */ "default_cache_size", | 
| +    /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) | 
| +  { /* zName:     */ "defer_foreign_keys", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_DeferFKs }, | 
| +#endif | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "empty_result_callbacks", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_NullCallback }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_UTF16) | 
| +  { /* zName:     */ "encoding", | 
| +    /* ePragTyp:  */ PragTyp_ENCODING, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) | 
| +  { /* zName:     */ "foreign_key_check", | 
| +    /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FOREIGN_KEY) | 
| +  { /* zName:     */ "foreign_key_list", | 
| +    /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) | 
| +  { /* zName:     */ "foreign_keys", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_ForeignKeys }, | 
| +#endif | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) | 
| +  { /* zName:     */ "freelist_count", | 
| +    /* ePragTyp:  */ PragTyp_HEADER_VALUE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "full_column_names", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_FullColNames }, | 
| +  { /* zName:     */ "fullfsync", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_FullFSync }, | 
| +#endif | 
| +#if defined(SQLITE_HAS_CODEC) | 
| +  { /* zName:     */ "hexkey", | 
| +    /* ePragTyp:  */ PragTyp_HEXKEY, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "hexrekey", | 
| +    /* ePragTyp:  */ PragTyp_HEXKEY, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +#if !defined(SQLITE_OMIT_CHECK) | 
| +  { /* zName:     */ "ignore_check_constraints", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_IgnoreChecks }, | 
| +#endif | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_AUTOVACUUM) | 
| +  { /* zName:     */ "incremental_vacuum", | 
| +    /* ePragTyp:  */ PragTyp_INCREMENTAL_VACUUM, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) | 
| +  { /* zName:     */ "index_info", | 
| +    /* ePragTyp:  */ PragTyp_INDEX_INFO, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "index_list", | 
| +    /* ePragTyp:  */ PragTyp_INDEX_LIST, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) | 
| +  { /* zName:     */ "integrity_check", | 
| +    /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) | 
| +  { /* zName:     */ "journal_mode", | 
| +    /* ePragTyp:  */ PragTyp_JOURNAL_MODE, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "journal_size_limit", | 
| +    /* ePragTyp:  */ PragTyp_JOURNAL_SIZE_LIMIT, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if defined(SQLITE_HAS_CODEC) | 
| +  { /* zName:     */ "key", | 
| +    /* ePragTyp:  */ PragTyp_KEY, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "legacy_file_format", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_LegacyFileFmt }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE | 
| +  { /* zName:     */ "lock_proxy_file", | 
| +    /* ePragTyp:  */ PragTyp_LOCK_PROXY_FILE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | 
| +  { /* zName:     */ "lock_status", | 
| +    /* ePragTyp:  */ PragTyp_LOCK_STATUS, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) | 
| +  { /* zName:     */ "locking_mode", | 
| +    /* ePragTyp:  */ PragTyp_LOCKING_MODE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "max_page_count", | 
| +    /* ePragTyp:  */ PragTyp_PAGE_COUNT, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "mmap_size", | 
| +    /* ePragTyp:  */ PragTyp_MMAP_SIZE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "page_count", | 
| +    /* ePragTyp:  */ PragTyp_PAGE_COUNT, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "page_size", | 
| +    /* ePragTyp:  */ PragTyp_PAGE_SIZE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if defined(SQLITE_DEBUG) | 
| +  { /* zName:     */ "parser_trace", | 
| +    /* ePragTyp:  */ PragTyp_PARSER_TRACE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "query_only", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_QueryOnly }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) | 
| +  { /* zName:     */ "quick_check", | 
| +    /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "read_uncommitted", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_ReadUncommitted }, | 
| +  { /* zName:     */ "recursive_triggers", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_RecTriggers }, | 
| +#endif | 
| +#if defined(SQLITE_HAS_CODEC) | 
| +  { /* zName:     */ "rekey", | 
| +    /* ePragTyp:  */ PragTyp_REKEY, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "reverse_unordered_selects", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_ReverseOrder }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) | 
| +  { /* zName:     */ "schema_version", | 
| +    /* ePragTyp:  */ PragTyp_HEADER_VALUE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) | 
| +  { /* zName:     */ "secure_delete", | 
| +    /* ePragTyp:  */ PragTyp_SECURE_DELETE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "short_column_names", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_ShortColNames }, | 
| +#endif | 
| +  { /* zName:     */ "shrink_memory", | 
| +    /* ePragTyp:  */ PragTyp_SHRINK_MEMORY, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "soft_heap_limit", | 
| +    /* ePragTyp:  */ PragTyp_SOFT_HEAP_LIMIT, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +#if defined(SQLITE_DEBUG) | 
| +  { /* zName:     */ "sql_trace", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_SqlTrace }, | 
| +#endif | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) | 
| +  { /* zName:     */ "stats", | 
| +    /* ePragTyp:  */ PragTyp_STATS, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) | 
| +  { /* zName:     */ "synchronous", | 
| +    /* ePragTyp:  */ PragTyp_SYNCHRONOUS, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) | 
| +  { /* zName:     */ "table_info", | 
| +    /* ePragTyp:  */ PragTyp_TABLE_INFO, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) | 
| +  { /* zName:     */ "temp_store", | 
| +    /* ePragTyp:  */ PragTyp_TEMP_STORE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "temp_store_directory", | 
| +    /* ePragTyp:  */ PragTyp_TEMP_STORE_DIRECTORY, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +  { /* zName:     */ "threads", | 
| +    /* ePragTyp:  */ PragTyp_THREADS, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) | 
| +  { /* zName:     */ "user_version", | 
| +    /* ePragTyp:  */ PragTyp_HEADER_VALUE, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +#if defined(SQLITE_DEBUG) | 
| +  { /* zName:     */ "vdbe_addoptrace", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_VdbeAddopTrace }, | 
| +  { /* zName:     */ "vdbe_debug", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, | 
| +  { /* zName:     */ "vdbe_eqp", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_VdbeEQP }, | 
| +  { /* zName:     */ "vdbe_listing", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_VdbeListing }, | 
| +  { /* zName:     */ "vdbe_trace", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_VdbeTrace }, | 
| +#endif | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_WAL) | 
| +  { /* zName:     */ "wal_autocheckpoint", | 
| +    /* ePragTyp:  */ PragTyp_WAL_AUTOCHECKPOINT, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ 0 }, | 
| +  { /* zName:     */ "wal_checkpoint", | 
| +    /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT, | 
| +    /* ePragFlag: */ PragFlag_NeedSchema, | 
| +    /* iArg:      */ 0 }, | 
| +#endif | 
| +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) | 
| +  { /* zName:     */ "writable_schema", | 
| +    /* ePragTyp:  */ PragTyp_FLAG, | 
| +    /* ePragFlag: */ 0, | 
| +    /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, | 
| +#endif | 
| +}; | 
| +/* Number of pragmas: 57 on by default, 70 total. */ | 
| +/* 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 | 
| -** unrecognized string argument. | 
| +** unrecognized string argument.  The FULL option is disallowed | 
| +** if the omitFull parameter it 1. | 
| ** | 
| ** Note that the values returned are one less that the values that | 
| ** should be passed into sqlite3BtreeSetSafetyLevel().  The is done | 
| ** to support legacy SQL code.  The safety level used to be boolean | 
| ** and older scripts may have used numbers 0 for OFF and 1 for ON. | 
| */ | 
| -static u8 getSafetyLevel(const char *z){ | 
| +static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ | 
| /* 123456789 123456789 */ | 
| static const char zText[] = "onoffalseyestruefull"; | 
| static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; | 
| @@ -38,21 +496,27 @@ static u8 getSafetyLevel(const char *z){ | 
| return (u8)sqlite3Atoi(z); | 
| } | 
| n = sqlite3Strlen30(z); | 
| -  for(i=0; i<ArraySize(iLength); i++){ | 
| +  for(i=0; i<ArraySize(iLength)-omitFull; i++){ | 
| if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){ | 
| return iValue[i]; | 
| } | 
| } | 
| -  return 1; | 
| +  return dflt; | 
| } | 
|  | 
| /* | 
| ** Interpret the given string as a boolean value. | 
| */ | 
| -static u8 getBoolean(const char *z){ | 
| -  return getSafetyLevel(z)&1; | 
| +u8 sqlite3GetBoolean(const char *z, u8 dflt){ | 
| +  return getSafetyLevel(z,1,dflt)!=0; | 
| } | 
|  | 
| +/* The sqlite3GetBoolean() function is used by other modules but the | 
| +** remainder of this file is specific to PRAGMA processing.  So omit | 
| +** the rest of the file if PRAGMAs are omitted from the build. | 
| +*/ | 
| +#if !defined(SQLITE_OMIT_PRAGMA) | 
| + | 
| /* | 
| ** Interpret the given string as a locking mode value. | 
| */ | 
| @@ -115,7 +579,7 @@ static int invalidateTempStorage(Parse *pParse){ | 
| } | 
| sqlite3BtreeClose(db->aDb[1].pBt); | 
| db->aDb[1].pBt = 0; | 
| -    sqlite3ResetInternalSchema(db, -1); | 
| +    sqlite3ResetAllSchemasOfConnection(db); | 
| } | 
| return SQLITE_OK; | 
| } | 
| @@ -155,90 +619,35 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){ | 
| sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); | 
| } | 
|  | 
| -#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. | 
| +** Set the safety_level and pager flags for pager iDb.  Or if iDb<0 | 
| +** set these values for all pagers. | 
| */ | 
| -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 }, | 
| -    { "reverse_unordered_selects", SQLITE_ReverseOrder  }, | 
| -#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     }, | 
| -#endif | 
| -#ifndef SQLITE_OMIT_CHECK | 
| -    { "ignore_check_constraints", SQLITE_IgnoreChecks  }, | 
| -#endif | 
| -    /* The following is VERY experimental */ | 
| -    { "writable_schema",          SQLITE_WriteSchema|SQLITE_RecoveryMode }, | 
| -    { "omit_readlock",            SQLITE_NoReadlock    }, | 
| - | 
| -    /* 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 }, | 
| -#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( getBoolean(zRight) ){ | 
| -            db->flags |= mask; | 
| -          }else{ | 
| -            db->flags &= ~mask; | 
| -          } | 
| - | 
| -          /* 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); | 
| -        } | 
| +#ifndef SQLITE_OMIT_PAGER_PRAGMAS | 
| +static void setAllPagerFlags(sqlite3 *db){ | 
| +  if( db->autoCommit ){ | 
| +    Db *pDb = db->aDb; | 
| +    int n = db->nDb; | 
| +    assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); | 
| +    assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); | 
| +    assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); | 
| +    assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) | 
| +             ==  PAGER_FLAGS_MASK ); | 
| +    assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); | 
| +    while( (n--) > 0 ){ | 
| +      if( pDb->pBt ){ | 
| +        sqlite3BtreeSetPagerFlags(pDb->pBt, | 
| +                 pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); | 
| } | 
| - | 
| -      return 1; | 
| +      pDb++; | 
| } | 
| } | 
| -  return 0; | 
| } | 
| -#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ | 
| +#else | 
| +# define setAllPagerFlags(X)  /* no-op */ | 
| +#endif | 
| + | 
|  | 
| /* | 
| ** Return a human-readable name for a constraint resolution action. | 
| @@ -309,10 +718,14 @@ 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 */ | 
| +  char *aFcntl[4];       /* Argument to SQLITE_FCNTL_PRAGMA */ | 
| int iDb;               /* Database index for <database> */ | 
| -  sqlite3 *db = pParse->db; | 
| -  Db *pDb; | 
| -  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); | 
| +  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 */ | 
| +  Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */ | 
| + | 
| if( v==0 ) return; | 
| sqlite3VdbeRunOnlyOnce(v); | 
| pParse->nMem = 2; | 
| @@ -343,8 +756,62 @@ void sqlite3Pragma( | 
| if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ | 
| goto pragma_out; | 
| } | 
| - | 
| -#ifndef SQLITE_OMIT_PAGER_PRAGMAS | 
| + | 
| +  /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS | 
| +  ** connection.  If it returns SQLITE_OK, then assume that the VFS | 
| +  ** handled the pragma and generate a no-op prepared statement. | 
| +  */ | 
| +  aFcntl[0] = 0; | 
| +  aFcntl[1] = zLeft; | 
| +  aFcntl[2] = zRight; | 
| +  aFcntl[3] = 0; | 
| +  db->busyHandler.nBusy = 0; | 
| +  rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); | 
| +  if( rc==SQLITE_OK ){ | 
| +    if( aFcntl[0] ){ | 
| +      int mem = ++pParse->nMem; | 
| +      sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0); | 
| +      sqlite3VdbeSetNumCols(v, 1); | 
| +      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC); | 
| +      sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); | 
| +      sqlite3_free(aFcntl[0]); | 
| +    } | 
| +    goto pragma_out; | 
| +  } | 
| +  if( rc!=SQLITE_NOTFOUND ){ | 
| +    if( aFcntl[0] ){ | 
| +      sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); | 
| +      sqlite3_free(aFcntl[0]); | 
| +    } | 
| +    pParse->nErr++; | 
| +    pParse->rc = rc; | 
| +    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; | 
| + | 
| +  /* Make sure the database schema is loaded if the pragma requires that */ | 
| +  if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){ | 
| +    if( sqlite3ReadSchema(pParse) ) 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 | 
| **  PRAGMA [database.]default_cache_size=N | 
| @@ -361,25 +828,26 @@ 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 int iLn = VDBE_OFFSET_LINENO(2); | 
| static const VdbeOpList getCacheSize[] = { | 
| { OP_Transaction, 0, 0,        0},                         /* 0 */ | 
| { OP_ReadCookie,  0, 1,        BTREE_DEFAULT_CACHE_SIZE},  /* 1 */ | 
| -      { OP_IfPos,       1, 7,        0}, | 
| +      { OP_IfPos,       1, 8,        0}, | 
| { OP_Integer,     0, 2,        0}, | 
| { OP_Subtract,    1, 2,        1}, | 
| -      { OP_IfPos,       1, 7,        0}, | 
| +      { OP_IfPos,       1, 8,        0}, | 
| { OP_Integer,     0, 1,        0},                         /* 6 */ | 
| +      { OP_Noop,        0, 0,        0}, | 
| { OP_ResultRow,   1, 1,        0}, | 
| }; | 
| int addr; | 
| -    if( sqlite3ReadSchema(pParse) ) goto pragma_out; | 
| sqlite3VdbeUsesBtree(v, iDb); | 
| if( !zRight ){ | 
| sqlite3VdbeSetNumCols(v, 1); | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC); | 
| pParse->nMem += 2; | 
| -      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); | 
| +      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn); | 
| sqlite3VdbeChangeP1(v, addr, iDb); | 
| sqlite3VdbeChangeP1(v, addr+1, iDb); | 
| sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); | 
| @@ -392,8 +860,11 @@ 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) | 
| /* | 
| **  PRAGMA [database.]page_size | 
| **  PRAGMA [database.]page_size=N | 
| @@ -403,7 +874,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 ){ | 
| @@ -414,11 +885,12 @@ void sqlite3Pragma( | 
| ** buffer that the pager module resizes using sqlite3_realloc(). | 
| */ | 
| db->nextPagesize = sqlite3Atoi(zRight); | 
| -      if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ | 
| +      if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ | 
| db->mallocFailed = 1; | 
| } | 
| } | 
| -  }else | 
| +    break; | 
| +  } | 
|  | 
| /* | 
| **  PRAGMA [database.]secure_delete | 
| @@ -428,12 +900,12 @@ 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 ); | 
| if( zRight ){ | 
| -      b = getBoolean(zRight); | 
| +      b = sqlite3GetBoolean(zRight, 0); | 
| } | 
| if( pId2->n==0 && b>=0 ){ | 
| int ii; | 
| @@ -443,7 +915,8 @@ void sqlite3Pragma( | 
| } | 
| b = sqlite3BtreeSecureDelete(pBt, b); | 
| returnSingleInt(pParse, "secure_delete", b); | 
| -  }else | 
| +    break; | 
| +  } | 
|  | 
| /* | 
| **  PRAGMA [database.]max_page_count | 
| @@ -454,32 +927,35 @@ void sqlite3Pragma( | 
| ** second form attempts to change this setting.  Both | 
| ** forms return the current setting. | 
| ** | 
| +  ** The absolute value of N is used.  This is undocumented and might | 
| +  ** change.  The only purpose is to provide an easy way to test | 
| +  ** the sqlite3AbsInt32() function. | 
| +  ** | 
| **  PRAGMA [database.]page_count | 
| ** | 
| ** 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); | 
| iReg = ++pParse->nMem; | 
| -    if( zLeft[0]=='p' ){ | 
| +    if( sqlite3Tolower(zLeft[0])=='p' ){ | 
| sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); | 
| }else{ | 
| -      sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight)); | 
| +      sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, | 
| +                        sqlite3AbsInt32(sqlite3Atoi(zRight))); | 
| } | 
| 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); | 
|  | 
| @@ -512,7 +988,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"; | 
| } | 
| @@ -520,23 +997,18 @@ 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 */ | 
|  | 
| -    /* Force the schema to be loaded on all databases.  This cases all | 
| -    ** database files to be opened and the journal_modes set. */ | 
| -    if( sqlite3ReadSchema(pParse) ){ | 
| -      goto pragma_out; | 
| -    } | 
| - | 
| sqlite3VdbeSetNumCols(v, 1); | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); | 
|  | 
| @@ -568,7 +1040,8 @@ void sqlite3Pragma( | 
| } | 
| } | 
| sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); | 
| -  }else | 
| +    break; | 
| +  } | 
|  | 
| /* | 
| **  PRAGMA [database.]journal_size_limit | 
| @@ -576,16 +1049,17 @@ 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 ){ | 
| -      sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); | 
| +      sqlite3DecOrHexToI64(zRight, &iLimit); | 
| if( iLimit<-1 ) iLimit = -1; | 
| } | 
| iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); | 
| returnSingleInt(pParse, "journal_size_limit", iLimit); | 
| -  }else | 
| +    break; | 
| +  } | 
|  | 
| #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ | 
|  | 
| @@ -597,57 +1071,48 @@ 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) ){ | 
| -      goto pragma_out; | 
| -    } | 
| if( !zRight ){ | 
| -      int auto_vacuum; | 
| -      if( ALWAYS(pBt) ){ | 
| -         auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt); | 
| -      }else{ | 
| -         auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM; | 
| -      } | 
| -      returnSingleInt(pParse, "auto_vacuum", auto_vacuum); | 
| +      returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); | 
| }else{ | 
| int eAuto = getAutoVacuum(zRight); | 
| assert( eAuto>=0 && eAuto<=2 ); | 
| db->nextAutovac = (u8)eAuto; | 
| -      if( ALWAYS(eAuto>=0) ){ | 
| -        /* Call SetAutoVacuum() to set initialize the internal auto and | 
| -        ** incr-vacuum flags. This is required in case this connection | 
| -        ** creates the database file. It is important that it is created | 
| -        ** as an auto-vacuum capable db. | 
| +      /* Call SetAutoVacuum() to set initialize the internal auto and | 
| +      ** incr-vacuum flags. This is required in case this connection | 
| +      ** creates the database file. It is important that it is created | 
| +      ** as an auto-vacuum capable db. | 
| +      */ | 
| +      rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); | 
| +      if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ | 
| +        /* When setting the auto_vacuum mode to either "full" or | 
| +        ** "incremental", write the value of meta[6] in the database | 
| +        ** file. Before writing to meta[6], check that meta[3] indicates | 
| +        ** that this really is an auto-vacuum capable database. | 
| */ | 
| -        int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); | 
| -        if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ | 
| -          /* When setting the auto_vacuum mode to either "full" or | 
| -          ** "incremental", write the value of meta[6] in the database | 
| -          ** file. Before writing to meta[6], check that meta[3] indicates | 
| -          ** that this really is an auto-vacuum capable database. | 
| -          */ | 
| -          static const VdbeOpList setMeta6[] = { | 
| -            { OP_Transaction,    0,         1,                 0},    /* 0 */ | 
| -            { OP_ReadCookie,     0,         1,         BTREE_LARGEST_ROOT_PAGE}, | 
| -            { OP_If,             1,         0,                 0},    /* 2 */ | 
| -            { OP_Halt,           SQLITE_OK, OE_Abort,          0},    /* 3 */ | 
| -            { OP_Integer,        0,         1,                 0},    /* 4 */ | 
| -            { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 1},    /* 5 */ | 
| -          }; | 
| -          int iAddr; | 
| -          iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); | 
| -          sqlite3VdbeChangeP1(v, iAddr, iDb); | 
| -          sqlite3VdbeChangeP1(v, iAddr+1, iDb); | 
| -          sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); | 
| -          sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); | 
| -          sqlite3VdbeChangeP1(v, iAddr+5, iDb); | 
| -          sqlite3VdbeUsesBtree(v, iDb); | 
| -        } | 
| +        static const int iLn = VDBE_OFFSET_LINENO(2); | 
| +        static const VdbeOpList setMeta6[] = { | 
| +          { OP_Transaction,    0,         1,                 0},    /* 0 */ | 
| +          { OP_ReadCookie,     0,         1,         BTREE_LARGEST_ROOT_PAGE}, | 
| +          { OP_If,             1,         0,                 0},    /* 2 */ | 
| +          { OP_Halt,           SQLITE_OK, OE_Abort,          0},    /* 3 */ | 
| +          { OP_Integer,        0,         1,                 0},    /* 4 */ | 
| +          { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 1},    /* 5 */ | 
| +        }; | 
| +        int iAddr; | 
| +        iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); | 
| +        sqlite3VdbeChangeP1(v, iAddr, iDb); | 
| +        sqlite3VdbeChangeP1(v, iAddr+1, iDb); | 
| +        sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); | 
| +        sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); | 
| +        sqlite3VdbeChangeP1(v, iAddr+5, iDb); | 
| +        sqlite3VdbeUsesBtree(v, iDb); | 
| } | 
| } | 
| -  }else | 
| +    break; | 
| +  } | 
| #endif | 
|  | 
| /* | 
| @@ -656,22 +1121,20 @@ 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; | 
| -    } | 
| if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ | 
| iLimit = 0x7fffffff; | 
| } | 
| sqlite3BeginWriteOperation(pParse, 0, iDb); | 
| sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); | 
| -    addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); | 
| +    addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); | 
| sqlite3VdbeAddOp1(v, OP_ResultRow, 1); | 
| sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); | 
| -    sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); | 
| +    sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); | 
| sqlite3VdbeJumpHere(v, addr); | 
| -  }else | 
| +    break; | 
| +  } | 
| #endif | 
|  | 
| #ifndef SQLITE_OMIT_PAGER_PRAGMAS | 
| @@ -680,26 +1143,67 @@ void sqlite3Pragma( | 
| **  PRAGMA [database.]cache_size=N | 
| ** | 
| ** The first form reports the current local setting for the | 
| -  ** page cache size.  The local setting can be different from | 
| -  ** the persistent cache size value that is stored in the database | 
| -  ** file itself.  The value returned is the maximum number of | 
| -  ** pages in the page cache.  The second form sets the local | 
| -  ** page cache size value.  It does not change the persistent | 
| -  ** cache size stored on the disk so the cache size will revert | 
| -  ** to its default value when the database is closed and reopened. | 
| -  ** N should be a positive integer. | 
| +  ** page cache size. The second form sets the local | 
| +  ** page cache size value.  If N is positive then that is the | 
| +  ** number of pages in the cache.  If N is negative, then the | 
| +  ** number of pages is adjusted so that the cache uses -N kibibytes | 
| +  ** of memory. | 
| */ | 
| -  if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ | 
| -    if( sqlite3ReadSchema(pParse) ) goto pragma_out; | 
| +  case PragTyp_CACHE_SIZE: { | 
| assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); | 
| if( !zRight ){ | 
| returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); | 
| }else{ | 
| -      int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); | 
| +      int size = sqlite3Atoi(zRight); | 
| pDb->pSchema->cache_size = size; | 
| sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); | 
| } | 
| -  }else | 
| +    break; | 
| +  } | 
| + | 
| +  /* | 
| +  **  PRAGMA [database.]mmap_size(N) | 
| +  ** | 
| +  ** Used to set mapping size limit. The mapping size limit is | 
| +  ** used to limit the aggregate size of all memory mapped regions of the | 
| +  ** database file. If this parameter is set to zero, then memory mapping | 
| +  ** is not used at all.  If N is negative, then the default memory map | 
| +  ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. | 
| +  ** The parameter N is measured in bytes. | 
| +  ** | 
| +  ** This value is advisory.  The underlying VFS is free to memory map | 
| +  ** 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. | 
| +  */ | 
| +  case PragTyp_MMAP_SIZE: { | 
| +    sqlite3_int64 sz; | 
| +#if SQLITE_MAX_MMAP_SIZE>0 | 
| +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); | 
| +    if( zRight ){ | 
| +      int ii; | 
| +      sqlite3DecOrHexToI64(zRight, &sz); | 
| +      if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; | 
| +      if( pId2->n==0 ) db->szMmap = sz; | 
| +      for(ii=db->nDb-1; ii>=0; ii--){ | 
| +        if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ | 
| +          sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); | 
| +        } | 
| +      } | 
| +    } | 
| +    sz = -1; | 
| +    rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); | 
| +#else | 
| +    sz = 0; | 
| +    rc = SQLITE_OK; | 
| +#endif | 
| +    if( rc==SQLITE_OK ){ | 
| +      returnSingleInt(pParse, "mmap_size", sz); | 
| +    }else if( rc!=SQLITE_NOTFOUND ){ | 
| +      pParse->nErr++; | 
| +      pParse->rc = rc; | 
| +    } | 
| +    break; | 
| +  } | 
|  | 
| /* | 
| **   PRAGMA temp_store | 
| @@ -712,13 +1216,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 | 
| @@ -730,7 +1235,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); | 
| @@ -742,7 +1247,6 @@ void sqlite3Pragma( | 
| }else{ | 
| #ifndef SQLITE_OMIT_WSD | 
| if( zRight[0] ){ | 
| -        int rc; | 
| int res; | 
| rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); | 
| if( rc!=SQLITE_OK || res==0 ){ | 
| @@ -764,30 +1268,69 @@ void sqlite3Pragma( | 
| } | 
| #endif /* SQLITE_OMIT_WSD */ | 
| } | 
| -  }else | 
| +    break; | 
| +  } | 
|  | 
| -#if !defined(SQLITE_ENABLE_LOCKING_STYLE) | 
| -#  if defined(__APPLE__) | 
| -#    define SQLITE_ENABLE_LOCKING_STYLE 1 | 
| -#  else | 
| -#    define SQLITE_ENABLE_LOCKING_STYLE 0 | 
| -#  endif | 
| +#if SQLITE_OS_WIN | 
| +  /* | 
| +  **   PRAGMA data_store_directory | 
| +  **   PRAGMA data_store_directory = ""|"directory_name" | 
| +  ** | 
| +  ** Return or set the local value of the data_store_directory flag.  Changing | 
| +  ** the value sets a specific directory to be used for database files that | 
| +  ** were specified with a relative pathname.  Setting to a null string reverts | 
| +  ** to the default database directory, which for database files specified with | 
| +  ** a relative path will probably be based on the current directory for the | 
| +  ** process.  Database file specified with an absolute path are not impacted | 
| +  ** by this setting, regardless of its value. | 
| +  ** | 
| +  */ | 
| +  case PragTyp_DATA_STORE_DIRECTORY: { | 
| +    if( !zRight ){ | 
| +      if( sqlite3_data_directory ){ | 
| +        sqlite3VdbeSetNumCols(v, 1); | 
| +        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, | 
| +            "data_store_directory", SQLITE_STATIC); | 
| +        sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0); | 
| +        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); | 
| +      } | 
| +    }else{ | 
| +#ifndef SQLITE_OMIT_WSD | 
| +      if( zRight[0] ){ | 
| +        int res; | 
| +        rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); | 
| +        if( rc!=SQLITE_OK || res==0 ){ | 
| +          sqlite3ErrorMsg(pParse, "not a writable directory"); | 
| +          goto pragma_out; | 
| +        } | 
| +      } | 
| +      sqlite3_free(sqlite3_data_directory); | 
| +      if( zRight[0] ){ | 
| +        sqlite3_data_directory = sqlite3_mprintf("%s", zRight); | 
| +      }else{ | 
| +        sqlite3_data_directory = 0; | 
| +      } | 
| +#endif /* SQLITE_OMIT_WSD */ | 
| +    } | 
| +    break; | 
| +  } | 
| #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; | 
| sqlite3_file *pFile = sqlite3PagerFile(pPager); | 
| -      sqlite3OsFileControl(pFile, SQLITE_GET_LOCKPROXYFILE, | 
| +      sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, | 
| &proxy_file_path); | 
|  | 
| if( proxy_file_path ){ | 
| @@ -813,7 +1356,8 @@ void sqlite3Pragma( | 
| goto pragma_out; | 
| } | 
| } | 
| -  }else | 
| +    break; | 
| +  } | 
| #endif /* SQLITE_ENABLE_LOCKING_STYLE */ | 
|  | 
| /* | 
| @@ -825,8 +1369,7 @@ void sqlite3Pragma( | 
| ** default value will be restored the next time the database is | 
| ** opened. | 
| */ | 
| -  if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ | 
| -    if( sqlite3ReadSchema(pParse) ) goto pragma_out; | 
| +  case PragTyp_SYNCHRONOUS: { | 
| if( !zRight ){ | 
| returnSingleInt(pParse, "synchronous", pDb->safety_level-1); | 
| }else{ | 
| @@ -834,17 +1377,49 @@ void sqlite3Pragma( | 
| sqlite3ErrorMsg(pParse, | 
| "Safety level may not be changed inside a transaction"); | 
| }else{ | 
| -        pDb->safety_level = getSafetyLevel(zRight)+1; | 
| +        pDb->safety_level = getSafetyLevel(zRight,0,1)+1; | 
| +        setAllPagerFlags(db); | 
| } | 
| } | 
| -  }else | 
| +    break; | 
| +  } | 
| #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ | 
|  | 
| #ifndef SQLITE_OMIT_FLAG_PRAGMAS | 
| -  if( flagPragma(pParse, zLeft, zRight) ){ | 
| -    /* The flagPragma() subroutine also generates any necessary code | 
| -    ** there is nothing more to do here */ | 
| -  }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 SQLITE_USER_AUTHENTICATION | 
| +      if( db->auth.authLevel==UAUTH_User ){ | 
| +        /* Do not allow non-admin users to modify the schema arbitrarily */ | 
| +        mask &= ~(SQLITE_WriteSchema); | 
| +      } | 
| +#endif | 
| + | 
| +      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 | 
| @@ -860,16 +1435,17 @@ 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); | 
| if( pTab ){ | 
| -      int i; | 
| +      int i, k; | 
| int nHidden = 0; | 
| Column *pCol; | 
| +      Index *pPk = sqlite3PrimaryKeyIndex(pTab); | 
| sqlite3VdbeSetNumCols(v, 6); | 
| pParse->nMem = 6; | 
| +      sqlite3CodeVerifySchema(pParse, iDb); | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC); | 
| sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); | 
| sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC); | 
| @@ -892,27 +1468,67 @@ void sqlite3Pragma( | 
| }else{ | 
| sqlite3VdbeAddOp2(v, OP_Null, 0, 5); | 
| } | 
| -        sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6); | 
| +        if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){ | 
| +          k = 0; | 
| +        }else if( pPk==0 ){ | 
| +          k = 1; | 
| +        }else{ | 
| +          for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){} | 
| +        } | 
| +        sqlite3VdbeAddOp2(v, OP_Integer, k, 6); | 
| sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); | 
| } | 
| } | 
| -  }else | 
| +  } | 
| +  break; | 
| + | 
| +  case PragTyp_STATS: { | 
| +    Index *pIdx; | 
| +    HashElem *i; | 
| +    v = sqlite3GetVdbe(pParse); | 
| +    sqlite3VdbeSetNumCols(v, 4); | 
| +    pParse->nMem = 4; | 
| +    sqlite3CodeVerifySchema(pParse, iDb); | 
| +    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC); | 
| +    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "index", SQLITE_STATIC); | 
| +    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "width", SQLITE_STATIC); | 
| +    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "height", SQLITE_STATIC); | 
| +    for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ | 
| +      Table *pTab = sqliteHashData(i); | 
| +      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0); | 
| +      sqlite3VdbeAddOp2(v, OP_Null, 0, 2); | 
| +      sqlite3VdbeAddOp2(v, OP_Integer, | 
| +                           (int)sqlite3LogEstToInt(pTab->szTabRow), 3); | 
| +      sqlite3VdbeAddOp2(v, OP_Integer, | 
| +          (int)sqlite3LogEstToInt(pTab->nRowLogEst), 4); | 
| +      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); | 
| +      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 
| +        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); | 
| +        sqlite3VdbeAddOp2(v, OP_Integer, | 
| +                             (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3); | 
| +        sqlite3VdbeAddOp2(v, OP_Integer, | 
| +            (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4); | 
| +        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); | 
| +      } | 
| +    } | 
| +  } | 
| +  break; | 
|  | 
| -  if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ | 
| +  case PragTyp_INDEX_INFO: if( zRight ){ | 
| Index *pIdx; | 
| Table *pTab; | 
| -    if( sqlite3ReadSchema(pParse) ) goto pragma_out; | 
| pIdx = sqlite3FindIndex(db, zRight, zDb); | 
| if( pIdx ){ | 
| int i; | 
| pTab = pIdx->pTable; | 
| sqlite3VdbeSetNumCols(v, 3); | 
| pParse->nMem = 3; | 
| +      sqlite3CodeVerifySchema(pParse, iDb); | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC); | 
| sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC); | 
| sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC); | 
| -      for(i=0; i<pIdx->nColumn; i++){ | 
| -        int cnum = pIdx->aiColumn[i]; | 
| +      for(i=0; i<pIdx->nKeyCol; i++){ | 
| +        i16 cnum = pIdx->aiColumn[i]; | 
| sqlite3VdbeAddOp2(v, OP_Integer, i, 1); | 
| sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2); | 
| assert( pTab->nCol>cnum ); | 
| @@ -920,38 +1536,34 @@ 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; | 
| +    int i; | 
| pTab = sqlite3FindTable(db, zRight, zDb); | 
| if( pTab ){ | 
| v = sqlite3GetVdbe(pParse); | 
| -      pIdx = pTab->pIndex; | 
| -      if( pIdx ){ | 
| -        int i = 0; | 
| -        sqlite3VdbeSetNumCols(v, 3); | 
| -        pParse->nMem = 3; | 
| -        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); | 
| -        sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); | 
| -        sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); | 
| -        while(pIdx){ | 
| -          sqlite3VdbeAddOp2(v, OP_Integer, i, 1); | 
| -          sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); | 
| -          sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3); | 
| -          sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); | 
| -          ++i; | 
| -          pIdx = pIdx->pNext; | 
| -        } | 
| +      sqlite3VdbeSetNumCols(v, 3); | 
| +      pParse->nMem = 3; | 
| +      sqlite3CodeVerifySchema(pParse, iDb); | 
| +      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); | 
| +      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); | 
| +      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); | 
| +      for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ | 
| +        sqlite3VdbeAddOp2(v, OP_Integer, i, 1); | 
| +        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); | 
| +        sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3); | 
| +        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); | 
| } | 
| } | 
| -  }else | 
| +  } | 
| +  break; | 
|  | 
| -  if( sqlite3StrICmp(zLeft, "database_list")==0 ){ | 
| +  case PragTyp_DATABASE_LIST: { | 
| int i; | 
| -    if( sqlite3ReadSchema(pParse) ) goto pragma_out; | 
| sqlite3VdbeSetNumCols(v, 3); | 
| pParse->nMem = 3; | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); | 
| @@ -966,9 +1578,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); | 
| @@ -981,14 +1594,14 @@ 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; | 
| pTab = sqlite3FindTable(db, zRight, zDb); | 
| if( pTab ){ | 
| v = sqlite3GetVdbe(pParse); | 
| @@ -997,6 +1610,7 @@ void sqlite3Pragma( | 
| int i = 0; | 
| sqlite3VdbeSetNumCols(v, 8); | 
| pParse->nMem = 8; | 
| +        sqlite3CodeVerifySchema(pParse, iDb); | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC); | 
| sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC); | 
| sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC); | 
| @@ -1027,59 +1641,191 @@ void sqlite3Pragma( | 
| } | 
| } | 
| } | 
| -  }else | 
| +  } | 
| +  break; | 
| +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ | 
| + | 
| +#ifndef SQLITE_OMIT_FOREIGN_KEY | 
| +#ifndef SQLITE_OMIT_TRIGGER | 
| +  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 */ | 
| +    Index *pIdx;           /* Index in the parent table */ | 
| +    int i;                 /* Loop counter:  Foreign key number for pTab */ | 
| +    int j;                 /* Loop counter:  Field of the foreign key */ | 
| +    HashElem *k;           /* Loop counter:  Next table in schema */ | 
| +    int x;                 /* result variable */ | 
| +    int regResult;         /* 3 registers to hold a result row */ | 
| +    int regKey;            /* Register to hold key for checking the FK */ | 
| +    int regRow;            /* Registers to hold a row from pTab */ | 
| +    int addrTop;           /* Top of a loop checking foreign keys */ | 
| +    int addrOk;            /* Jump here if the key is OK */ | 
| +    int *aiCols;           /* child to parent column mapping */ | 
| + | 
| +    regResult = pParse->nMem+1; | 
| +    pParse->nMem += 4; | 
| +    regKey = ++pParse->nMem; | 
| +    regRow = ++pParse->nMem; | 
| +    v = sqlite3GetVdbe(pParse); | 
| +    sqlite3VdbeSetNumCols(v, 4); | 
| +    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC); | 
| +    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC); | 
| +    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC); | 
| +    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC); | 
| +    sqlite3CodeVerifySchema(pParse, iDb); | 
| +    k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); | 
| +    while( k ){ | 
| +      if( zRight ){ | 
| +        pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); | 
| +        k = 0; | 
| +      }else{ | 
| +        pTab = (Table*)sqliteHashData(k); | 
| +        k = sqliteHashNext(k); | 
| +      } | 
| +      if( pTab==0 || pTab->pFKey==0 ) continue; | 
| +      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); | 
| +      if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; | 
| +      sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); | 
| +      sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName, | 
| +                        P4_TRANSIENT); | 
| +      for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ | 
| +        pParent = sqlite3FindTable(db, pFK->zTo, zDb); | 
| +        if( pParent==0 ) continue; | 
| +        pIdx = 0; | 
| +        sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); | 
| +        x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); | 
| +        if( x==0 ){ | 
| +          if( pIdx==0 ){ | 
| +            sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead); | 
| +          }else{ | 
| +            sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb); | 
| +            sqlite3VdbeSetP4KeyInfo(pParse, pIdx); | 
| +          } | 
| +        }else{ | 
| +          k = 0; | 
| +          break; | 
| +        } | 
| +      } | 
| +      assert( pParse->nErr>0 || pFK==0 ); | 
| +      if( pFK ) break; | 
| +      if( pParse->nTab<i ) pParse->nTab = i; | 
| +      addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); | 
| +      for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ | 
| +        pParent = sqlite3FindTable(db, pFK->zTo, zDb); | 
| +        pIdx = 0; | 
| +        aiCols = 0; | 
| +        if( pParent ){ | 
| +          x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); | 
| +          assert( x==0 ); | 
| +        } | 
| +        addrOk = sqlite3VdbeMakeLabel(v); | 
| +        if( pParent && pIdx==0 ){ | 
| +          int iKey = pFK->aCol[0].iFrom; | 
| +          assert( iKey>=0 && iKey<pTab->nCol ); | 
| +          if( iKey!=pTab->iPKey ){ | 
| +            sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow); | 
| +            sqlite3ColumnDefault(v, pTab, iKey, regRow); | 
| +            sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v); | 
| +            sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow, | 
| +               sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v); | 
| +          }else{ | 
| +            sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow); | 
| +          } | 
| +          sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v); | 
| +          sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk); | 
| +          sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); | 
| +        }else{ | 
| +          for(j=0; j<pFK->nCol; j++){ | 
| +            sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, | 
| +                            aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); | 
| +            sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); | 
| +          } | 
| +          if( pParent ){ | 
| +            sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, | 
| +                              sqlite3IndexAffinityStr(v,pIdx), pFK->nCol); | 
| +            sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); | 
| +            VdbeCoverage(v); | 
| +          } | 
| +        } | 
| +        sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); | 
| +        sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0, | 
| +                          pFK->zTo, P4_TRANSIENT); | 
| +        sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3); | 
| +        sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); | 
| +        sqlite3VdbeResolveLabel(v, addrOk); | 
| +        sqlite3DbFree(db, aiCols); | 
| +      } | 
| +      sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); | 
| +      sqlite3VdbeJumpHere(v, addrTop); | 
| +    } | 
| +  } | 
| +  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( getBoolean(zRight) ){ | 
| +      if( sqlite3GetBoolean(zRight, 0) ){ | 
| sqlite3ParserTrace(stderr, "parser: "); | 
| }else{ | 
| 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, getBoolean(zRight)); | 
| +      sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); | 
| } | 
| -  }else | 
| +  } | 
| +  break; | 
|  | 
| #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX | 
| # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 | 
| #endif | 
|  | 
| #ifndef SQLITE_OMIT_INTEGRITY_CHECK | 
| -  /* Pragma "quick_check" is an experimental reduced version of | 
| +  /* Pragma "quick_check" is reduced version of | 
| ** 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 | 
| ** messages have been generated, output OK.  Otherwise output the | 
| ** error message | 
| */ | 
| +    static const int iLn = VDBE_OFFSET_LINENO(2); | 
| static const VdbeOpList endCode[] = { | 
| -      { OP_AddImm,      1, 0,        0},    /* 0 */ | 
| -      { OP_IfNeg,       1, 0,        0},    /* 1 */ | 
| -      { OP_String8,     0, 3,        0},    /* 2 */ | 
| +      { OP_IfNeg,       1, 0,        0},    /* 0 */ | 
| +      { OP_String8,     0, 3,        0},    /* 1 */ | 
| { OP_ResultRow,   3, 1,        0}, | 
| }; | 
|  | 
| -    int isQuick = (zLeft[0]=='q'); | 
| +    int isQuick = (sqlite3Tolower(zLeft[0])=='q'); | 
| + | 
| +    /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check", | 
| +    ** then iDb is set to the index of the database identified by <db>. | 
| +    ** In this case, the integrity of database iDb only is verified by | 
| +    ** the VDBE created below. | 
| +    ** | 
| +    ** Otherwise, if the command was simply "PRAGMA integrity_check" (or | 
| +    ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb | 
| +    ** to -1 here, to indicate that the VDBE should verify the integrity | 
| +    ** of all attached databases.  */ | 
| +    assert( iDb>=0 ); | 
| +    assert( iDb==0 || pId2->z ); | 
| +    if( pId2->z==0 ) iDb = -1; | 
|  | 
| /* Initialize the VDBE program */ | 
| -    if( sqlite3ReadSchema(pParse) ) goto pragma_out; | 
| pParse->nMem = 6; | 
| sqlite3VdbeSetNumCols(v, 1); | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC); | 
| @@ -1101,9 +1847,11 @@ void sqlite3Pragma( | 
| int cnt = 0; | 
|  | 
| if( OMIT_TEMPDB && i==1 ) continue; | 
| +      if( iDb>=0 && i!=iDb ) continue; | 
|  | 
| sqlite3CodeVerifySchema(pParse, i); | 
| addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ | 
| +      VdbeCoverage(v); | 
| sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); | 
| sqlite3VdbeJumpHere(v, addr); | 
|  | 
| @@ -1112,28 +1860,30 @@ void sqlite3Pragma( | 
| ** Begin by filling registers 2, 3, ... with the root pages numbers | 
| ** for all tables and indices in the database. | 
| */ | 
| -      assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); | 
| +      assert( sqlite3SchemaMutexHeld(db, i, 0) ); | 
| pTbls = &db->aDb[i].pSchema->tblHash; | 
| for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ | 
| Table *pTab = sqliteHashData(x); | 
| Index *pIdx; | 
| -        sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); | 
| -        cnt++; | 
| +        if( HasRowid(pTab) ){ | 
| +          sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); | 
| +          VdbeComment((v, "%s", pTab->zName)); | 
| +          cnt++; | 
| +        } | 
| for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 
| sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt); | 
| +          VdbeComment((v, "%s", pIdx->zName)); | 
| cnt++; | 
| } | 
| } | 
|  | 
| /* Make sure sufficient number of registers have been allocated */ | 
| -      if( pParse->nMem < cnt+4 ){ | 
| -        pParse->nMem = cnt+4; | 
| -      } | 
| +      pParse->nMem = MAX( pParse->nMem, cnt+8 ); | 
|  | 
| /* Do the b-tree integrity checks */ | 
| sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1); | 
| sqlite3VdbeChangeP5(v, (u8)i); | 
| -      addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); | 
| +      addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); | 
| sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, | 
| sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), | 
| P4_DYNAMIC); | 
| @@ -1146,77 +1896,127 @@ void sqlite3Pragma( | 
| */ | 
| for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ | 
| Table *pTab = sqliteHashData(x); | 
| -        Index *pIdx; | 
| +        Index *pIdx, *pPk; | 
| +        Index *pPrior = 0; | 
| int loopTop; | 
| +        int iDataCur, iIdxCur; | 
| +        int r1 = -1; | 
|  | 
| if( pTab->pIndex==0 ) continue; | 
| +        pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); | 
| addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);  /* Stop if out of errors */ | 
| +        VdbeCoverage(v); | 
| sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); | 
| sqlite3VdbeJumpHere(v, addr); | 
| -        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); | 
| -        sqlite3VdbeAddOp2(v, OP_Integer, 0, 2);  /* reg(2) will count entries */ | 
| -        loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0); | 
| -        sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1);   /* increment entry count */ | 
| +        sqlite3ExprCacheClear(pParse); | 
| +        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, | 
| +                                   1, 0, &iDataCur, &iIdxCur); | 
| +        sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); | 
| for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | 
| -          int jmp2; | 
| -          int r1; | 
| -          static const VdbeOpList idxErr[] = { | 
| -            { OP_AddImm,      1, -1,  0}, | 
| -            { OP_String8,     0,  3,  0},    /* 1 */ | 
| -            { OP_Rowid,       1,  4,  0}, | 
| -            { OP_String8,     0,  5,  0},    /* 3 */ | 
| -            { OP_String8,     0,  6,  0},    /* 4 */ | 
| -            { OP_Concat,      4,  3,  3}, | 
| -            { OP_Concat,      5,  3,  3}, | 
| -            { OP_Concat,      6,  3,  3}, | 
| -            { OP_ResultRow,   3,  1,  0}, | 
| -            { OP_IfPos,       1,  0,  0},    /* 9 */ | 
| -            { OP_Halt,        0,  0,  0}, | 
| -          }; | 
| -          r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0); | 
| -          jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1); | 
| -          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); | 
| -          sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); | 
| -          sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC); | 
| -          sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT); | 
| -          sqlite3VdbeJumpHere(v, addr+9); | 
| +          sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ | 
| +        } | 
| +        pParse->nMem = MAX(pParse->nMem, 8+j); | 
| +        sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); | 
| +        loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); | 
| +        /* Verify that all NOT NULL columns really are NOT NULL */ | 
| +        for(j=0; j<pTab->nCol; j++){ | 
| +          char *zErr; | 
| +          int jmp2, jmp3; | 
| +          if( j==pTab->iPKey ) continue; | 
| +          if( pTab->aCol[j].notNull==0 ) continue; | 
| +          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); | 
| +          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); | 
| +          jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); | 
| +          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ | 
| +          zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, | 
| +                              pTab->aCol[j].zName); | 
| +          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); | 
| +          sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); | 
| +          jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); | 
| +          sqlite3VdbeAddOp0(v, OP_Halt); | 
| sqlite3VdbeJumpHere(v, jmp2); | 
| +          sqlite3VdbeJumpHere(v, jmp3); | 
| } | 
| -        sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1); | 
| -        sqlite3VdbeJumpHere(v, loopTop); | 
| +        /* Validate index entries for the current row */ | 
| for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | 
| -          static const VdbeOpList cntIdx[] = { | 
| -             { OP_Integer,      0,  3,  0}, | 
| -             { OP_Rewind,       0,  0,  0},  /* 1 */ | 
| -             { OP_AddImm,       3,  1,  0}, | 
| -             { OP_Next,         0,  0,  0},  /* 3 */ | 
| -             { OP_Eq,           2,  0,  3},  /* 4 */ | 
| -             { OP_AddImm,       1, -1,  0}, | 
| -             { OP_String8,      0,  2,  0},  /* 6 */ | 
| -             { OP_String8,      0,  3,  0},  /* 7 */ | 
| -             { OP_Concat,       3,  2,  2}, | 
| -             { OP_ResultRow,    2,  1,  0}, | 
| -          }; | 
| -          addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); | 
| -          sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); | 
| -          sqlite3VdbeJumpHere(v, addr); | 
| -          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); | 
| -          sqlite3VdbeChangeP1(v, addr+1, j+2); | 
| -          sqlite3VdbeChangeP2(v, addr+1, addr+4); | 
| -          sqlite3VdbeChangeP1(v, addr+3, j+2); | 
| -          sqlite3VdbeChangeP2(v, addr+3, addr+2); | 
| -          sqlite3VdbeJumpHere(v, addr+4); | 
| -          sqlite3VdbeChangeP4(v, addr+6, | 
| +          int jmp2, jmp3, jmp4, jmp5; | 
| +          int ckUniq = sqlite3VdbeMakeLabel(v); | 
| +          if( pPk==pIdx ) continue; | 
| +          r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, | 
| +                                       pPrior, r1); | 
| +          pPrior = pIdx; | 
| +          sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);  /* increment entry count */ | 
| +          /* Verify that an index entry exists for the current table row */ | 
| +          jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, | 
| +                                      pIdx->nColumn); VdbeCoverage(v); | 
| +          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ | 
| +          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC); | 
| +          sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); | 
| +          sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, | 
| +                            " missing from index ", P4_STATIC); | 
| +          sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); | 
| +          jmp5 = sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, | 
| +                                   pIdx->zName, P4_TRANSIENT); | 
| +          sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); | 
| +          sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); | 
| +          jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); | 
| +          sqlite3VdbeAddOp0(v, OP_Halt); | 
| +          sqlite3VdbeJumpHere(v, jmp2); | 
| +          /* For UNIQUE indexes, verify that only one entry exists with the | 
| +          ** current key.  The entry is unique if (1) any column is NULL | 
| +          ** or (2) the next entry has a different key */ | 
| +          if( IsUniqueIndex(pIdx) ){ | 
| +            int uniqOk = sqlite3VdbeMakeLabel(v); | 
| +            int jmp6; | 
| +            int kk; | 
| +            for(kk=0; kk<pIdx->nKeyCol; kk++){ | 
| +              int iCol = pIdx->aiColumn[kk]; | 
| +              assert( iCol>=0 && iCol<pTab->nCol ); | 
| +              if( pTab->aCol[iCol].notNull ) continue; | 
| +              sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); | 
| +              VdbeCoverage(v); | 
| +            } | 
| +            jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); | 
| +            sqlite3VdbeAddOp2(v, OP_Goto, 0, uniqOk); | 
| +            sqlite3VdbeJumpHere(v, jmp6); | 
| +            sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, | 
| +                                 pIdx->nKeyCol); VdbeCoverage(v); | 
| +            sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ | 
| +            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, | 
| +                              "non-unique entry in index ", P4_STATIC); | 
| +            sqlite3VdbeAddOp2(v, OP_Goto, 0, jmp5); | 
| +            sqlite3VdbeResolveLabel(v, uniqOk); | 
| +          } | 
| +          sqlite3VdbeJumpHere(v, jmp4); | 
| +          sqlite3ResolvePartIdxLabel(pParse, jmp3); | 
| +        } | 
| +        sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); | 
| +        sqlite3VdbeJumpHere(v, loopTop-1); | 
| +#ifndef SQLITE_OMIT_BTREECOUNT | 
| +        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, | 
| "wrong # of entries in index ", P4_STATIC); | 
| -          sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT); | 
| +        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | 
| +          if( pPk==pIdx ) continue; | 
| +          addr = sqlite3VdbeCurrentAddr(v); | 
| +          sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); | 
| +          sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); | 
| +          sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); | 
| +          sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); | 
| +          sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); | 
| +          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); | 
| +          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT); | 
| +          sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); | 
| +          sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); | 
| } | 
| +#endif /* SQLITE_OMIT_BTREECOUNT */ | 
| } | 
| } | 
| -    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); | 
| -    sqlite3VdbeChangeP2(v, addr, -mxErr); | 
| -    sqlite3VdbeJumpHere(v, addr+1); | 
| -    sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); | 
| -  }else | 
| +    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); | 
| +    sqlite3VdbeChangeP3(v, addr, -mxErr); | 
| +    sqlite3VdbeJumpHere(v, addr); | 
| +    sqlite3VdbeChangeP4(v, addr+1, "ok", P4_STATIC); | 
| +  } | 
| +  break; | 
| #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ | 
|  | 
| #ifndef SQLITE_OMIT_UTF16 | 
| @@ -1242,7 +2042,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; | 
| @@ -1289,7 +2089,8 @@ void sqlite3Pragma( | 
| } | 
| } | 
| } | 
| -  }else | 
| +  } | 
| +  break; | 
| #endif /* SQLITE_OMIT_UTF16 */ | 
|  | 
| #ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS | 
| @@ -1300,6 +2101,11 @@ void sqlite3Pragma( | 
| **   PRAGMA [database.]user_version | 
| **   PRAGMA [database.]user_version = <integer> | 
| ** | 
| +  **   PRAGMA [database.]freelist_count = <integer> | 
| +  ** | 
| +  **   PRAGMA [database.]application_id | 
| +  **   PRAGMA [database.]application_id = <integer> | 
| +  ** | 
| ** The pragma's schema_version and user_version are used to set or get | 
| ** the value of the schema-version and user-version, respectively. Both | 
| ** the schema-version and the user-version are 32-bit signed integers | 
| @@ -1318,13 +2124,13 @@ 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 | 
| -  ){ | 
| +  case PragTyp_HEADER_VALUE: { | 
| int iCookie;   /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */ | 
| sqlite3VdbeUsesBtree(v, iDb); | 
| switch( zLeft[0] ){ | 
| +      case 'a': case 'A': | 
| +        iCookie = BTREE_APPLICATION_ID; | 
| +        break; | 
| case 'f': case 'F': | 
| iCookie = BTREE_FREE_PAGE_COUNT; | 
| break; | 
| @@ -1343,7 +2149,7 @@ void sqlite3Pragma( | 
| { OP_Integer,        0,  1,  0},    /* 1 */ | 
| { OP_SetCookie,      0,  0,  1},    /* 2 */ | 
| }; | 
| -      int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); | 
| +      int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); | 
| sqlite3VdbeChangeP1(v, addr, iDb); | 
| sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight)); | 
| sqlite3VdbeChangeP1(v, addr+2, iDb); | 
| @@ -1355,14 +2161,15 @@ void sqlite3Pragma( | 
| { OP_ReadCookie,      0,  1,  0},    /* 1 */ | 
| { OP_ResultRow,       1,  1,  0} | 
| }; | 
| -      int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); | 
| +      int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0); | 
| sqlite3VdbeChangeP1(v, addr, iDb); | 
| sqlite3VdbeChangeP1(v, addr+1, iDb); | 
| sqlite3VdbeChangeP3(v, addr+1, iCookie); | 
| sqlite3VdbeSetNumCols(v, 1); | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); | 
| } | 
| -  }else | 
| +  } | 
| +  break; | 
| #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ | 
|  | 
| #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS | 
| @@ -1372,7 +2179,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); | 
| @@ -1382,7 +2189,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 | 
| @@ -1391,7 +2199,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 ){ | 
| @@ -1401,7 +2209,6 @@ void sqlite3Pragma( | 
| eMode = SQLITE_CHECKPOINT_RESTART; | 
| } | 
| } | 
| -    if( sqlite3ReadSchema(pParse) ) goto pragma_out; | 
| sqlite3VdbeSetNumCols(v, 3); | 
| pParse->nMem = 3; | 
| sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); | 
| @@ -1410,7 +2217,8 @@ void sqlite3Pragma( | 
|  | 
| sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); | 
| sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); | 
| -  }else | 
| +  } | 
| +  break; | 
|  | 
| /* | 
| **   PRAGMA wal_autocheckpoint | 
| @@ -1420,21 +2228,87 @@ 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 | 
|  | 
| +  /* | 
| +  **  PRAGMA shrink_memory | 
| +  ** | 
| +  ** This pragma attempts to free as much memory as possible from the | 
| +  ** current database connection. | 
| +  */ | 
| +  case PragTyp_SHRINK_MEMORY: { | 
| +    sqlite3_db_release_memory(db); | 
| +    break; | 
| +  } | 
| + | 
| +  /* | 
| +  **   PRAGMA busy_timeout | 
| +  **   PRAGMA busy_timeout = N | 
| +  ** | 
| +  ** Call sqlite3_busy_timeout(db, N).  Return the current timeout value | 
| +  ** if one is set.  If no busy handler or a different busy handler is set | 
| +  ** then 0 is returned.  Setting the busy_timeout to 0 or negative | 
| +  ** disables the timeout. | 
| +  */ | 
| +  /*case PragTyp_BUSY_TIMEOUT*/ default: { | 
| +    assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT ); | 
| +    if( zRight ){ | 
| +      sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); | 
| +    } | 
| +    returnSingleInt(pParse, "timeout",  db->busyTimeout); | 
| +    break; | 
| +  } | 
| + | 
| +  /* | 
| +  **   PRAGMA soft_heap_limit | 
| +  **   PRAGMA soft_heap_limit = N | 
| +  ** | 
| +  ** Call sqlite3_soft_heap_limit64(N).  Return the result.  If N is omitted, | 
| +  ** use -1. | 
| +  */ | 
| +  case PragTyp_SOFT_HEAP_LIMIT: { | 
| +    sqlite3_int64 N; | 
| +    if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ | 
| +      sqlite3_soft_heap_limit64(N); | 
| +    } | 
| +    returnSingleInt(pParse, "soft_heap_limit",  sqlite3_soft_heap_limit64(-1)); | 
| +    break; | 
| +  } | 
| + | 
| +  /* | 
| +  **   PRAGMA threads | 
| +  **   PRAGMA threads = N | 
| +  ** | 
| +  ** Configure the maximum number of worker threads.  Return the new | 
| +  ** maximum, which might be less than requested. | 
| +  */ | 
| +  case PragTyp_THREADS: { | 
| +    sqlite3_int64 N; | 
| +    if( zRight | 
| +     && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK | 
| +     && N>=0 | 
| +    ){ | 
| +      sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); | 
| +    } | 
| +    returnSingleInt(pParse, "threads", | 
| +                    sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); | 
| +    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" | 
| }; | 
| @@ -1445,13 +2319,12 @@ void sqlite3Pragma( | 
| sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC); | 
| for(i=0; i<db->nDb; i++){ | 
| Btree *pBt; | 
| -      Pager *pPager; | 
| const char *zState = "unknown"; | 
| int j; | 
| if( db->aDb[i].zName==0 ) continue; | 
| sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC); | 
| pBt = db->aDb[i].pBt; | 
| -      if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ | 
| +      if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ | 
| zState = "closed"; | 
| }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, | 
| SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ | 
| @@ -1460,35 +2333,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(db, zRight, sqlite3Strlen30(zRight)); | 
| -  }else | 
| -  if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){ | 
| -    sqlite3_rekey(db, 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(db, zKey, i/2); | 
| -    }else{ | 
| -      sqlite3_rekey(db, 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 ){ | 
| +      u8 iByte; | 
| +      int i; | 
| +      char zKey[40]; | 
| +      for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){ | 
| +        iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]); | 
| +        if( (i&1)!=0 ) zKey[i/2] = iByte; | 
| +      } | 
| +      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 ){ | 
| +  case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){ | 
| #ifdef SQLITE_HAS_CODEC | 
| if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ | 
| sqlite3_activate_see(&zRight[4]); | 
| @@ -1499,23 +2376,12 @@ void sqlite3Pragma( | 
| sqlite3_activate_cerod(&zRight[6]); | 
| } | 
| #endif | 
| -  }else | 
| +  } | 
| +  break; | 
| #endif | 
|  | 
| - | 
| -  {/* Empty ELSE clause */} | 
| +  } /* End of the PRAGMA switch */ | 
|  | 
| -  /* | 
| -  ** Reset the safety level, in case the fullfsync flag or synchronous | 
| -  ** setting changed. | 
| -  */ | 
| -#ifndef SQLITE_OMIT_PAGER_PRAGMAS | 
| -  if( db->autoCommit ){ | 
| -    sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, | 
| -               (db->flags&SQLITE_FullFSync)!=0, | 
| -               (db->flags&SQLITE_CkptFullFSync)!=0); | 
| -  } | 
| -#endif | 
| pragma_out: | 
| sqlite3DbFree(db, zLeft); | 
| sqlite3DbFree(db, zRight); | 
|  |