]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Where possible, avoid loading all schemas into memory for PRAGMA statements.
authordan <dan@noemail.net>
Mon, 25 Feb 2019 17:54:23 +0000 (17:54 +0000)
committerdan <dan@noemail.net>
Mon, 25 Feb 2019 17:54:23 +0000 (17:54 +0000)
FossilOrigin-Name: 64f97530ad387655767b5205fb9a9c723210cd4975176ab6fb71bca0cb585a74

manifest
manifest.uuid
src/build.c
src/callback.c
src/pragma.c
src/pragma.h
test/reuse4.test
tool/mkpragmatab.tcl

index 480a38c5b0f422da2ee5ce2bc084e82c84ef8eb9..b98349d699c1436c3daa62de9a080d3215d0114f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\slatest\strunk\schanges\sinto\sthis\sbranch.
-D 2019-02-22T17:44:58.708
+C Where\spossible,\savoid\sloading\sall\sschemas\sinto\smemory\sfor\sPRAGMA\sstatements.
+D 2019-02-25T17:54:23.054
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 56456706c4da271309914c756c9c8ea537685f1c79f8785afa72f968d6810482
@@ -460,8 +460,8 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c 026f48c39b179a5602423904fcaaae87bbd75f659fd672b3756fea43356d9909
 F src/btree.h 63b94fb38ce571c15eb6a3661815561b501d23d5948b2d1e951fbd7a2d04e8d3
 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
-F src/build.c 7971c75fc7e31d9a0e1caea7b1b5534326a10dda23837ae1848ee72a99ddb691
-F src/callback.c f8b769a9344624b8df474480762ea7d2e7e925fe754f7eca53457b6ed88a1116
+F src/build.c 5db330027edad02d2b95d9dc7e3c3a49da275ef18892244fe2bb0097cbbee286
+F src/callback.c 0d68a032872495351f70d533610a94388a4f191cce37ec7663d6598eaa8a4a21
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
 F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
@@ -509,8 +509,8 @@ F src/parse.y 741a270b7f2f85bc5d026d06fb5a9ccba5335304ff2831e1cb44b36cd0da6006
 F src/pcache.c 696a01f1a6370c1b50a09c15972bc3bee3333f8fcd1f2da8e9a76b1b062c59ee
 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c a72804486dfa8e4b6bc30d666c97ecf1155f91a4351fc6e48ea4097e4eb304fb
-F src/pragma.c af67dedaad8bafe9a5f9adcec32a0da6dd118617dd8220ad1d118f5a6bf83a02
-F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177
+F src/pragma.c bbe1ba394629ae81c332d76a2c454635fcc76608cea02c7ad24a647ee16398d4
+F src/pragma.h 9d7658a7be442c1149409aab8ebdde012f387de66fca20056fc9e0791e40dbda
 F src/prepare.c 48cea94dcae45d83ab1a3db75c23c8b4d610a4c1199542242e7bd110047dc961
 F src/printf.c 93a3d539019264683a444bc043c875e9a6cca43fe935ae7bf6cfff0af3bba118
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
@@ -1231,7 +1231,7 @@ F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
 F test/reuse1.test 31c312375ccfcc5c2abc1fca5e4a89d6309c57ea6b1fa3179a5eee68016f9c74
 F test/reuse2.test 04d88621f0c51a8b3bf5512b9e61a5d7a61059e33097a1a6b1c6f6cf2d1f2a35
 F test/reuse3.test 75071034556d4915066adc249bfac364c6ed0fc62c997c4b02410fdacd3bfb9d
-F test/reuse4.test 1aef94898fd51bc87750d81074185a4f57cccd0bf87b9f98ae58b9c799452d42
+F test/reuse4.test 5a5aa075db13fb09299b68b43040f9e205c3ad8f84a0f083030dc8df32a7cac8
 F test/reusefault.test 5d60bfbcaccfaffa02132f2137d849dc4b3802da8a929054e23f483bf5dc06e4
 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
 F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6
@@ -1745,7 +1745,7 @@ F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6
 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
 F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
