]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the SQLITE_DBCONFIG_ENABLE_QPSG option to activate the query planner
authordrh <drh@noemail.net>
Mon, 26 Jun 2017 13:57:49 +0000 (13:57 +0000)
committerdrh <drh@noemail.net>
Mon, 26 Jun 2017 13:57:49 +0000 (13:57 +0000)
stability guarantee.  This involves refactoring the sqlite3.flags bitvector
to carve out a free bit to use.

FossilOrigin-Name: 7076e8283ebae1b45a5d85d9538b49b6da399d38c3c6935de100f948f814f6a9

15 files changed:
manifest
manifest.uuid
src/btree.c
src/main.c
src/pragma.h
src/prepare.c
src/sqlite.h.in
src/sqliteInt.h
src/test1.c
src/vdbe.c
src/vdbeaux.c
src/vdbemem.c
test/analyze3.test
test/like.test
tool/mkpragmatab.tcl

index 915d31b911287ac77094716d384b15fd5cf874d3..dc3b1665b6712378b87b860f3d99a323d92b587b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Disable\sshell\stests\sfor\sthe\s.schema\scommand\sif\svirtual\stables\sare\snot\savailable.
-D 2017-06-24T19:21:48.519
+C Add\sthe\sSQLITE_DBCONFIG_ENABLE_QPSG\soption\sto\sactivate\sthe\squery\splanner\nstability\sguarantee.\s\sThis\sinvolves\srefactoring\sthe\ssqlite3.flags\sbitvector\nto\scarve\sout\sa\sfree\sbit\sto\suse.
+D 2017-06-26T13:57:49.311
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc
@@ -348,7 +348,7 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c
 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
-F src/btree.c 430e34151e6ef37e42d3f956bb062907c80ff91e1380704b967b8c1a02a98f64
+F src/btree.c 00579ff9c2831d6f98cc993f8f2a34c0ff996e89b3cd2f27928f75796bc3a58a
 F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca
 F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610
 F src/build.c 88a8cdc11d1c081ed565aa3e795bdf9160f4556463b4c4555e9860b59dd80340
@@ -370,7 +370,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 F src/insert.c 974499a3999d339a4c1ba8ef129a988d9f136b3789e423808b38cdc19d28adbe
 F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
 F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9
-F src/main.c 18f2145d572069dae91161add89446aec680aab296492a92ae5afcc2fc7c6b5a
+F src/main.c 747ec45346c3826113bc081cafe1aa2df945e50540c4b3fb13ec02b5e231c3db
 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -399,23 +399,23 @@ F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11
 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
 F src/pragma.c 2362670a9d28b71708aecb2b9b10b3f7be71f4c950961c07e81dc400e3ce6371
-F src/pragma.h a8a949000214fefb6210330eed8ccbbb4f752619a9871f31b3dedd4a240277fd
-F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
+F src/pragma.h 99d3df4a3d2f12c5227ad403f767334910e6356325b6d155a9a99b4037093460
+F src/prepare.c a80a740b306a5fb2f2594d68776aade4ce1920687932e7c4dc0320ebdadcbb5d
 F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c adf3ef9843135b1383321ad751f16f5a40c3f37925154555a3e61653d2a954e8
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c 35ccfae64cecfa843d54a5898c4ab7d6595ce03d147267fa5eecdc8eab39cd6a
 F src/shell.c 2026e88e7892ba177eae79936285d781f1c449f7a7b4e8d86fd02739d4ead26b
-F src/sqlite.h.in 67fa8bd29808e7988e0ce36c8d4c6043eb1727f94522fc612687aa5af51931e6
+F src/sqlite.h.in 2555ff1b79a1aadeb4eb761740351dc3027fa08120bf84511633ba75a630e7a8
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
-F src/sqliteInt.h 34a54fb47de2da1465f3d3ba1cd373db880bd5d588b0fe862a073ecacd6ddaae
+F src/sqliteInt.h 620093497e54998c6b2a01ad98aed9b561716c3db4bde0cc37c8bf2416200bed
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
 F src/tclsqlite.c 1ac29f18b1b3787a30b45dbbdf6fdc4aa4f1a2f8c7c8fe586beba1b177eba97d
