]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Initial code for a proposed new sqlite3_stmt_mode() API.
authordrh <drh@noemail.net>
Thu, 19 Mar 2020 21:17:11 +0000 (21:17 +0000)
committerdrh <drh@noemail.net>
Thu, 19 Mar 2020 21:17:11 +0000 (21:17 +0000)
This is an incomplete snapshot of a work-in-progress.

FossilOrigin-Name: 3cf7537b5e14e218218b18b3c0c668c950a71fcddc68a5faf0f197519718a6c2

12 files changed:
manifest
manifest.uuid
src/parse.y
src/resolve.c
src/select.c
src/sqlite.h.in
src/test1.c
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbeaux.c
src/wherecode.c

index 145549d62a8df849b30218411a463959bcbade76..67aab6cc0c511782c5c6682d2db7ab9df5f1ffad 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Chagnes\sthe\sESCAPE\sclause\son\sthe\sLIKE\soperator\sto\soverwrite\swildcard\ncharacters,\sin\sorder\sot\smatch\sthe\sbehavior\sof\sPosgreSQL.
-D 2020-03-19T18:13:29.000
+C Initial\scode\sfor\sa\sproposed\snew\ssqlite3_stmt_mode()\sAPI.\nThis\sis\san\sincomplete\ssnapshot\sof\sa\swork-in-progress.
+D 2020-03-19T21:17:11.830
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -520,7 +520,7 @@ F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c a71ffd145f55e28cbdc1bdabb5e6bef063da428a6c0de3c3a36e9a0c41d4c8c0
 F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3
-F src/parse.y 8575183809cf30f8c9d1fbea65ca34d1de78b659792bc7c42681e01fc596b520
+F src/parse.y a6d7151326370346817560153c44dc73860c43e775fe43789981336910914dd2
 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
@@ -529,11 +529,11 @@ F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5
 F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28
 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf
+F src/resolve.c ad43b2ed4bea58abca3092993382aa2ac91b89144d2066faae4ac924b39396f9
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 49d46acea0e69311aa891e18253973d63e81da2a9c135924bc827856d33872ad
+F src/select.c 128d9d6996eca5e0db686495559b6588f197ef1b6643fa8ec4914861226ff021
 F src/shell.c.in f76590931c0cbbfef347f44f81ade6b335f80c46bc6e59b8b6114383a8df30e0
-F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
+F src/sqlite.h.in 416ef92b6b08bfb9a31de8001eb5d44243ecda036224421623cc8e5fdfdf1528
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
 F src/sqliteInt.h 5f74c1c52b152259ee07f241821620f11736e4f590936cfaf1cbbff9a2f563d3
@@ -541,7 +541,7 @@ F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454
 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
 F src/tclsqlite.c d0aa320416efe88c4dbb0156ed6c494f2f9958871a940e46984ee57b3e7fcc50
-F src/test1.c 5e8b8cc54e8c88906ea8a084387aa79bad245e539f4cee73149e5c0527e1db16
+F src/test1.c 93cc6cb90fd708c1822ab74543fd586e4d3510236db24ddcc5ef046f74a4b19c
 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
@@ -603,11 +603,11 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
 F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
 F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a
 F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9
-F src/vdbe.c c1c123c6248fa88940b932a00bcc75056921b6d046d45a82566cb97415d2299c
+F src/vdbe.c ca986d3f9961045256c1b077a6986cd2e9cfa86909adfd0acafb761e6656b5bb
 F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9
-F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051
-F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
-F src/vdbeaux.c e8baf66528e36474f4071e3171b660a454606eb5b54459a729982c939ad7a5bb
+F src/vdbeInt.h a341e6994ffd865531089f0c94d3910acc66d25d312259c4a45f422693deab9b
+F src/vdbeapi.c e8351c4f351e492e260fb8b0f9f57575772f583fbbe97dca4c31dcadd06760d6
+F src/vdbeaux.c ce2521d1979d6e081c21766523244891149df247092202db3a0e097f4eae40f2
 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
 F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22
 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
@@ -619,7 +619,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
 F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d
 F src/where.c 9546c82056e8cdb27291f98cf1adca5d271240b399bb97b32f77fc2bea6146c9
 F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c