-F tool/mkpragmatab.tcl 49039adedafbc430d2959400da2e0e8f20ef8dcf6898e447c946e7d50ef5906b
+F tool/mkpragmatab.tcl a3ca473c1ddf1fd6b95e2670907b7856c26c52091a5daa78e88b21a471c39e48
 F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5
 F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@@ -1812,7 +1812,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ba0ab042f401a9d3b81dc546573214bbe2ad712c932aafcf0c045f189bbf09ca 73056b314bd63288c662752e9bd469b70264c38031c1c857460e64fdb1ed4e2e
-R 946ba507a3cdc55ed2626c60efd4cb5c
+P 001771afd0567c04736a778fc78fd7144492ae7c830e7f55de61869ce988f0ed
+R e2cbde6afbe543379cd9c4b379401b87
 U dan
-Z 5e4a7a781579fd8bc4e7e2fd55764d3a
+Z 60c071924920896d623a07a27d1e6e34
index fe5b588fa1b872c3790bc5fea1967bef6c9d81e7..4f6b971bd35ec52f0c37474e0825d43cc87c3b1c 100644 (file)
@@ -1 +1 @@
-001771afd0567c04736a778fc78fd7144492ae7c830e7f55de61869ce988f0ed
\ No newline at end of file
+64f97530ad387655767b5205fb9a9c723210cd4975176ab6fb71bca0cb585a74
\ No newline at end of file
index f5027394d8b9b3514651e73eb41f9e9d44a77dbb..08617532b6b472819260531d96623a6c6ff70560 100644 (file)
@@ -308,7 +308,7 @@ int sqlite3SchemaLoad(sqlite3 *db, int iDb, int *pbUnload, char **pzErr){
     memset(&db->init, 0, sizeof(struct sqlite3InitInfo));
     rc = sqlite3InitOne(db, iDb, pzErr, 0);
     db->init = sv;
-    *pbUnload = (rc==SQLITE_OK && (iDb!=1));
+    if( pbUnload ) *pbUnload = (rc==SQLITE_OK && (iDb!=1));
   }
   return rc;
 }
index c3abfb1dce94a5ac5237db63e16f58ff97dd1715..cb5cb5f24f3752bfb5d9080570f2bf8c9af87b83 100644 (file)
@@ -794,7 +794,7 @@ void sqlite3SchemaReleaseAll(sqlite3 *db){
       }
     }
   }
-  db->flags &= ~DBFLAG_FreeSchema;
+  db->mDbFlags &= ~DBFLAG_FreeSchema;
   sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
 }
 
index 1dcd21400cb02348efd2527f73d641c95c120700..8bd8d18fa197e2a76e6e274285d09753e66daea3 100644 (file)
@@ -420,7 +420,13 @@ void sqlite3Pragma(
 
   /* Make sure the database schema is loaded if the pragma requires that */
   if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
-    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+    if( IsReuseSchema(db) && (zDb || (pPragma->mPragFlg & PragFlg_OneSchema)) ){
+      assert( iDb>=0 && iDb<db->nDb );
+      pParse->rc = sqlite3SchemaLoad(db, iDb, 0, &pParse->zErrMsg);
+      if( pParse->rc ) goto pragma_out;
+    }else{
+      if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+    }
   }
 
   /* Register the result column names for pragmas that return results */