-F src/test1.c c99f0442918a7a5d5b68a95d6024c211989e6c782c15ced5a558994baaf76a5e
+F src/test1.c 735f7711e787f30ad4e0001220c580ce456d9f731e22e0e5f86dd5c7e41ccd4d
 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
 F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
 F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
@@ -472,13 +472,13 @@ F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc
 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
 F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
-F src/vdbe.c 6783778df820f3e0c68289fe5d12ddd34168b0eb1acf248668fec6e2ea1012d5
+F src/vdbe.c 50f4f47bb190099b61fe87e239de17ad00636a522a271dd9b28329053091401d
 F src/vdbe.h 70a409d171d4e51b962f0d53abf15c33c404c6aa4c9d62fb3a931b5a62ba9615
 F src/vdbeInt.h cdcdabad4f5d6bf7a3beb826a7f33ee6f8f1cb220042bedd5b7d4bf2ea1d179f
 F src/vdbeapi.c c961d8d9e0f52e2df60a6ddbbccd7d99dc4d00103db7e53f77fcef44fbd23178
-F src/vdbeaux.c bc9b3228f6d99bef0d0ecaf3a0e0e8358b3873242d0d2fe944226de3fdf9521e
+F src/vdbeaux.c c03e96a20476f003a26d638da01264abc49288aa3a47d2a62aac16efe4a98ee7
 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
-F src/vdbemem.c 94b17d851f31d4fd075d47d373d4b33ed3962a6ecb82cf385018025751091360
+F src/vdbemem.c dc204ad331409d4b7116d3112b8ff665e6a2927e1ac9e5cdd2c6b27e4ed8093f
 F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
 F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
@@ -504,7 +504,7 @@ F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b
 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
 F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
-F test/analyze3.test 1dccda46a6c374018af617fba00bfe297a61d442
+F test/analyze3.test 8b3ef8ba6d1096b76c40e0925c0fe51e700d2b779cdda40914580de3f9b9d80f
 F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
 F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
 F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
@@ -928,7 +928,7 @@ F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
 F test/kvtest.c d2b8cfc91047ebf6cac4f3a04f19c3a864e4ecfd683bbb65c395df450b8dc79c
 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
-F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302
+F test/like.test e7b1e724c731a219c4338e37cfe2c5861cd1cd7a856bbdd1d6045ae4f83dc7c7
 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
 F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
@@ -1521,7 +1521,7 @@ F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66e
 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
 F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
-F tool/mkpragmatab.tcl bdd4c76449e9e0874ae7f0846868c42583e63b47a081b177a97f94e2b702b3e7
+F tool/mkpragmatab.tcl aa94395a91b5bd47022b7db0c08126f047887e0d299cc19ec1c23a9e5b136961
 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
 F tool/mksqlite3c.tcl 226da6d794d7d43a31e159a6fa89db867bf1f5eafe4b37d031222287ef8dbadc
@@ -1583,7 +1583,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c2ea62937ec8fabec72d3c7cd38d8e2cabbb5ce48638f8ce7ebefd6cd2716fd3
-R 9f5da0e29f079e233ed155fcb887700c
+P c8186874b3fec737445ad5c4ba3eaecd922af664b387d89dc31eea60476a0294
+R aa6192592198c78cf22d0f0e4a80cfa8
+T *branch * enable-QPSG
+T *sym-enable-QPSG *
+T -sym-trunk *
 U drh
-Z e393ac92ea73930e7d0783c651bf561b
+Z bed31a9a72b1edbf482f280709a5296c
index 0bae5da8dd6a6caaad62406529850798391c9faa..7edf40f7c33185b5fd46d452c6776322910d0598 100644 (file)
@@ -1 +1 @@
-c8186874b3fec737445ad5c4ba3eaecd922af664b387d89dc31eea60476a0294
\ No newline at end of file
+7076e8283ebae1b45a5d85d9538b49b6da399d38c3c6935de100f948f814f6a9
\ No newline at end of file
index 1f06e4503105a5af0d998d6c85d7d39bb3f7379d..be6c0dd1716de8b0b67a9fcc929d21f85916df7b 100644 (file)
@@ -152,7 +152,7 @@ static int hasSharedCacheTableLock(
   ** Return true immediately.
   */
   if( (pBtree->sharable==0)
-   || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted))
+   || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommit))
   ){
     return 1;
   }