-F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d
+F src/wherecode.c 9e931b9d01c3c6ffa9b150f4535dacea0dd38360fa740b6f525cf27c17415ba0
 F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
 F src/window.c ba1ffb78d73c5831433681aab7ee634230ee32f14ad508efa585044662141d5a
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
@@ -1860,7 +1860,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 1d64f4a8af81fe1235fffa54884d8f842a48ff6a33d6172f0cd65bf42fe8b2a1
-R 199dfbc9c8ca72850da0099d6c1cde58
+P 11e0844f71e8f2d27ce9363fb505e02fd7795c61dae0b3886cf0d8df4484dd97
+R bfd344317fdbc4dd2c74ef078364da12
+T *branch * sqlite3_stmt_mode
+T *sym-sqlite3_stmt_mode *
+T -sym-trunk *
 U drh
-Z 2c8ae1f04515bf2ea893e9cb3af9713c
+Z 4fdf6d3f28007c100776cbe88029096e
index 6dd6aeb2a7429c06680ae5fb853cd967a90022d5..05aae7265e73f035316fcabf1251399fe1b7478b 100644 (file)
@@ -1 +1 @@
-11e0844f71e8f2d27ce9363fb505e02fd7795c61dae0b3886cf0d8df4484dd97
\ No newline at end of file
+3cf7537b5e14e218218b18b3c0c668c950a71fcddc68a5faf0f197519718a6c2
\ No newline at end of file
index c321daf19564fca62c5f5ae891bb23868232a562..0b6cf95bd41d94fba742aa80958d43171af2f35a 100644 (file)
@@ -121,8 +121,8 @@ ecmd ::= SEMI.
 ecmd ::= cmdx SEMI.
 %ifndef SQLITE_OMIT_EXPLAIN
 ecmd ::= explain cmdx SEMI.       {NEVER-REDUCE}
-explain ::= EXPLAIN.              { pParse->explain = 1; }
-explain ::= EXPLAIN QUERY PLAN.   { pParse->explain = 2; }
+explain ::= EXPLAIN.              { pParse->explain = SQLITE_STMTMODE_EXPLAIN; }
+explain ::= EXPLAIN QUERY PLAN.   { pParse->explain = SQLITE_STMTMODE_EQP; }
 %endif  SQLITE_OMIT_EXPLAIN
 cmdx ::= cmd.           { sqlite3FinishCoding(pParse); }
 