@@ -1802,9 +1808,10 @@ void sqlite3Pragma(
   ** applications for any purpose.
   */
   case PragTyp_HEADER_VALUE: {
-    int iCookie = pPragma->iArg;  /* Which cookie to read or write */
+    int iCookie;                  /* Which cookie to read or write */
+    iCookie = pPragma->iArg & PRAGMA_HEADER_VALUE_MASK;     
     sqlite3VdbeUsesBtree(v, iDb);
-    if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
+    if( zRight && (pPragma->iArg & PRAGMA_HEADER_VALUE_READONLY)==0 ){
       /* Write the specified cookie value */
       static const VdbeOpList setCookie[] = {
         { OP_Transaction,    0,  1,  0},    /* 0 */
index c156e3a4fb06d33385fb4ac88749071015f9715c..7046d424b88dff8a86a3a270d40a7136200bae9c 100644 (file)
 #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
 #define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
 #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
-#define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
+#define PragFlg_OneSchema  0x08 /* Only a single schema required */
 #define PragFlg_Result0    0x10 /* Acts as query when no argument */
 #define PragFlg_Result1    0x20 /* Acts as query when has one argument */
 #define PragFlg_SchemaOpt  0x40 /* Schema restricts name search if present */
 #define PragFlg_SchemaReq  0x80 /* Schema required - "main" is default */
 
+/* For PragTyp_HEADER_VALUE pragmas the Pragma.iArg value is set
+** to the index of the header field to access (always 10 or less).
+** Ored with HEADER_VALUE_READONLY if the field is read only. */
+#define PRAGMA_HEADER_VALUE_READONLY 0x0100
+#define PRAGMA_HEADER_VALUE_MASK 0x00FF
+
+
 /* Names of columns for pragmas that return multi-column result
 ** or that return single-column results where the name of the
 ** result column is different from the name of the pragma
@@ -146,7 +153,7 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_AUTOVACUUM)
  {/* zName:     */ "auto_vacuum",
   /* ePragTyp:  */ PragTyp_AUTO_VACUUM,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
@@ -167,7 +174,7 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  {/* zName:     */ "cache_size",
   /* ePragTyp:  */ PragTyp_CACHE_SIZE,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
@@ -226,21 +233,21 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
  {/* zName:     */ "data_version",
   /* ePragTyp:  */ PragTyp_HEADER_VALUE,
-  /* ePragFlg:  */ PragFlg_ReadOnly|PragFlg_Result0,
+  /* ePragFlg:  */ PragFlg_Result0,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ BTREE_DATA_VERSION },
+  /* iArg:      */ BTREE_DATA_VERSION|PRAGMA_HEADER_VALUE_READONLY },
 #endif
 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  {/* zName:     */ "database_list",
   /* ePragTyp:  */ PragTyp_DATABASE_LIST,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_OneSchema,
   /* ColNames:  */ 35, 3,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
  {/* zName:     */ "default_cache_size",
   /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
   /* ColNames:  */ 45, 1,
   /* iArg:      */ 0 },
 #endif
@@ -270,14 +277,14 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
  {/* zName:     */ "foreign_key_check",
   /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_OneSchema,
   /* ColNames:  */ 31, 4,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_FOREIGN_KEY)
  {/* zName:     */ "foreign_key_list",
   /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt|PragFlg_OneSchema,
   /* ColNames:  */ 0, 8,
   /* iArg:      */ 0 },
 #endif
@@ -293,9 +300,9 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
  {/* zName:     */ "freelist_count",
   /* ePragTyp:  */ PragTyp_HEADER_VALUE,
-  /* ePragFlg:  */ PragFlg_ReadOnly|PragFlg_Result0,
+  /* ePragFlg:  */ PragFlg_Result0,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ BTREE_FREE_PAGE_COUNT },
+  /* iArg:      */ BTREE_FREE_PAGE_COUNT|PRAGMA_HEADER_VALUE_READONLY },
 #endif
 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  {/* zName:     */ "full_column_names",
@@ -342,7 +349,7 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_AUTOVACUUM)
  {/* zName:     */ "incremental_vacuum",
   /* ePragTyp:  */ PragTyp_INCREMENTAL_VACUUM,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_NoColumns,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_NoColumns|PragFlg_OneSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
@@ -373,7 +380,7 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  {/* zName:     */ "journal_mode",
   /* ePragTyp:  */ PragTyp_JOURNAL_MODE,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
  {/* zName:     */ "journal_size_limit",
@@ -423,7 +430,7 @@ static const PragmaName aPragmaName[] = {
   /* iArg:      */ 0 },
  {/* zName:     */ "max_page_count",
   /* ePragTyp:  */ PragTyp_PAGE_COUNT,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
  {/* zName:     */ "mmap_size",
@@ -451,7 +458,7 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  {/* zName:     */ "page_count",
   /* ePragTyp:  */ PragTyp_PAGE_COUNT,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
  {/* zName:     */ "page_size",
@@ -559,14 +566,14 @@ static const PragmaName aPragmaName[] = {
 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
  {/* zName:     */ "stats",
   /* ePragTyp:  */ PragTyp_STATS,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
   /* ColNames:  */ 21, 5,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  {/* zName:     */ "synchronous",
   /* ePragTyp:  */ PragTyp_SYNCHRONOUS,
-  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
@@ -655,7 +662,7 @@ static const PragmaName aPragmaName[] = {
   /* iArg:      */ 0 },
  {/* zName:     */ "wal_checkpoint",
   /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
-  /* ePragFlg:  */ PragFlg_NeedSchema,
+  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_OneSchema,
   /* ColNames:  */ 38, 3,
   /* iArg:      */ 0 },
 #endif
index 383f7c0797d3bf331d21d6dd9022ad8a9dfcb45e..0f32d56592456a010f7226a685a3745daa3c60b9 100644 (file)
@@ -115,5 +115,54 @@ foreach {tn sharedschema} {
   }
 }
 
+#-------------------------------------------------------------------------
+# Test some PRAGMA statements with shared-schema connections.
+#
+reset_db
+do_execsql_test 2.0 {
+  CREATE TABLE t1(a, b, c);
+  CREATE INDEX t1abc ON t1(a, b, c);
+}
+
+foreach {tn pragma nSchema nDelete} {
+  1 "PRAGMA synchronous = OFF"     1 0
+  2 "PRAGMA cache_size = 200"      1 0
+  3 "PRAGMA aux2.integrity_check"  1 0
+  4 "PRAGMA      integrity_check"  1 5
+  5 "PRAGMA index_info=t1abc"      1 5
+  6 "PRAGMA aux3.index_info=t1abc" 1 0
+  7 "PRAGMA journal_mode"          1 0
+  8 "PRAGMA aux2.wal_checkpoint"   1 0
+  9 "PRAGMA wal_checkpoint"        1 0
+} {
+  do_test 2.$tn.1 {
+    catch { db close }
+    catch { db2 close }
+    for {set i 1} {$i < 6} {incr i} {
+      forcedelete "test.db$i" "test.db${i}-wal" "test.db${i}-journal"
+      forcecopy test.db test.db$i
+    }
+    sqlite3 db2 test.db -shared-schema 1
+    for {set i 1} {$i < 6} {incr i} {
+      execsql "ATTACH 'test.db$i' AS aux$i" db2
+    }
+  } {}
+
+  sqlite3 db test.db
+  register_schemapool_module db
+
+  do_test 2.$tn.2 {
+    execsql $pragma db2
+    execsql { SELECT 'nschema='||nschema, 'ndelete='||nDelete FROM schemapool }
+  } "nschema=$nSchema ndelete=$nDelete"
+
+  do_test 2.$tn.3 {
+    execsql {
+      SELECT * FROM main.t1,aux1.t1,aux2.t1,aux3.t1,aux4.t1,aux5.t1
+    } db2
+    execsql { SELECT 'nschema=' || nschema, 'nref=' || nref FROM schemapool }
+  } "nschema=6 nref=6"
+}
+
 finish_test
 
index b236bdd5d564fe24c2f51dd1848d5637fc16c861..7aa562f69b79af51f2a4181c3dc14413a442ac28 100644 (file)
@@ -12,7 +12,7 @@
 
 # Flag meanings:
 set flagMeaning(NeedSchema) {Force schema load before running}
-set flagMeaning(ReadOnly)   {Read-only HEADER_VALUE}
+set flagMeaning(OneSchema)  {Only a single schema required}
 set flagMeaning(Result0)    {Acts as query when no argument}
 set flagMeaning(Result1)    {Acts as query when has one argument}
 set flagMeaning(SchemaReq)  {Schema required - "main" is default}
@@ -150,7 +150,7 @@ set pragma_def {
   ARG:  SQLITE_CellSizeCk
 
   NAME: default_cache_size
-  FLAG: NeedSchema Result0 SchemaReq NoColumns1
+  FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
   COLS: cache_size
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
 
@@ -163,12 +163,12 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: page_count
-  FLAG: NeedSchema Result0 SchemaReq
+  FLAG: NeedSchema Result0 SchemaReq OneSchema
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: max_page_count
   TYPE: PAGE_COUNT
-  FLAG: NeedSchema Result0 SchemaReq
+  FLAG: NeedSchema Result0 SchemaReq OneSchema
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: locking_mode
@@ -176,7 +176,7 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: journal_mode
-  FLAG: NeedSchema Result0 SchemaReq
+  FLAG: NeedSchema Result0 SchemaReq OneSchema
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: journal_size_limit
@@ -184,18 +184,18 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: cache_size
-  FLAG: NeedSchema Result0 SchemaReq NoColumns1
+  FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: mmap_size
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: auto_vacuum
-  FLAG: NeedSchema Result0 SchemaReq NoColumns1
+  FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
   IF:   !defined(SQLITE_OMIT_AUTOVACUUM)
 
   NAME: incremental_vacuum
-  FLAG: NeedSchema NoColumns
+  FLAG: NeedSchema NoColumns OneSchema
   IF:   !defined(SQLITE_OMIT_AUTOVACUUM)
 
   NAME: temp_store
@@ -215,7 +215,7 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
 
   NAME: synchronous
-  FLAG: NeedSchema Result0 SchemaReq NoColumns1
+  FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
   IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 
   NAME: table_info
@@ -232,7 +232,7 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 
   NAME: stats
-  FLAG: NeedSchema Result0 SchemaReq
+  FLAG: NeedSchema Result0 SchemaReq OneSchema
   COLS: tbl idx wdth hght flgs
   IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
 
@@ -256,7 +256,7 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 
   NAME: database_list
-  FLAG: NeedSchema Result0
+  FLAG: NeedSchema Result0 OneSchema
   COLS: seq name file
   IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 
@@ -284,12 +284,12 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 
   NAME: foreign_key_list
-  FLAG: NeedSchema Result1 SchemaOpt
+  FLAG: NeedSchema Result1 SchemaOpt OneSchema
   COLS: id seq table from to on_update on_delete match
   IF:   !defined(SQLITE_OMIT_FOREIGN_KEY)
 
   NAME: foreign_key_check
-  FLAG: NeedSchema Result0
+  FLAG: NeedSchema Result0 OneSchema
   COLS: table rowid parent fkid
   IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
 
@@ -329,14 +329,14 @@ set pragma_def {
 
   NAME: data_version
   TYPE: HEADER_VALUE
-  ARG:  BTREE_DATA_VERSION
-  FLAG: ReadOnly Result0
+  ARG:  BTREE_DATA_VERSION|PRAGMA_HEADER_VALUE_READONLY
+  FLAG: Result0
   IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
 
   NAME: freelist_count
   TYPE: HEADER_VALUE
-  ARG:  BTREE_FREE_PAGE_COUNT
-  FLAG: ReadOnly Result0
+  ARG:  BTREE_FREE_PAGE_COUNT|PRAGMA_HEADER_VALUE_READONLY
+  FLAG: Result0
   IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
 
   NAME: application_id
@@ -350,7 +350,7 @@ set pragma_def {
   IF:   !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
 
   NAME: wal_checkpoint
-  FLAG: NeedSchema
+  FLAG: NeedSchema OneSchema
   COLS: busy log checkpointed
   IF:   !defined(SQLITE_OMIT_WAL)
 
@@ -533,6 +533,12 @@ foreach f [lsort [array names allflags]] {
   set fv [expr {$fv*2}]
 }
 
+puts $fd "\n/* For PragTyp_HEADER_VALUE pragmas the Pragma.iArg value is set"
+puts $fd "** to the index of the header field to access (always 10 or less)."
+puts $fd "** Ored with HEADER_VALUE_READONLY if the field is read only. */"
+puts $fd "#define PRAGMA_HEADER_VALUE_READONLY 0x0100"
+puts $fd "#define PRAGMA_HEADER_VALUE_MASK 0x00FF\n"
+
 # Sort the column lists so that longer column lists occur first
 #
 proc colscmp {a b} {