@@ -229,7 +229,7 @@ static int hasReadConflicts(Btree *pBtree, Pgno iRoot){
   for(p=pBtree->pBt->pCursor; p; p=p->pNext){
     if( p->pgnoRoot==iRoot 
      && p->pBtree!=pBtree
-     && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted)
+     && 0==(p->pBtree->db->flags & SQLITE_ReadUncommit)
     ){
       return 1;
     }
@@ -251,7 +251,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
   assert( sqlite3BtreeHoldsMutex(p) );
   assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
   assert( p->db!=0 );
-  assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
+  assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 );
   
   /* If requesting a write-lock, then the Btree must have an open write
   ** transaction on this file. And, obviously, for this to be so there 
@@ -329,7 +329,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
   ** obtain a read-lock using this function. The only read-lock obtained
   ** by a connection in read-uncommitted mode is on the sqlite_master 
   ** table, and that lock is obtained in BtreeBeginTrans().  */
-  assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
+  assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK );
 
   /* This function should only be called on a sharable b-tree after it 
   ** has been determined that no other b-tree holds a conflicting lock.  */
@@ -3021,7 +3021,7 @@ static int lockBtree(BtShared *pBt){
                                    pageSize-usableSize);
       return rc;
     }
-    if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){
+    if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
       rc = SQLITE_CORRUPT_BKPT;
       goto page1_init_failed;
     }