index 05ef0c06eb79870b842b6ea8443f4ee102c21304..e69405db240a6f33c0a267b9398765efebde66dc 100644 (file)
@@ -934,7 +934,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
 #endif
         else if( no_such_func && pParse->db->init.busy==0
 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
-                  && pParse->explain==0
+                  && pParse->explain==SQLITE_STMTMODE_RUN
 #endif
         ){
           sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
index 3128d482a99bc6df0d3ce4927ced3e6b4d99688c..eed610a048c4e571172b58df6afa1a2b116f1b43 100644 (file)
@@ -5505,7 +5505,7 @@ static void explainSimpleCount(
   Table *pTab,                    /* Table being queried */
   Index *pIdx                     /* Index used to optimize scan, or NULL */
 ){
-  if( pParse->explain==2 ){
+  if( pParse->explain==SQLITE_STMTMODE_EQP ){
     int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
     sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s",
         pTab->zName,
index 7b2049ae0a231d71582be7e245b57f63f85773f9..f97d4f65d07f50bb5ce1f4a3d03ce1e2c643ec5b 100644 (file)
@@ -4132,14 +4132,88 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
 ** METHOD: sqlite3_stmt
 **
-** ^The sqlite3_stmt_isexplain(S) interface returns 1 if the
-** prepared statement S is an EXPLAIN statement, or 2 if the
-** statement S is an EXPLAIN QUERY PLAN.
-** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
-** an ordinary statement or a NULL pointer.
+** ^The sqlite3_stmt_isexplain(S) interface returns [SQLITE_STMTMODE_EXPLAIN]
+** if the prepared statement S is an EXPLAIN statement, or 
+** [SQLITE_STMTMODE_EQP] if the* statement S is an [EXPLAIN QUERY PLAN].
+** ^The sqlite3_stmt_isexplain(S) interface returns [SQLITE_STMTMODE_RUN]
+** if S is an ordinary statement or a NULL pointer.
+**
+** The sqlite3_stmt_isexplain(S) call is the same thing as
+** [sqlite3_stmt_mode](S, [SQLITE_STMTMODE_QUERY]).
 */
 int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
 
+/*
+** CAPI3REF: Set Or Query The Operating Mode For A Prepared Statement
+** METHOD: sqlite3_stmt
+**
+** The sqlite3_stmt_mode(S,M) attempts to change the "mode" of
+** statement S to value M, where M is one of the 
+** [SQLITE_STMTMODE_RUN|statement mode constants].  The value
+** of the statement mode (after the change) is returned.  The mode
+** change might be disallowed, for example if the statement is currently
+** in use or for other reasons listed below.  If the mode change is
+** disallowed, then the original mode is returned.  The only way to
+** determine if mode change was effective is to compare the return value
+** against the second parameter to see if they are the same.
+**
+** The mode cannot be changed to SQLITE_STMTMODE_RUN unless the prepared
+** statement was originally compiled without either the "EXPLAIN" or 
+** "EXPLAIN QUERY PLAN" prefix.
+**
+** The mode cannot be changed to SQLITE_STMTMODE_EQP unless the
+** statement was originally compiled using the "EXPLAIN QUERY PLAN"
+** prefix.
+**
+** If M is SQLITE_STMTMODE_QUERY, then the mode is not changed but the
+** current mode is still returned.  This can be used to query the mode
+** of a statement without changing it.
+*/
+int sqlite3_stmt_mode(sqlite3_stmt*,int);
+
+/* CAPI3REF: Prepared Statement Modes
+**
+** These integer constants are used as the second parameter and the
+** return value from the [sqlite3_stmt_mode()] interface and as the
+** return value from [sqlite3_stmt_isexplain()].
+**
+** <ul>
+** <li>[[SQLITE_STMTMODE_RUN]]
+** The [SQLITE_STMTMODE_RUN] value indicates that the statement will
+** run the SQL statement as normal.  This is the default and usual
+** mode for a prepared statement.
+**
+** <li>[[SQLITE_STMTMODE_EXPLAIN]]
+** The [SQLITE_STMTMODE_EXPLAIN] value indicates that the statement will
+** output the [bytecode] used to implement the SQL statement.  This is
+** the mode that a prepared statement is initialized to if the input
+** SQL begins with the "EXPLAIN" keyword.
+**
+** <li>[[SQLITE_STMTMODE_EQP]]
+** The [SQLITE_STMTMODE_EQP] value indicates that the statement is an
+** [EXPLAIN QUERY PLAN] statement.  In order for this mode to operate
+** correctly, it is necessary to prepare the statement using the
+** "EXPLAIN QUERY PLAN" keywords.  If a statement is converted into
+** this mode after having been prepared without the "EXPLAIN QUERY PLAN"
+** prefix, then it will probably not output the query plan.
+**
+** <li>[[SQLITE_STMTMODE_TABLELIST]]
+** The [SQLITE_STMTMODE_TABLELIST] value indicates that the statement
+** will output information about all (non-transient) tables and indexes that
+** are used by the prepared statement.
+**
+** <li>[[SQLITE_STMTMODE_QUERY]]
+** The [SQLITE_STMTMODE_QUERY] value is not an actual statement mode, but
+** this value can be used as the second parameter to [sqlite3_stmt_mode()]
+** in order to determine the statement mode without changing it.
+** </ul>
+*/
+#define SQLITE_STMTMODE_RUN        0
+#define SQLITE_STMTMODE_EXPLAIN    1
+#define SQLITE_STMTMODE_EQP        2
+#define SQLITE_STMTMODE_TABLELIST  3
+#define SQLITE_STMTMODE_QUERY      (-1)
+
 /*
 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
 ** METHOD: sqlite3_stmt
index 29207d51acdd753c5d5d0393c5fc591a355f47c1..78d4f897b1b84487be60bb26282a7c2949a05971 100644 (file)
@@ -2697,9 +2697,10 @@ static int SQLITE_TCLAPI test_stmt_readonly(
 
 /*
 ** Usage:  sqlite3_stmt_isexplain  STMT
+** Usage:  sqlite3_stmt_mode STMT NEWMODE
 **
-** Return 1, 2, or 0 respectively if STMT is an EXPLAIN statement, an
-** EXPLAIN QUERY PLAN statement or an ordinary statement or NULL pointer.
+** Return integers 0, 1, 2, or 3 depending on the mode of STMT.  If the
+** 2nd argument is provided, change the mode to the integer in that argument.
 */
 static int SQLITE_TCLAPI test_stmt_isexplain(
   void * clientData,
@@ -2710,14 +2711,19 @@ static int SQLITE_TCLAPI test_stmt_isexplain(
   sqlite3_stmt *pStmt;
   int rc;
 
-  if( objc!=2 ){
+  if( objc!=2 && objc!=3 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"",
         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
     return TCL_ERROR;
   }
-
   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
-  rc = sqlite3_stmt_isexplain(pStmt);
+  if( objc==3 ){
+    int iNewMode = SQLITE_STMTMODE_QUERY;
+    if( Tcl_GetIntFromObj(interp, objv[2], &iNewMode) ) return TCL_ERROR;
+    rc = sqlite3_stmt_mode(pStmt, iNewMode);
+  }else{
+    rc = sqlite3_stmt_isexplain(pStmt);
+  }
   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
   return TCL_OK;
 }
@@ -7976,6 +7982,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_next_stmt",             test_next_stmt     ,0 },
      { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
      { "sqlite3_stmt_isexplain",        test_stmt_isexplain,0 },
+     { "sqlite3_stmt_mode",             test_stmt_isexplain,0 },
      { "sqlite3_stmt_busy",             test_stmt_busy     ,0 },
      { "uses_stmt_journal",             uses_stmt_journal ,0 },
 
index 7f053286606d76aa8b0c05df4960490d11b2498f..1eae9c62940ba303225fd180306a874c15a46e3e 100644 (file)
@@ -704,7 +704,7 @@ int sqlite3VdbeExec(
   assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
   assert( p->bIsReader || p->readOnly!=0 );
   p->iCurrentTime = 0;
-  assert( p->explain==0 );
+  assert( p->explain==SQLITE_STMTMODE_RUN );
   p->pResultSet = 0;
   db->busyHandler.nBusy = 0;
   if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
index 810283162412764f649dc165c361db3140e5eec4..1717d64a6f6ce168981b56dbbe15a31f5a7dd917 100644 (file)
@@ -420,6 +420,7 @@ struct Vdbe {
   u8 prepFlags;           /* SQLITE_PREPARE_* flags */
   bft expired:2;          /* 1: recompile VM immediately  2: when convenient */
   bft explain:2;          /* True if EXPLAIN present on SQL command */
+  bft origExplain:2;      /* The original value of explain */
   bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
   bft changeCntOn:1;      /* True to update the change-counter */
   bft runOnlyOnce:1;      /* Automatically expire on reset */
@@ -429,6 +430,7 @@ struct Vdbe {
   yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
   yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
   u32 aCounter[7];        /* Counters used by sqlite3_stmt_status() */
+  u32 nColName;           /* Number of slots allocated to aColName[] above */
   char *zSql;             /* Text of the SQL statement that generated this */
 #ifdef SQLITE_ENABLE_NORMALIZE
   char *zNormSql;         /* Normalization of the associated SQL statement */
index 074d4588154ca54dacf9057d5d995f99279ecd49..c007a7712167a626dfa3a22738aa02161ec0ea56 100644 (file)
@@ -996,8 +996,17 @@ int sqlite3_aggregate_count(sqlite3_context *p){
 ** Return the number of columns in the result set for the statement pStmt.
 */
 int sqlite3_column_count(sqlite3_stmt *pStmt){
+  static const u8 anColumn[] = {
+    0,     /* SQLITE_STMTMODE_RUN  (Use pVm->nResColumn instead) */
+    8,     /* SQLITE_STMTMODE_EXPLAIN    */
+    4,     /* SQLITE_STMTMODE_EQP        */
+    6      /* SQLITE_STMTMODE_TABLELIST  */
+  };
   Vdbe *pVm = (Vdbe *)pStmt;
-  return pVm ? pVm->nResColumn : 0;
+  if( pVm==0 ) return 0;
+  assert( pVm->explain>=0 && pVm->explain<=3 );
+  if( pVm->explain==0 ) return pVm->nResColumn;
+  return (int)anColumn[pVm->explain];
 }
 
 /*
@@ -1211,6 +1220,7 @@ static const void *columnName(
     N += useType*n;
     sqlite3_mutex_enter(db->mutex);
     assert( db->mallocFailed==0 );
+    assert( N>=0 && N<p->nColName );
 #ifndef SQLITE_OMIT_UTF16
     if( useUtf16 ){
       ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
@@ -1683,6 +1693,22 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
   return pStmt ? ((Vdbe*)pStmt)->explain : 0;
 }
 
+/*
+** Query or set the mode for a prepared statement.
+*/
+int sqlite3_stmt_mode(sqlite3_stmt *pStmt, int iNewMode){
+  Vdbe *v;
+  if( pStmt==0 ) return SQLITE_STMTMODE_RUN;
+  v = (Vdbe*)pStmt;
+  if( iNewMode==SQLITE_STMTMODE_EXPLAIN
+   || iNewMode==SQLITE_STMTMODE_TABLELIST
+   || iNewMode==v->origExplain
+  ){
+    v->explain = iNewMode;
+  }
+  return v->explain;
+}
+
 /*
 ** Return true if the prepared statement is in need of being reset.
 */
index 6afbf9a5a516abf43c5b5fe69a760c0583a601f3..41b7e7bcc618f1066b2f2bbe332ba5c0617fcd5a 100644 (file)
@@ -2388,6 +2388,7 @@ void sqlite3VdbeMakeReady(
       sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME,
                             azColName[i], SQLITE_STATIC);
     }
+    p->explain = p->origExplain = pParse->explain;
   }
   p->expired = 0;
 
@@ -2425,7 +2426,6 @@ void sqlite3VdbeMakeReady(
 
   p->pVList = pParse->pVList;
   pParse->pVList =  0;
-  p->explain = pParse->explain;
   if( db->mallocFailed ){
     p->nVar = 0;
     p->nCursor = 0;
@@ -2563,17 +2563,20 @@ static void closeAllCursors(Vdbe *p){
 ** be called on an SQL statement before sqlite3_step().
 */
 void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
-  int n;
   sqlite3 *db = p->db;
+  u32 n;
 
-  if( p->nResColumn ){
-    releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+  if( p->nColName ){
+    releaseMemArray(p->aColName, p->nColName);
     sqlite3DbFree(db, p->aColName);
   }
-  n = nResColumn*COLNAME_N;
   p->nResColumn = (u16)nResColumn;
+  n = p->nColName = (u32)nResColumn*COLNAME_N;
   p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
-  if( p->aColName==0 ) return;
+  if( p->aColName==0 ){
+    p->nColName = 0;
+    return;
+  }
   initMemArray(p->aColName, n, db, MEM_Null);
 }
 
@@ -3412,7 +3415,7 @@ void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
 void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
   SubProgram *pSub, *pNext;
   assert( p->db==0 || p->db==db );
-  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+  releaseMemArray(p->aColName, p->nColName);
   for(pSub=p->pProgram; pSub; pSub=pNext){
     pNext = pSub->pNext;
     vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
index 4e8b211700732499e777995f0af8bbea554ece64..7bc3ceece02b3787d701bac872cc4597de5420cf 100644 (file)
@@ -126,7 +126,7 @@ int sqlite3WhereExplainOneScan(
 ){
   int ret = 0;
 #if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
-  if( sqlite3ParseToplevel(pParse)->explain==2 )
+  if( sqlite3ParseToplevel(pParse)->explain==SQLITE_STMTMODE_EQP )
 #endif
   {
     struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];