index 6a48f93d173336044a9d0b9fbf7b75d9c619e973..f1194266615d63fd48c37a5355ca3eee30bf1609 100644 (file)
@@ -811,6 +811,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
         { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
         { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
         { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
+        { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
       };
       unsigned int i;
       rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -2915,6 +2916,9 @@ static int openDatabase(
 #endif
 #if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
                  | SQLITE_Fts3Tokenizer
+#endif
+#if defined(SQLITE_ENABLE_QPSG)
+                 | SQLITE_EnableQPSG
 #endif
       ;
   sqlite3HashInit(&db->aCollSeq);
index bf0f648f07cce3e2279c6f9d94d2bce8620b5f18..76e59cbc6bb7a8bf4957774500feabb0f6c51d13 100644 (file)
@@ -458,7 +458,7 @@ static const PragmaName aPragmaName[] = {
   /* ePragTyp:  */ PragTyp_FLAG,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ SQLITE_ReadUncommitted },
+  /* iArg:      */ SQLITE_ReadUncommit },
  {/* zName:     */ "recursive_triggers",
   /* ePragTyp:  */ PragTyp_FLAG,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -610,7 +610,7 @@ static const PragmaName aPragmaName[] = {
   /* ePragTyp:  */ PragTyp_FLAG,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
+  /* iArg:      */ SQLITE_WriteSchema },
 #endif
 };
 /* Number of pragmas: 60 on by default, 74 total. */
index 74127bc76b424e558709e100765c1a26cedbd6ef..395b9e40457c9fd92a22642ef87f5f299e994e2f 100644 (file)
@@ -25,7 +25,7 @@ static void corruptSchema(
   const char *zExtra   /* Error information */
 ){
   sqlite3 *db = pData->db;
-  if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
+  if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){
     char *z;
     if( zObj==0 ) zObj = "?";
     z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
@@ -312,8 +312,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
     rc = SQLITE_NOMEM_BKPT;
     sqlite3ResetAllSchemasOfConnection(db);
   }
-  if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
-    /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
+  if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
+    /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
     ** the schema loaded, even if errors occurred. In this situation the 
     ** current sqlite3_prepare() operation will fail, but the following one
     ** will attempt to compile the supplied statement against whatever subset
@@ -561,7 +561,7 @@ static int sqlite3Prepare(
       if( rc ){
         const char *zDb = db->aDb[i].zDbSName;
         sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
-        testcase( db->flags & SQLITE_ReadUncommitted );
+        testcase( db->flags & SQLITE_ReadUncommit );
         goto end_prepare;
       }
     }
index 1e4389215d181d886d2f36a5d08fc53408e10843..2f72f83f5db7634d94c7eed6c9f0f1aaf995de08 100644 (file)
@@ -2007,6 +2007,17 @@ struct sqlite3_mem_methods {
 ** have been disabled - 0 if they are not disabled, 1 if they are.
 ** </dd>
 **
+** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
+** <dd>The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
+** a single SQL query statement will always use the same algorithm regardless
+** of values of [bound parameters].  The QPSG disables some query optimizations
+** that look at the values of bound parameters, which can make some queries
+** slower.  But the QPSG has the advantage of more predictable behavior.  With
+** the QPSG active, SQLite will always use the same query plan in the field as
+** was used during testing in the lab.
+** </dd>
+**
 ** </dl>
 */
 #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
@@ -2016,6 +2027,7 @@ struct sqlite3_mem_methods {
 #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
 #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
 #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
+#define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
 
 
 /*
index ee83a511f28d3c166832116ead144194ff8ea760..cc51197d651cb9ec308f45680e49031ea6092984 100644 (file)
@@ -1450,8 +1450,8 @@ struct sqlite3 {
 **      SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
 **      SQLITE_CacheSpill    == PAGER_CACHE_SPILL
 */
-#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
-#define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */
+#define SQLITE_WriteSchema    0x00000001  /* OK to update SQLITE_MASTER */
+#define SQLITE_LegacyFileFmt  0x00000002  /* Create new databases in format 1 */
 #define SQLITE_FullColNames   0x00000004  /* Show full column names on SELECT */
 #define SQLITE_FullFSync      0x00000008  /* Use full fsync on the backend */
 #define SQLITE_CkptFullFSync  0x00000010  /* Use full fsync for checkpoint */
@@ -1462,29 +1462,34 @@ struct sqlite3 {
                                           /*   the count using a callback. */
 #define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                           /*   result set is empty */
-#define SQLITE_SqlTrace       0x00000200  /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
-#define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
-#define SQLITE_VdbeAddopTrace 0x00001000  /* Trace sqlite3VdbeAddOp() calls */
-#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
-#define SQLITE_ReadUncommitted 0x0004000  /* For shared-cache mode */
-#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
-#define SQLITE_RecoveryMode   0x00010000  /* Ignore schema errors */
-#define SQLITE_ReverseOrder   0x00020000  /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers    0x00040000  /* Enable recursive triggers */
-#define SQLITE_ForeignKeys    0x00080000  /* Enforce foreign key constraints  */
-#define SQLITE_AutoIndex      0x00100000  /* Enable automatic indexes */
-#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
-#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
-#define SQLITE_LoadExtFunc    0x00800000  /* Enable load_extension() SQL func */
-#define SQLITE_EnableTrigger  0x01000000  /* True to enable triggers */
-#define SQLITE_DeferFKs       0x02000000  /* Defer all FK constraints */
-#define SQLITE_QueryOnly      0x04000000  /* Disable database changes */
-#define SQLITE_VdbeEQP        0x08000000  /* Debug EXPLAIN QUERY PLAN */
-#define SQLITE_Vacuum         0x10000000  /* Currently in a VACUUM */
-#define SQLITE_CellSizeCk     0x20000000  /* Check btree cell sizes on load */
-#define SQLITE_Fts3Tokenizer  0x40000000  /* Enable fts3_tokenizer(2) */
-#define SQLITE_NoCkptOnClose  0x80000000  /* No checkpoint on close()/DETACH */
+#define SQLITE_IgnoreChecks   0x00000200  /* Do not enforce check constraints */
+#define SQLITE_ReadUncommit   0x00000400  /* READ UNCOMMITTED in shared-cache */
+#define SQLITE_NoCkptOnClose  0x00000800  /* No checkpoint on close()/DETACH */
+#define SQLITE_ReverseOrder   0x00001000  /* Reverse unordered SELECTs */
+#define SQLITE_RecTriggers    0x00002000  /* Enable recursive triggers */
+#define SQLITE_ForeignKeys    0x00004000  /* Enforce foreign key constraints  */
+#define SQLITE_AutoIndex      0x00008000  /* Enable automatic indexes */
+#define SQLITE_LoadExtension  0x00010000  /* Enable load_extension */
+#define SQLITE_EnableTrigger  0x00020000  /* True to enable triggers */
+#define SQLITE_DeferFKs       0x00040000  /* Defer all FK constraints */
+#define SQLITE_QueryOnly      0x00080000  /* Disable database changes */
+#define SQLITE_CellSizeCk     0x00100000  /* Check btree cell sizes on load */
+#define SQLITE_Fts3Tokenizer  0x00200000  /* Enable fts3_tokenizer(2) */
+#define SQLITE_EnableQPSG     0x00400000  /* Query Planner Stability Guarantee */
+/* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and
+** could be factored out into a separate bit vector of the sqlite3 object. */
+#define SQLITE_InternChanges  0x00800000  /* Uncommitted Hash table changes */
+#define SQLITE_LoadExtFunc    0x01000000  /* Enable load_extension() SQL func */
+#define SQLITE_PreferBuiltin  0x02000000  /* Preference to built-in funcs */
+#define SQLITE_Vacuum         0x04000000  /* Currently in a VACUUM */
+/* Flags used only if debugging */
+#ifdef SQLITE_DEBUG
+#define SQLITE_SqlTrace       0x08000000  /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing    0x10000000  /* Debug listings of VDBE programs */
+#define SQLITE_VdbeTrace      0x20000000  /* True to trace VDBE execution */
+#define SQLITE_VdbeAddopTrace 0x40000000  /* Trace sqlite3VdbeAddOp() calls */
+#define SQLITE_VdbeEQP        0x80000000  /* Debug EXPLAIN QUERY PLAN */
+#endif
 
 
 /*
index 87b255c9e9d92e9414cfd840d394393f9a8cd36a..eaafd87755f95415844b8608d6a33ba528df2888 100644 (file)
@@ -7317,6 +7317,7 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
     { "FTS3_TOKENIZER",  SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
     { "LOAD_EXTENSION",  SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
     { "NO_CKPT_ON_CLOSE",SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
+    { "QPSG",            SQLITE_DBCONFIG_ENABLE_QPSG },
   };
   int i;
   int v;
index 4a412b4e5014ab9a77349740f0bb18aaf91e524a..ecdd92be9cf9186ad58b44a719810aa95dc12bb4 100644 (file)
@@ -6571,7 +6571,7 @@ case OP_Expire: {
 */
 case OP_TableLock: {
   u8 isWriteLock = (u8)pOp->p3;
-  if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
+  if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){
     int p1 = pOp->p1; 
     assert( p1>=0 && p1<db->nDb );
     assert( DbMaskTest(p->btreeMask, p1) );
index 5dfbe4f5bd9ebfaced301922e799bbb8af0bafca..846bf7c8d28ded17eb5c818bc7013fe136003b93 100644 (file)
@@ -4540,7 +4540,7 @@ sqlite3 *sqlite3VdbeDb(Vdbe *v){
 */
 sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
   assert( iVar>0 );
-  if( v ){
+  if( v && (v->db->flags & SQLITE_EnableQPSG)==0 ){
     Mem *pMem = &v->aVar[iVar-1];
     if( 0==(pMem->flags & MEM_Null) ){
       sqlite3_value *pRet = sqlite3ValueNew(v->db);
index 88c57f1abadbc34695edc3edf326b44c0ac89f52..dc24f446845a031d583a8cb95148429d6f8f0556 100644 (file)
@@ -1493,13 +1493,11 @@ static int stat4ValueFromExpr(
     Vdbe *v;
     int iBindVar = pExpr->iColumn;
     sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
-    if( (v = pParse->pReprepare)!=0 ){
+    if( (v = pParse->pReprepare)!=0 && (db->flags & SQLITE_EnableQPSG)==0 ){
       pVal = valueNew(db, pAlloc);
       if( pVal ){
         rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
-        if( rc==SQLITE_OK ){
-          sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
-        }
+        sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
         pVal->db = pParse->db;
       }
     }
index 2fb558d16a285708f13185c21bc27aff19930546..3e721a087713e0c0223e61e5ea97d2dbc57f73b1 100644 (file)
@@ -123,6 +123,36 @@ do_eqp_test analyze3-1.1.3 {
   SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 
 } {0 0 0 {SCAN TABLE t1}}
 
+# 2017-06-26:  Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables
+# the use of bound parameters by STAT4
+#
+db cache flush
+unset -nocomplain l
+unset -nocomplain u
+do_eqp_test analyze3-1.1.3.100 {
+  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
+} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
+set l 200
+set u 300
+do_eqp_test analyze3-1.1.3.101 {
+  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
+} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
+set l 0
+set u 1100
+do_eqp_test analyze3-1.1.3.102 {
+  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
+} {0 0 0 {SCAN TABLE t1}}
+db cache flush
+sqlite3_db_config db ENABLE_QPSG 1
+do_eqp_test analyze3-1.1.3.103 {
+  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
+} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
+db cache flush
+sqlite3_db_config db ENABLE_QPSG 0
+do_eqp_test analyze3-1.1.3.104 {
+  SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
+} {0 0 0 {SCAN TABLE t1}}
+
 do_test analyze3-1.1.4 {
   sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
 } {199 0 14850}
index 8082b351237083b90f509e527086ffdd4eef94be..e07b4e0603ec452f5e77845bb28446f52d6fda4f 100644 (file)
@@ -160,6 +160,7 @@ ifcapable !like_opt {
 #
 proc queryplan {sql} {
   set ::sqlite_sort_count 0
+  db cache flush
   set data [execsql $sql]
   if {$::sqlite_sort_count} {set x sort} {set x nosort}
   lappend data $x
@@ -196,7 +197,7 @@ do_test like-3.2 {
 
 # With an index on t1.x and case sensitivity on, optimize completely.
 #
-do_test like-3.3 {
+do_test like-3.3.100 {
   set sqlite_like_count 0
   execsql {
     PRAGMA case_sensitive_like=on;
@@ -206,9 +207,50 @@ do_test like-3.3 {
     SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
   }
 } {abc abcd nosort {} i1}
-do_test like-3.4 {
+do_test like-3.3.101 {
+  set sqlite_like_count
+} 0
+
+# The like optimization works even when the pattern is a bound parameter
+#
+do_test like-3.3.102 {
+  set sqlite_like_count 0
+  unset -nocomplain ::likepat
+  set ::likepat abc%
+  queryplan {
+    SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
+  }
+} {abc abcd nosort {} i1}
+do_test like-3.3.103 {
+  set sqlite_like_count
+} 0
+
+# Except, the like optimization does not work for bound parameters if
+# the query planner stability guarantee is active.
+#
+do_test like-3.3.104 {
+  set sqlite_like_count 0
+  sqlite3_db_config db QPSG 1
+  queryplan {
+    SELECT x FROM t1 WHERE x LIKE $::likepat ORDER BY 1;
+  }
+} {abc abcd nosort {} i1}
+do_test like-3.3.105 {
+  set sqlite_like_count
+} 12
+
+# The query planner stability guarantee does not disrupt explicit patterns
+#
+do_test like-3.3.105 {
+  set sqlite_like_count 0
+  queryplan {
+    SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
+  }
+} {abc abcd nosort {} i1}
+do_test like-3.3.106 {
   set sqlite_like_count
 } 0
+sqlite3_db_config db QPSG 0
 
 # The LIKE optimization still works when the RHS is a string with no
 # wildcard.  Ticket [e090183531fc2747]
index 8eb8250535ee095edc5efc97d083e7224a822cd0..c7001dc33997ff853f2fc025d6dbc3e78f9ff87a 100644 (file)
@@ -120,12 +120,12 @@ set pragma_def {
 
   NAME: writable_schema
   TYPE: FLAG
-  ARG:  SQLITE_WriteSchema|SQLITE_RecoveryMode
+  ARG:  SQLITE_WriteSchema
   IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 
   NAME: read_uncommitted
   TYPE: FLAG
-  ARG:  SQLITE_ReadUncommitted
+  ARG:  SQLITE_ReadUncommit
   IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 
   NAME: recursive_triggers