/ Check-in [ae86cf60]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge latest trunk changes with this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA3-256:ae86cf60b6648a7ec789e233c9b0cc826efbbb0f301140b4848dc84d691ccd4f
User & Date: dan 2018-05-15 11:45:47
Context
2018-06-06
17:03
Merge changes from trunk, including all the 3.24.0 changes plus some later enhancements. check-in: d7299bfe user: drh tags: begin-concurrent
2018-05-15
11:55
Merge latest trunk changes into this branch. check-in: 72f39efa user: dan tags: begin-concurrent-pnu
11:45
Merge latest trunk changes with this branch. check-in: ae86cf60 user: dan tags: begin-concurrent
11:28
Instead of just the flags byte, include the first 8 bytes of the relevant page in an on-commit conflict log message. check-in: e7dc03e7 user: dan tags: begin-concurrent
09:09
Fix a test case problem in wherelimit.test. check-in: 3012df8b user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   568    568   # Databases containing fuzzer test cases
   569    569   #
   570    570   FUZZDATA = \
   571    571     $(TOP)/test/fuzzdata1.db \
   572    572     $(TOP)/test/fuzzdata2.db \
   573    573     $(TOP)/test/fuzzdata3.db \
   574    574     $(TOP)/test/fuzzdata4.db \
   575         -  $(TOP)/test/fuzzdata5.db
          575  +  $(TOP)/test/fuzzdata5.db \
          576  +  $(TOP)/test/fuzzdata6.db
   576    577   
   577    578   # Standard options to testfixture
   578    579   #
   579    580   TESTOPTS = --verbose=file --output=test-out.txt
   580    581   
   581    582   # Extra compiler options for various shell tools
   582    583   #

Changes to Makefile.msc.

  1595   1595   # Databases containing fuzzer test cases
  1596   1596   #
  1597   1597   FUZZDATA = \
  1598   1598     $(TOP)\test\fuzzdata1.db \
  1599   1599     $(TOP)\test\fuzzdata2.db \
  1600   1600     $(TOP)\test\fuzzdata3.db \
  1601   1601     $(TOP)\test\fuzzdata4.db \
  1602         -  $(TOP)\test\fuzzdata5.db
         1602  +  $(TOP)\test\fuzzdata5.db \
         1603  +  $(TOP)\test\fuzzdata6.db
  1603   1604   # <</mark>>
  1604   1605   
  1605   1606   # Additional compiler options for the shell.  These are only effective
  1606   1607   # when the shell is not being dynamically linked.
  1607   1608   #
  1608   1609   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
  1609   1610   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB

Changes to autoconf/Makefile.am.

     1      1   
     2         -AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @ZLIB_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
            2  +AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @ZLIB_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE @DEBUG_FLAGS@
     3      3   
     4      4   lib_LTLIBRARIES = libsqlite3.la
     5      5   libsqlite3_la_SOURCES = sqlite3.c
     6      6   libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
     7      7   
     8      8   bin_PROGRAMS = sqlite3
     9      9   sqlite3_SOURCES = shell.c sqlite3.h

Changes to autoconf/configure.ac.

   111    111   AC_SUBST(DYNAMIC_EXTENSION_FLAGS)
   112    112   #-----------------------------------------------------------------------
   113    113   
   114    114   #-----------------------------------------------------------------------
   115    115   #   --enable-fts5
   116    116   #
   117    117   AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
   118         -  [--enable-fts5], [include fts5 support [default=no]])], 
   119         -  [], [enable_fts5=no])
          118  +  [--enable-fts5], [include fts5 support [default=yes]])], 
          119  +  [], [enable_fts5=yes])
   120    120   if test x"$enable_fts5" = "xyes"; then
   121    121     AC_SEARCH_LIBS(log, m)
   122    122     FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
   123    123   fi
   124    124   AC_SUBST(FTS5_FLAGS)
   125    125   #-----------------------------------------------------------------------
   126    126   
   127    127   #-----------------------------------------------------------------------
   128    128   #   --enable-json1
   129    129   #
   130    130   AC_ARG_ENABLE(json1, [AS_HELP_STRING(
   131         -  [--enable-json1], [include json1 support [default=no]])], 
   132         -  [], [enable_json1=no])
          131  +  [--enable-json1], [include json1 support [default=yes]])], 
          132  +  [], [enable_json1=yes])
   133    133   if test x"$enable_json1" = "xyes"; then
   134    134     JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
   135    135   fi
   136    136   AC_SUBST(JSON1_FLAGS)
   137    137   #-----------------------------------------------------------------------
   138    138   
   139    139   #-----------------------------------------------------------------------
................................................................................
   143    143     [--enable-session], [enable the session extension [default=no]])], 
   144    144     [], [enable_session=no])
   145    145   if test x"$enable_session" = "xyes"; then
   146    146     SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
   147    147   fi
   148    148   AC_SUBST(SESSION_FLAGS)
   149    149   #-----------------------------------------------------------------------
          150  +
          151  +#-----------------------------------------------------------------------
          152  +#   --enable-debug
          153  +#
          154  +AC_ARG_ENABLE(debug, [AS_HELP_STRING(
          155  +  [--enable-debug], [build with debugging features enabled [default=no]])], 
          156  +  [], [enable_session=no])
          157  +if test x"$enable_debug" = "xyes"; then
          158  +  DEBUG_FLAGS="-DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
          159  +fi
          160  +AC_SUBST(DEBUG_FLAGS)
          161  +#-----------------------------------------------------------------------
   150    162   
   151    163   #-----------------------------------------------------------------------
   152    164   #   --enable-static-shell
   153    165   #
   154    166   AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(
   155    167     [--enable-static-shell], 
   156    168     [statically link libsqlite3 into shell tool [default=yes]])], 

Changes to ext/expert/expert1.test.

    91     91     eval $setup
    92     92   
    93     93   
    94     94   do_setup_rec_test $tn.1 { CREATE TABLE t1(a, b, c) } {
    95     95     SELECT * FROM t1
    96     96   } {
    97     97     (no new indexes)
    98         -  0|0|0|SCAN TABLE t1
           98  +  SCAN TABLE t1
    99     99   }
   100    100   
   101    101   do_setup_rec_test $tn.2 {
   102    102     CREATE TABLE t1(a, b, c);
   103    103   } {
   104    104     SELECT * FROM t1 WHERE b>?;
   105    105   } {
   106    106     CREATE INDEX t1_idx_00000062 ON t1(b);
   107         -  0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?)
          107  +  SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?)
   108    108   }
   109    109   
   110    110   do_setup_rec_test $tn.3 {
   111    111     CREATE TABLE t1(a, b, c);
   112    112   } {
   113    113     SELECT * FROM t1 WHERE b COLLATE nocase BETWEEN ? AND ?
   114    114   } {
   115    115     CREATE INDEX t1_idx_3e094c27 ON t1(b COLLATE NOCASE);
   116         -  0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
          116  +  SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
   117    117   }
   118    118   
   119    119   do_setup_rec_test $tn.4 {
   120    120     CREATE TABLE t1(a, b, c);
   121    121   } {
   122    122     SELECT a FROM t1 ORDER BY b;
   123    123   } {
   124    124     CREATE INDEX t1_idx_00000062 ON t1(b);
   125         -  0|0|0|SCAN TABLE t1 USING INDEX t1_idx_00000062
          125  +  SCAN TABLE t1 USING INDEX t1_idx_00000062
   126    126   }
   127    127   
   128    128   do_setup_rec_test $tn.5 {
   129    129     CREATE TABLE t1(a, b, c);
   130    130   } {
   131    131     SELECT a FROM t1 WHERE a=? ORDER BY b;
   132    132   } {
   133    133     CREATE INDEX t1_idx_000123a7 ON t1(a, b);
   134         -  0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
          134  +  SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
   135    135   }
   136    136   
   137    137   do_setup_rec_test $tn.6 {
   138    138     CREATE TABLE t1(a, b, c);
   139    139   } {
   140    140     SELECT min(a) FROM t1
   141    141   } {
   142    142     CREATE INDEX t1_idx_00000061 ON t1(a);
   143         -  0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
          143  +  SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
   144    144   }
   145    145   
   146    146   do_setup_rec_test $tn.7 {
   147    147     CREATE TABLE t1(a, b, c);
   148    148   } {
   149    149     SELECT * FROM t1 ORDER BY a, b, c;
   150    150   } {
   151    151     CREATE INDEX t1_idx_033e95fe ON t1(a, b, c);
   152         -  0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_033e95fe
          152  +  SCAN TABLE t1 USING COVERING INDEX t1_idx_033e95fe
   153    153   }
   154    154   
   155    155   #do_setup_rec_test $tn.1.8 {
   156    156   #  CREATE TABLE t1(a, b, c);
   157    157   #} {
   158    158   #  SELECT * FROM t1 ORDER BY a ASC, b COLLATE nocase DESC, c ASC;
   159    159   #} {
................................................................................
   163    163   
   164    164   do_setup_rec_test $tn.8.1 {
   165    165     CREATE TABLE t1(a COLLATE NOCase, b, c);
   166    166   } {
   167    167     SELECT * FROM t1 WHERE a=?
   168    168   } {
   169    169     CREATE INDEX t1_idx_00000061 ON t1(a);
   170         -  0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000061 (a=?)
          170  +  SEARCH TABLE t1 USING INDEX t1_idx_00000061 (a=?)
   171    171   }
   172    172   do_setup_rec_test $tn.8.2 {
   173    173     CREATE TABLE t1(a, b COLLATE nocase, c);
   174    174   } {
   175    175     SELECT * FROM t1 ORDER BY a ASC, b DESC, c ASC;
   176    176   } {
   177    177     CREATE INDEX t1_idx_5cb97285 ON t1(a, b DESC, c);
   178         -  0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_5cb97285
          178  +  SCAN TABLE t1 USING COVERING INDEX t1_idx_5cb97285
   179    179   }
   180    180   
   181    181   
   182    182   # Tables with names that require quotes.
   183    183   #
   184    184   do_setup_rec_test $tn.9.1 {
   185    185     CREATE TABLE "t t"(a, b, c);
   186    186   } {
   187    187     SELECT * FROM "t t" WHERE a=?
   188    188   } {
   189    189     CREATE INDEX 't t_idx_00000061' ON 't t'(a);
   190         -  0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000061 (a=?) 
          190  +  SEARCH TABLE t t USING INDEX t t_idx_00000061 (a=?) 
   191    191   }
   192    192   
   193    193   do_setup_rec_test $tn.9.2 {
   194    194     CREATE TABLE "t t"(a, b, c);
   195    195   } {
   196    196     SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
   197    197   } {
   198    198     CREATE INDEX 't t_idx_00000062' ON 't t'(b);
   199         -  0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000062 (b>? AND b<?)
          199  +  SEARCH TABLE t t USING INDEX t t_idx_00000062 (b>? AND b<?)
   200    200   }
   201    201   
   202    202   # Columns with names that require quotes.
   203    203   #
   204    204   do_setup_rec_test $tn.10.1 {
   205    205     CREATE TABLE t3(a, "b b", c);
   206    206   } {
   207    207     SELECT * FROM t3 WHERE "b b" = ?
   208    208   } {
   209    209     CREATE INDEX t3_idx_00050c52 ON t3('b b');
   210         -  0|0|0|SEARCH TABLE t3 USING INDEX t3_idx_00050c52 (b b=?)
          210  +  SEARCH TABLE t3 USING INDEX t3_idx_00050c52 (b b=?)
   211    211   }
   212    212   
   213    213   do_setup_rec_test $tn.10.2 {
   214    214     CREATE TABLE t3(a, "b b", c);
   215    215   } {
   216    216     SELECT * FROM t3 ORDER BY "b b"
   217    217   } {
   218    218     CREATE INDEX t3_idx_00050c52 ON t3('b b');
   219         -  0|0|0|SCAN TABLE t3 USING INDEX t3_idx_00050c52
          219  +  SCAN TABLE t3 USING INDEX t3_idx_00050c52
   220    220   }
   221    221   
   222    222   # Transitive constraints
   223    223   #
   224    224   do_setup_rec_test $tn.11.1 {
   225    225     CREATE TABLE t5(a, b);
   226    226     CREATE TABLE t6(c, d);
   227    227   } {
   228    228     SELECT * FROM t5, t6 WHERE a=? AND b=c AND c=?
   229    229   } {
   230    230     CREATE INDEX t5_idx_000123a7 ON t5(a, b);
   231    231     CREATE INDEX t6_idx_00000063 ON t6(c);
   232         -  0|0|1|SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?) 
   233         -  0|1|0|SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
          232  +  SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?) 
          233  +  SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
   234    234   }
   235    235   
   236    236   # OR terms.
   237    237   #
   238    238   do_setup_rec_test $tn.12.1 {
   239    239     CREATE TABLE t7(a, b);
   240    240   } {
   241    241     SELECT * FROM t7 WHERE a=? OR b=?
   242    242   } {
   243    243     CREATE INDEX t7_idx_00000062 ON t7(b);
   244    244     CREATE INDEX t7_idx_00000061 ON t7(a);
   245         -  0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?) 
   246         -  0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
          245  +  MULTI-INDEX OR
          246  +    SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?) 
          247  +    SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
   247    248   }
   248    249   
   249    250   # rowid terms.
   250    251   #
   251    252   do_setup_rec_test $tn.13.1 {
   252    253     CREATE TABLE t8(a, b);
   253    254   } {
   254    255     SELECT * FROM t8 WHERE rowid=?
   255    256   } {
   256    257     (no new indexes)
   257         -  0|0|0|SEARCH TABLE t8 USING INTEGER PRIMARY KEY (rowid=?)
          258  +  SEARCH TABLE t8 USING INTEGER PRIMARY KEY (rowid=?)
   258    259   }
   259    260   do_setup_rec_test $tn.13.2 {
   260    261     CREATE TABLE t8(a, b);
   261    262   } {
   262    263     SELECT * FROM t8 ORDER BY rowid
   263    264   } {
   264    265     (no new indexes)
   265         -  0|0|0|SCAN TABLE t8
          266  +  SCAN TABLE t8
   266    267   }
   267    268   do_setup_rec_test $tn.13.3 {
   268    269     CREATE TABLE t8(a, b);
   269    270   } {
   270    271     SELECT * FROM t8 WHERE a=? ORDER BY rowid
   271    272   } {
   272    273     CREATE INDEX t8_idx_00000061 ON t8(a); 
   273         -  0|0|0|SEARCH TABLE t8 USING INDEX t8_idx_00000061 (a=?)
          274  +  SEARCH TABLE t8 USING INDEX t8_idx_00000061 (a=?)
   274    275   }
   275    276   
   276    277   # Triggers
   277    278   #
   278    279   do_setup_rec_test $tn.14 {
   279    280     CREATE TABLE t9(a, b, c);
   280    281     CREATE TABLE t10(a, b, c);
................................................................................
   281    282     CREATE TRIGGER t9t AFTER INSERT ON t9 BEGIN
   282    283       UPDATE t10 SET a=new.a WHERE b = new.b;
   283    284     END;
   284    285   } {
   285    286     INSERT INTO t9 VALUES(?, ?, ?);
   286    287   } {
   287    288     CREATE INDEX t10_idx_00000062 ON t10(b); 
   288         -  0|1|0|-- TRIGGER t9t
   289         -  0|0|0|SEARCH TABLE t10 USING INDEX t10_idx_00000062 (b=?)
          289  +  -- TRIGGER t9t
          290  +  SEARCH TABLE t10 USING INDEX t10_idx_00000062 (b=?)
   290    291   }
   291    292   
   292    293   do_setup_rec_test $tn.15 {
   293    294     CREATE TABLE t1(a, b);
   294    295     CREATE TABLE t2(c, d);
   295    296   
   296    297     WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
................................................................................
   298    299   
   299    300     WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
   300    301     INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
   301    302   } {
   302    303     SELECT * FROM t2, t1 WHERE b=? AND d=? AND t2.rowid=t1.rowid
   303    304   } {
   304    305     CREATE INDEX t2_idx_00000064 ON t2(d);
   305         -  0|0|0|SEARCH TABLE t2 USING INDEX t2_idx_00000064 (d=?) 
   306         -  0|1|1|SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
          306  +  SEARCH TABLE t2 USING INDEX t2_idx_00000064 (d=?) 
          307  +  SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
   307    308   }
   308    309   
   309    310   do_setup_rec_test $tn.16 {
   310    311     CREATE TABLE t1(a, b);
   311    312   } {
   312    313     SELECT * FROM t1 WHERE b IS NOT NULL;
   313    314   } {
   314    315     (no new indexes)
   315         -  0|0|0|SCAN TABLE t1
          316  +  SCAN TABLE t1
   316    317   }
   317    318   
   318    319   }
   319    320   
   320    321   proc do_candidates_test {tn sql res} {
   321    322     set res [squish [string trim $res]]
   322    323   

Changes to ext/expert/sqlite3expert.c.

  1119   1119       IdxHashEntry *pEntry;
  1120   1120       sqlite3_stmt *pExplain = 0;
  1121   1121       idxHashClear(&hIdx);
  1122   1122       rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,
  1123   1123           "EXPLAIN QUERY PLAN %s", pStmt->zSql
  1124   1124       );
  1125   1125       while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
  1126         -      int iSelectid = sqlite3_column_int(pExplain, 0);
  1127         -      int iOrder = sqlite3_column_int(pExplain, 1);
  1128         -      int iFrom = sqlite3_column_int(pExplain, 2);
         1126  +      /* int iId = sqlite3_column_int(pExplain, 0); */
         1127  +      /* int iParent = sqlite3_column_int(pExplain, 1); */
         1128  +      /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
  1129   1129         const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
  1130   1130         int nDetail = STRLEN(zDetail);
  1131   1131         int i;
  1132   1132   
  1133   1133         for(i=0; i<nDetail; i++){
  1134   1134           const char *zIdx = 0;
  1135   1135           if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
................................................................................
  1148   1148               idxHashAdd(&rc, &hIdx, zSql, 0);
  1149   1149               if( rc ) goto find_indexes_out;
  1150   1150             }
  1151   1151             break;
  1152   1152           }
  1153   1153         }
  1154   1154   
  1155         -      pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%d|%d|%d|%s\n", 
  1156         -          iSelectid, iOrder, iFrom, zDetail
  1157         -      );
         1155  +      pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
  1158   1156       }
  1159   1157   
  1160   1158       for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
  1161   1159         pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey);
  1162   1160       }
  1163   1161   
  1164   1162       idxFinalize(&rc, pExplain);

Changes to ext/fts3/fts3.c.

  3959   3959       ){
  3960   3960         rc = SQLITE_NOMEM;
  3961   3961       }
  3962   3962     }
  3963   3963   
  3964   3964   #ifdef SQLITE_TEST
  3965   3965     if( rc==SQLITE_OK ){
  3966         -    rc = sqlite3Fts3ExprInitTestInterface(db);
         3966  +    rc = sqlite3Fts3ExprInitTestInterface(db, pHash);
  3967   3967     }
  3968   3968   #endif
  3969   3969   
  3970   3970     /* Create the virtual table wrapper around the hash-table and overload 
  3971   3971     ** the four scalar functions. If this is successful, register the
  3972   3972     ** module with sqlite.
  3973   3973     */

Changes to ext/fts3/fts3Int.h.

   580    580   
   581    581   /* fts3_expr.c */
   582    582   int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
   583    583     char **, int, int, int, const char *, int, Fts3Expr **, char **
   584    584   );
   585    585   void sqlite3Fts3ExprFree(Fts3Expr *);
   586    586   #ifdef SQLITE_TEST
   587         -int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
          587  +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
   588    588   int sqlite3Fts3InitTerm(sqlite3 *db);
   589    589   #endif
   590    590   
   591    591   int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
   592    592     sqlite3_tokenizer_cursor **
   593    593   );
   594    594   

Changes to ext/fts3/fts3_expr.c.

  1104   1104   ** Everything after this point is just test code.
  1105   1105   */
  1106   1106   
  1107   1107   #ifdef SQLITE_TEST
  1108   1108   
  1109   1109   #include <stdio.h>
  1110   1110   
  1111         -/*
  1112         -** Function to query the hash-table of tokenizers (see README.tokenizers).
  1113         -*/
  1114         -static int queryTestTokenizer(
  1115         -  sqlite3 *db, 
  1116         -  const char *zName,  
  1117         -  const sqlite3_tokenizer_module **pp
  1118         -){
  1119         -  int rc;
  1120         -  sqlite3_stmt *pStmt;
  1121         -  const char zSql[] = "SELECT fts3_tokenizer(?)";
  1122         -
  1123         -  *pp = 0;
  1124         -  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  1125         -  if( rc!=SQLITE_OK ){
  1126         -    return rc;
  1127         -  }
  1128         -
  1129         -  sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
  1130         -  if( SQLITE_ROW==sqlite3_step(pStmt) ){
  1131         -    if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
  1132         -      memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
  1133         -    }
  1134         -  }
  1135         -
  1136         -  return sqlite3_finalize(pStmt);
  1137         -}
  1138         -
  1139   1111   /*
  1140   1112   ** Return a pointer to a buffer containing a text representation of the
  1141   1113   ** expression passed as the first argument. The buffer is obtained from
  1142   1114   ** sqlite3_malloc(). It is the responsibility of the caller to use 
  1143   1115   ** sqlite3_free() to release the memory. If an OOM condition is encountered,
  1144   1116   ** NULL is returned.
  1145   1117   **
................................................................................
  1199   1171   ** to parse the query expression (see README.tokenizers). The second argument
  1200   1172   ** is the query expression to parse. Each subsequent argument is the name
  1201   1173   ** of a column of the fts3 table that the query expression may refer to.
  1202   1174   ** For example:
  1203   1175   **
  1204   1176   **   SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
  1205   1177   */
  1206         -static void fts3ExprTest(
         1178  +static void fts3ExprTestCommon(
         1179  +  int bRebalance,
  1207   1180     sqlite3_context *context,
  1208   1181     int argc,
  1209   1182     sqlite3_value **argv
  1210   1183   ){
  1211         -  sqlite3_tokenizer_module const *pModule = 0;
  1212   1184     sqlite3_tokenizer *pTokenizer = 0;
  1213   1185     int rc;
  1214   1186     char **azCol = 0;
  1215   1187     const char *zExpr;
  1216   1188     int nExpr;
  1217   1189     int nCol;
  1218   1190     int ii;
  1219   1191     Fts3Expr *pExpr;
  1220   1192     char *zBuf = 0;
  1221         -  sqlite3 *db = sqlite3_context_db_handle(context);
         1193  +  Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context);
         1194  +  const char *zTokenizer = 0;
         1195  +  char *zErr = 0;
  1222   1196   
  1223   1197     if( argc<3 ){
  1224   1198       sqlite3_result_error(context, 
  1225   1199           "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1
  1226   1200       );
  1227   1201       return;
  1228   1202     }
  1229   1203   
  1230         -  rc = queryTestTokenizer(db,
  1231         -                          (const char *)sqlite3_value_text(argv[0]), &pModule);
  1232         -  if( rc==SQLITE_NOMEM ){
  1233         -    sqlite3_result_error_nomem(context);
  1234         -    goto exprtest_out;
  1235         -  }else if( !pModule ){
  1236         -    sqlite3_result_error(context, "No such tokenizer module", -1);
  1237         -    goto exprtest_out;
         1204  +  zTokenizer = (const char*)sqlite3_value_text(argv[0]);
         1205  +  rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr);
         1206  +  if( rc!=SQLITE_OK ){
         1207  +    if( rc==SQLITE_NOMEM ){
         1208  +      sqlite3_result_error_nomem(context);
         1209  +    }else{
         1210  +      sqlite3_result_error(context, zErr, -1);
         1211  +    }
         1212  +    sqlite3_free(zErr);
         1213  +    return;
  1238   1214     }
  1239   1215   
  1240         -  rc = pModule->xCreate(0, 0, &pTokenizer);
  1241         -  assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
  1242         -  if( rc==SQLITE_NOMEM ){
  1243         -    sqlite3_result_error_nomem(context);
  1244         -    goto exprtest_out;
  1245         -  }
  1246         -  pTokenizer->pModule = pModule;
  1247         -
  1248   1216     zExpr = (const char *)sqlite3_value_text(argv[1]);
  1249   1217     nExpr = sqlite3_value_bytes(argv[1]);
  1250   1218     nCol = argc-2;
  1251   1219     azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
  1252   1220     if( !azCol ){
  1253   1221       sqlite3_result_error_nomem(context);
  1254   1222       goto exprtest_out;
  1255   1223     }
  1256   1224     for(ii=0; ii<nCol; ii++){
  1257   1225       azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
  1258   1226     }
  1259   1227   
  1260         -  if( sqlite3_user_data(context) ){
         1228  +  if( bRebalance ){
  1261   1229       char *zDummy = 0;
  1262   1230       rc = sqlite3Fts3ExprParse(
  1263   1231           pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy
  1264   1232       );
  1265   1233       assert( rc==SQLITE_OK || pExpr==0 );
  1266   1234       sqlite3_free(zDummy);
  1267   1235     }else{
................................................................................
  1279   1247       sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  1280   1248       sqlite3_free(zBuf);
  1281   1249     }
  1282   1250   
  1283   1251     sqlite3Fts3ExprFree(pExpr);
  1284   1252   
  1285   1253   exprtest_out:
  1286         -  if( pModule && pTokenizer ){
  1287         -    rc = pModule->xDestroy(pTokenizer);
         1254  +  if( pTokenizer ){
         1255  +    rc = pTokenizer->pModule->xDestroy(pTokenizer);
  1288   1256     }
  1289   1257     sqlite3_free(azCol);
  1290   1258   }
         1259  +
         1260  +static void fts3ExprTest(
         1261  +  sqlite3_context *context,
         1262  +  int argc,
         1263  +  sqlite3_value **argv
         1264  +){
         1265  +  fts3ExprTestCommon(0, context, argc, argv);
         1266  +}
         1267  +static void fts3ExprTestRebalance(
         1268  +  sqlite3_context *context,
         1269  +  int argc,
         1270  +  sqlite3_value **argv
         1271  +){
         1272  +  fts3ExprTestCommon(1, context, argc, argv);
         1273  +}
  1291   1274   
  1292   1275   /*
  1293   1276   ** Register the query expression parser test function fts3_exprtest() 
  1294   1277   ** with database connection db. 
  1295   1278   */
  1296         -int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
         1279  +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){
  1297   1280     int rc = sqlite3_create_function(
  1298         -      db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
         1281  +      db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0
  1299   1282     );
  1300   1283     if( rc==SQLITE_OK ){
  1301   1284       rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", 
  1302         -        -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0
         1285  +        -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0
  1303   1286       );
  1304   1287     }
  1305   1288     return rc;
  1306   1289   }
  1307   1290   
  1308   1291   #endif
  1309   1292   #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts5/test/fts5plan.test.

    25     25     CREATE TABLE t1(x, y);
    26     26     CREATE VIRTUAL TABLE f1 USING fts5(ff);
    27     27   }
    28     28   
    29     29   do_eqp_test 1.1 {
    30     30     SELECT * FROM t1, f1 WHERE f1 MATCH t1.x
    31     31   } {
    32         -  0 0 0 {SCAN TABLE t1} 
    33         -  0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
           32  +  QUERY PLAN
           33  +  |--SCAN TABLE t1
           34  +  `--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
    34     35   }
    35     36   
    36     37   do_eqp_test 1.2 {
    37     38     SELECT * FROM t1, f1 WHERE f1 > t1.x
    38     39   } {
    39         -  0 0 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:}
    40         -  0 1 0 {SCAN TABLE t1} 
           40  +  QUERY PLAN
           41  +  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:
           42  +  `--SCAN TABLE t1
    41     43   }
    42     44   
    43     45   do_eqp_test 1.3 {
    44     46     SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
    45     47   } {
    46         -  0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
    47         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
           48  +  QUERY PLAN
           49  +  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
           50  +  `--USE TEMP B-TREE FOR ORDER BY
    48     51   }
    49     52   
    50     53   do_eqp_test 1.4 {
    51     54     SELECT * FROM f1 ORDER BY rank
    52     55   } {
    53         -  0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:}
    54         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
           56  +  QUERY PLAN
           57  +  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:
           58  +  `--USE TEMP B-TREE FOR ORDER BY
    55     59   }
    56     60   
    57     61   do_eqp_test 1.5 {
    58     62     SELECT * FROM f1 WHERE rank MATCH ?
    59         -} {
    60         -  0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
    61         -}
    62         -
    63         -
    64         -
           63  +} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
    65     64   
    66     65   finish_test

Changes to ext/fts5/test/fts5unicode.test.

    37     37     tokenize_test 1.$tn.2 $t {..May...you.shAre.freely} {may you share freely}
    38     38     tokenize_test 1.$tn.3 $t {} {}
    39     39   }
    40     40   
    41     41   #-------------------------------------------------------------------------
    42     42   # Check that "unicode61" really is the default tokenizer.
    43     43   #
    44         -
    45     44   do_execsql_test 2.0 "
    46     45     CREATE VIRTUAL TABLE t1 USING fts5(x);
    47     46     CREATE VIRTUAL TABLE t2 USING fts5(x, tokenize = unicode61);
    48     47     CREATE VIRTUAL TABLE t3 USING fts5(x, tokenize = ascii);
    49     48     INSERT INTO t1 VALUES('\xC0\xC8\xCC');
    50     49     INSERT INTO t2 VALUES('\xC0\xC8\xCC');
    51     50     INSERT INTO t3 VALUES('\xC0\xC8\xCC');
    52     51   "
    53     52   do_execsql_test 2.1 "
    54     53     SELECT 't1' FROM t1 WHERE t1 MATCH '\xE0\xE8\xEC';
    55     54     SELECT 't2' FROM t2 WHERE t2 MATCH '\xE0\xE8\xEC';
    56     55     SELECT 't3' FROM t3 WHERE t3 MATCH '\xE0\xE8\xEC';
    57     56   " {t1 t2}
           57  +
           58  +#-------------------------------------------------------------------------
           59  +# Check that codepoints that require 4 bytes to store in utf-8 (those that
           60  +# require 17 or more bits to store).
           61  +#
           62  +
           63  +set A [db one {SELECT char(0x1F75E)}]    ;# Type So
           64  +set B [db one {SELECT char(0x1F5FD)}]    ;# Type So
           65  +set C [db one {SELECT char(0x2F802)}]    ;# Type Lo
           66  +set D [db one {SELECT char(0x2F808)}]    ;# Type Lo
           67  +
           68  +do_execsql_test 3.0 "
           69  +  CREATE VIRTUAL TABLE xyz USING fts5(x,
           70  +    tokenize = \"unicode61 separators '$C' tokenchars '$A'\"
           71  +  );
           72  +  CREATE VIRTUAL TABLE xyz_v USING fts5vocab(xyz, row);
           73  +
           74  +  INSERT INTO xyz VALUES('$A$B$C$D');
           75  +"
           76  +
           77  +do_execsql_test 3.1 {
           78  +  SELECT * FROM xyz_v;
           79  +} [list $A 1 1 $D 1 1]
           80  +  
           81  +
           82  +
    58     83   
    59     84   
    60     85   finish_test

Changes to ext/misc/closure.c.

   822    822   static int closureBestIndex(
   823    823     sqlite3_vtab *pTab,             /* The virtual table */
   824    824     sqlite3_index_info *pIdxInfo    /* Information about the query */
   825    825   ){
   826    826     int iPlan = 0;
   827    827     int i;
   828    828     int idx = 1;
   829         -  int seenMatch = 0;
   830    829     const struct sqlite3_index_constraint *pConstraint;
   831    830     closure_vtab *pVtab = (closure_vtab*)pTab;
   832    831     double rCost = 10000000.0;
   833    832   
   834    833     pConstraint = pIdxInfo->aConstraint;
   835    834     for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
   836         -    if( pConstraint->iColumn==CLOSURE_COL_ROOT
   837         -     && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
   838         -      seenMatch = 1;
   839         -    }
   840    835       if( pConstraint->usable==0 ) continue;
   841    836       if( (iPlan & 1)==0 
   842    837        && pConstraint->iColumn==CLOSURE_COL_ROOT
   843    838        && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
   844    839       ){
   845    840         iPlan |= 1;
   846    841         pIdxInfo->aConstraintUsage[i].argvIndex = 1;
................................................................................
   888    883      || (pVtab->zIdColumn==0     && (iPlan & 0x00f000)==0)
   889    884      || (pVtab->zParentColumn==0 && (iPlan & 0x0f0000)==0)
   890    885     ){
   891    886       /* All of tablename, idcolumn, and parentcolumn must be specified
   892    887       ** in either the CREATE VIRTUAL TABLE or in the WHERE clause constraints
   893    888       ** or else the result is an empty set. */
   894    889       iPlan = 0;
          890  +  }
          891  +  if( (iPlan&1)==0 ){
          892  +    /* If there is no usable "root=?" term, then set the index-type to 0.
          893  +    ** Also clear any argvIndex variables already set. This is necessary
          894  +    ** to prevent the core from throwing an "xBestIndex malfunction error"
          895  +    ** error (because the argvIndex values are not contiguously assigned
          896  +    ** starting from 1).  */
          897  +    rCost *= 1e30;
          898  +    for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
          899  +      pIdxInfo->aConstraintUsage[i].argvIndex = 0;
          900  +    }
          901  +    iPlan = 0;
   895    902     }
   896    903     pIdxInfo->idxNum = iPlan;
   897    904     if( pIdxInfo->nOrderBy==1
   898    905      && pIdxInfo->aOrderBy[0].iColumn==CLOSURE_COL_ID
   899    906      && pIdxInfo->aOrderBy[0].desc==0
   900    907     ){
   901    908       pIdxInfo->orderByConsumed = 1;
   902    909     }
   903         -  if( seenMatch && (iPlan&1)==0 ) rCost *= 1e30;
   904    910     pIdxInfo->estimatedCost = rCost;
   905    911      
   906    912     return SQLITE_OK;
   907    913   }
   908    914   
   909    915   /*
   910    916   ** A virtual table module that implements the "transitive_closure".

Changes to ext/misc/templatevtab.c.

     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13         -** This file implements a template virtual-table implementation.
           13  +** This file implements a template virtual-table.
    14     14   ** Developers can make a copy of this file as a baseline for writing
    15     15   ** new virtual tables and/or table-valued functions.
    16     16   **
    17     17   ** Steps for writing a new virtual table implementation:
    18     18   **
    19         -**     (1)  Make a copy of this file.  Prehaps "mynewvtab.c"
           19  +**     (1)  Make a copy of this file.  Perhaps call it "mynewvtab.c"
    20     20   **
    21     21   **     (2)  Replace this header comment with something appropriate for
    22     22   **          the new virtual table
    23     23   **
    24     24   **     (3)  Change every occurrence of "templatevtab" to some other string
    25     25   **          appropriate for the new virtual table.  Ideally, the new string
    26         -**          should be the basename of the source file: "mynewvtab".
           26  +**          should be the basename of the source file: "mynewvtab".  Also
           27  +**          globally change "TEMPLATEVTAB" to "MYNEWVTAB".
    27     28   **
    28     29   **     (4)  Run a test compilation to make sure the unmodified virtual
    29     30   **          table works.
    30     31   **
    31         -**     (5)  Begin making changes to make the new virtual table do what you
    32         -**          want it to do.
    33         -**
    34         -**     (6)  Ensure that all the "FIXME" comments in the file have been dealt
    35         -**          with.
           32  +**     (5)  Begin making incremental changes, testing as you go, to evolve
           33  +**          the new virtual table to do what you want it to do.
    36     34   **
    37     35   ** This template is minimal, in the sense that it uses only the required
    38     36   ** methods on the sqlite3_module object.  As a result, templatevtab is
    39     37   ** a read-only and eponymous-only table.  Those limitation can be removed
    40     38   ** by adding new methods.
           39  +**
           40  +** This template implements an eponymous-only virtual table with a rowid and
           41  +** two columns named "a" and "b".  The table as 10 rows with fixed integer
           42  +** values. Usage example:
           43  +**
           44  +**     SELECT rowid, a, b FROM templatevtab;
    41     45   */
    42     46   #if !defined(SQLITEINT_H)
    43     47   #include "sqlite3ext.h"
    44     48   #endif
    45     49   SQLITE_EXTENSION_INIT1
    46     50   #include <string.h>
           51  +#include <assert.h>
    47     52   
    48     53   /* templatevtab_vtab is a subclass of sqlite3_vtab which is
    49     54   ** underlying representation of the virtual table
    50     55   */
    51     56   typedef struct templatevtab_vtab templatevtab_vtab;
    52     57   struct templatevtab_vtab {
    53     58     sqlite3_vtab base;  /* Base class - must be first */
................................................................................
    88     93   ){
    89     94     templatevtab_vtab *pNew;
    90     95     int rc;
    91     96   
    92     97     rc = sqlite3_declare_vtab(db,
    93     98              "CREATE TABLE x(a,b)"
    94     99          );
          100  +  /* For convenience, define symbolic names for the index to each column. */
          101  +#define TEMPLATEVTAB_A  0
          102  +#define TEMPLATEVTAB_B  1
    95    103     if( rc==SQLITE_OK ){
    96    104       pNew = sqlite3_malloc( sizeof(*pNew) );
    97    105       *ppVtab = (sqlite3_vtab*)pNew;
    98    106       if( pNew==0 ) return SQLITE_NOMEM;
    99    107       memset(pNew, 0, sizeof(*pNew));
   100    108     }
   101    109     return rc;
................................................................................
   147    155   */
   148    156   static int templatevtabColumn(
   149    157     sqlite3_vtab_cursor *cur,   /* The cursor */
   150    158     sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
   151    159     int i                       /* Which column to return */
   152    160   ){
   153    161     templatevtab_cursor *pCur = (templatevtab_cursor*)cur;
   154         -  sqlite3_result_int(ctx, (i+1)*1000 + pCur->iRowid);
          162  +  switch( i ){
          163  +    case TEMPLATEVTAB_A:
          164  +      sqlite3_result_int(ctx, 1000 + pCur->iRowid);
          165  +      break;
          166  +    default:
          167  +      assert( i==TEMPLATEVTAB_B );
          168  +      sqlite3_result_int(ctx, 2000 + pCur->iRowid);
          169  +      break;
          170  +  }
   155    171     return SQLITE_OK;
   156    172   }
   157    173   
   158    174   /*
   159    175   ** Return the rowid for the current row.  In this implementation, the
   160    176   ** rowid is the same as the output value.
   161    177   */

Changes to ext/rbu/rbu1.test.

   135    135   } {
   136    136   
   137    137     eval $create_vfs
   138    138   
   139    139     foreach {tn2 cmd} {
   140    140         1 run_rbu 
   141    141         2 step_rbu 3 step_rbu_uri 4 step_rbu_state
          142  +      5 step_rbu_legacy
   142    143     } {
   143    144       foreach {tn schema} {
   144    145         1 {
   145    146           CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
   146    147         }
   147    148         2 { 
   148    149           CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);

Changes to ext/rbu/rbu_common.tcl.

    65     65       set rc [rbu step]
    66     66       check_poststep_state $rc $target $state
    67     67       rbu close
    68     68       if {$rc != "SQLITE_OK"} break
    69     69     }
    70     70     set rc
    71     71   }
           72  +
           73  +proc step_rbu_legacy {target rbu} {
           74  +  while 1 {
           75  +    sqlite3rbu rbu $target $rbu
           76  +    set state [rbu state]
           77  +    check_prestep_state $target $state
           78  +    set rc [rbu step]
           79  +    check_poststep_state $rc $target $state
           80  +    rbu close
           81  +    if {$rc != "SQLITE_OK"} break
           82  +    sqlite3 tmpdb $rbu
           83  +    tmpdb eval { DELETE FROM rbu_state WHERE k==10 }
           84  +    tmpdb close
           85  +  }
           86  +  set rc
           87  +}
    72     88   
    73     89   proc do_rbu_vacuum_test {tn step} {
    74     90     forcedelete state.db
    75     91     uplevel [list do_test $tn.1 {
    76     92       if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
    77     93       while 1 {
    78     94         if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }

Added ext/rbu/rbusplit.test.

            1  +# 2018 April 28
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +#
           13  +
           14  +source [file join [file dirname [info script]] rbu_common.tcl]
           15  +set ::testprefix rbusplit
           16  +
           17  +db close
           18  +sqlite3_shutdown
           19  +sqlite3_config_uri 1
           20  +
           21  +autoinstall_test_functions
           22  +
           23  +proc build_db {db} {
           24  +  $db eval {
           25  +    CREATE TABLE t1(a PRIMARY KEY, b, c);
           26  +    CREATE TABLE t2(a PRIMARY KEY, b, c);
           27  +
           28  +    CREATE INDEX t1c ON t1(c);
           29  +  }
           30  +}
           31  +
           32  +proc build_rbu {filename} {
           33  +  forcedelete $filename
           34  +  sqlite3 dbRbu $filename
           35  +  dbRbu eval {
           36  +    CREATE TABLE data0_t1(a, b, c, rbu_control);
           37  +    CREATE TABLE data1_t1(a, b, c, rbu_control);
           38  +    CREATE TABLE data2_t1(a, b, c, rbu_control);
           39  +    CREATE TABLE data3_t1(a, b, c, rbu_control);
           40  +
           41  +    CREATE TABLE data_t2(a, b, c, rbu_control);
           42  +
           43  +    INSERT INTO data0_t1 VALUES(1, 1, 1, 0);
           44  +    INSERT INTO data0_t1 VALUES(2, 2, 2, 0);
           45  +    INSERT INTO data0_t1 VALUES(3, 3, 3, 0);
           46  +    INSERT INTO data0_t1 VALUES(4, 4, 4, 0);
           47  +    INSERT INTO data1_t1 VALUES(5, 5, 5, 0);
           48  +    INSERT INTO data1_t1 VALUES(6, 6, 6, 0);
           49  +    INSERT INTO data1_t1 VALUES(7, 7, 7, 0);
           50  +    INSERT INTO data1_t1 VALUES(8, 8, 8, 0);
           51  +    INSERT INTO data3_t1 VALUES(9, 9, 9, 0);
           52  +
           53  +    INSERT INTO data_t2 VALUES(1, 1, 1, 0);
           54  +    INSERT INTO data_t2 VALUES(2, 2, 2, 0);
           55  +    INSERT INTO data_t2 VALUES(3, 3, 3, 0);
           56  +    INSERT INTO data_t2 VALUES(4, 4, 4, 0);
           57  +    INSERT INTO data_t2 VALUES(5, 5, 5, 0);
           58  +    INSERT INTO data_t2 VALUES(6, 6, 6, 0);
           59  +    INSERT INTO data_t2 VALUES(7, 7, 7, 0);
           60  +    INSERT INTO data_t2 VALUES(8, 8, 8, 0);
           61  +    INSERT INTO data_t2 VALUES(9, 9, 9, 0);
           62  +  }
           63  +  
           64  +  dbRbu close
           65  +}
           66  +
           67  +foreach {tn cmd} {
           68  +  1 run_rbu
           69  +  2 step_rbu
           70  +} {
           71  +  reset_db
           72  +  build_db db
           73  +  build_rbu testrbu.db
           74  +
           75  +  do_test 1.$tn.1 {
           76  +    $cmd test.db testrbu.db
           77  +  } {SQLITE_DONE}
           78  +  do_execsql_test 1.$tn.1 {
           79  +    SELECT * FROM t1;
           80  +  } {
           81  +    1 1 1 2 2 2 3 3 3 4 4 4
           82  +    5 5 5 6 6 6 7 7 7 8 8 8
           83  +    9 9 9
           84  +  }
           85  +  do_execsql_test 1.$tn.2 {
           86  +    SELECT * FROM t2;
           87  +  } {
           88  +    1 1 1 2 2 2 3 3 3 4 4 4
           89  +    5 5 5 6 6 6 7 7 7 8 8 8
           90  +    9 9 9
           91  +  }
           92  +}
           93  +
           94  +finish_test
           95  +

Changes to ext/rbu/sqlite3rbu.c.

   149    149   **
   150    150   ** RBU_STATE_COOKIE:
   151    151   **   Valid if STAGE==1. The current change-counter cookie value in the 
   152    152   **   target db file.
   153    153   **
   154    154   ** RBU_STATE_OALSZ:
   155    155   **   Valid if STAGE==1. The size in bytes of the *-oal file.
          156  +**
          157  +** RBU_STATE_DATATBL:
          158  +**   Only valid if STAGE==1. The RBU database name of the table 
          159  +**   currently being read.
   156    160   */
   157    161   #define RBU_STATE_STAGE        1
   158    162   #define RBU_STATE_TBL          2
   159    163   #define RBU_STATE_IDX          3
   160    164   #define RBU_STATE_ROW          4
   161    165   #define RBU_STATE_PROGRESS     5
   162    166   #define RBU_STATE_CKPT         6
   163    167   #define RBU_STATE_COOKIE       7
   164    168   #define RBU_STATE_OALSZ        8
   165    169   #define RBU_STATE_PHASEONESTEP 9
          170  +#define RBU_STATE_DATATBL     10
   166    171   
   167    172   #define RBU_STAGE_OAL         1
   168    173   #define RBU_STAGE_MOVE        2
   169    174   #define RBU_STAGE_CAPTURE     3
   170    175   #define RBU_STAGE_CKPT        4
   171    176   #define RBU_STAGE_DONE        5
   172    177   
................................................................................
   201    206   
   202    207   /*
   203    208   ** A structure to store values read from the rbu_state table in memory.
   204    209   */
   205    210   struct RbuState {
   206    211     int eStage;
   207    212     char *zTbl;
          213  +  char *zDataTbl;
   208    214     char *zIdx;
   209    215     i64 iWalCksum;
   210    216     int nRow;
   211    217     i64 nProgress;
   212    218     u32 iCookie;
   213    219     i64 iOalSz;
   214    220     i64 nPhaseOneStep;
................................................................................
  2264   2270   
  2265   2271   /*
  2266   2272   ** Free an RbuState object allocated by rbuLoadState().
  2267   2273   */
  2268   2274   static void rbuFreeState(RbuState *p){
  2269   2275     if( p ){
  2270   2276       sqlite3_free(p->zTbl);
         2277  +    sqlite3_free(p->zDataTbl);
  2271   2278       sqlite3_free(p->zIdx);
  2272   2279       sqlite3_free(p);
  2273   2280     }
  2274   2281   }
  2275   2282   
  2276   2283   /*
  2277   2284   ** Allocate an RbuState object and load the contents of the rbu_state 
................................................................................
  2333   2340         case RBU_STATE_OALSZ:
  2334   2341           pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
  2335   2342           break;
  2336   2343   
  2337   2344         case RBU_STATE_PHASEONESTEP:
  2338   2345           pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
  2339   2346           break;
         2347  +
         2348  +      case RBU_STATE_DATATBL:
         2349  +        pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
         2350  +        break;
  2340   2351   
  2341   2352         default:
  2342   2353           rc = SQLITE_CORRUPT;
  2343   2354           break;
  2344   2355       }
  2345   2356     }
  2346   2357     rc2 = sqlite3_finalize(pStmt);
................................................................................
  3108   3119             "(%d, %Q), "
  3109   3120             "(%d, %Q), "
  3110   3121             "(%d, %d), "
  3111   3122             "(%d, %d), "
  3112   3123             "(%d, %lld), "
  3113   3124             "(%d, %lld), "
  3114   3125             "(%d, %lld), "
  3115         -          "(%d, %lld) ",
         3126  +          "(%d, %lld), "
         3127  +          "(%d, %Q)  ",
  3116   3128             p->zStateDb,
  3117   3129             RBU_STATE_STAGE, eStage,
  3118   3130             RBU_STATE_TBL, p->objiter.zTbl, 
  3119   3131             RBU_STATE_IDX, p->objiter.zIdx, 
  3120   3132             RBU_STATE_ROW, p->nStep, 
  3121   3133             RBU_STATE_PROGRESS, p->nProgress,
  3122   3134             RBU_STATE_CKPT, p->iWalCksum,
  3123   3135             RBU_STATE_COOKIE, (i64)pFd->iCookie,
  3124   3136             RBU_STATE_OALSZ, p->iOalSz,
  3125         -          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
         3137  +          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep,
         3138  +          RBU_STATE_DATATBL, p->objiter.zDataTbl
  3126   3139         )
  3127   3140       );
  3128   3141       assert( pInsert==0 || rc==SQLITE_OK );
  3129   3142   
  3130   3143       if( rc==SQLITE_OK ){
  3131   3144         sqlite3_step(pInsert);
  3132   3145         rc = sqlite3_finalize(pInsert);
................................................................................
  3374   3387     assert( p->rc==SQLITE_OK );
  3375   3388     if( pState->zTbl ){
  3376   3389       RbuObjIter *pIter = &p->objiter;
  3377   3390       int rc = SQLITE_OK;
  3378   3391   
  3379   3392       while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup 
  3380   3393          || rbuStrCompare(pIter->zIdx, pState->zIdx)
  3381         -       || rbuStrCompare(pIter->zTbl, pState->zTbl) 
         3394  +       || (pState->zDataTbl==0 && rbuStrCompare(pIter->zTbl, pState->zTbl))
         3395  +       || (pState->zDataTbl && rbuStrCompare(pIter->zDataTbl, pState->zDataTbl))
  3382   3396       )){
  3383   3397         rc = rbuObjIterNext(p, pIter);
  3384   3398       }
  3385   3399   
  3386   3400       if( rc==SQLITE_OK && !pIter->zTbl ){
  3387   3401         rc = SQLITE_ERROR;
  3388   3402         p->zErrmsg = sqlite3_mprintf("rbu_state mismatch error");

Changes to ext/rtree/rtree.c.

  3490   3490     ** that is successful, call sqlite3_declare_vtab() to configure
  3491   3491     ** the r-tree table schema.
  3492   3492     */
  3493   3493     if( rc==SQLITE_OK ){
  3494   3494       if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
  3495   3495         *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
  3496   3496       }else{
  3497         -      char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
  3498         -      char *zTmp;
         3497  +      sqlite3_str *pSql = sqlite3_str_new(db);
         3498  +      char *zSql;
  3499   3499         int ii;
  3500         -      for(ii=4; zSql && ii<argc; ii++){
  3501         -        zTmp = zSql;
  3502         -        zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
  3503         -        sqlite3_free(zTmp);
  3504         -      }
  3505         -      if( zSql ){
  3506         -        zTmp = zSql;
  3507         -        zSql = sqlite3_mprintf("%s);", zTmp);
  3508         -        sqlite3_free(zTmp);
         3500  +      if( pSql==0 ){
         3501  +        zSql = 0;
         3502  +      }else{
         3503  +        sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]);
         3504  +        for(ii=4; ii<argc; ii++){
         3505  +          sqlite3_str_appendf(pSql, ", %s", argv[ii]);
         3506  +        }
         3507  +        sqlite3_str_appendf(pSql, ");");
         3508  +        zSql = sqlite3_str_finish(pSql);
  3509   3509         }
  3510   3510         if( !zSql ){
  3511   3511           rc = SQLITE_NOMEM;
  3512   3512         }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
  3513   3513           *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
  3514   3514         }
  3515   3515         sqlite3_free(zSql);

Changes to ext/rtree/rtree6.test.

    70     70   do_test rtree6-1.5 {
    71     71     rtree_strategy {SELECT * FROM t1,t2 WHERE k=+ii AND x1<10}
    72     72   } {C0}
    73     73   
    74     74   do_eqp_test rtree6.2.1 {
    75     75     SELECT * FROM t1,t2 WHERE k=+ii AND x1<10
    76     76   } {
    77         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} 
    78         -  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
           77  +  QUERY PLAN
           78  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0
           79  +  `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
    79     80   }
    80     81   
    81     82   do_eqp_test rtree6.2.2 {
    82     83     SELECT * FROM t1,t2 WHERE k=ii AND x1<10
    83     84   } {
    84         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} 
    85         -  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
           85  +  QUERY PLAN
           86  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0
           87  +  `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
    86     88   }
    87     89   
    88     90   do_eqp_test rtree6.2.3 {
    89     91     SELECT * FROM t1,t2 WHERE k=ii
    90     92   } {
    91         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:} 
    92         -  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
           93  +  QUERY PLAN
           94  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:
           95  +  `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
    93     96   }
    94     97   
    95     98   do_eqp_test rtree6.2.4.1 {
    96     99     SELECT * FROM t1,t2 WHERE v=+ii and x1<10 and x2>10
    97    100   } {
    98         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1} 
    99         -  0 1 1 {SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)}
          101  +  QUERY PLAN
          102  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1
          103  +  `--SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)
   100    104   }
   101    105   do_eqp_test rtree6.2.4.2 {
   102    106     SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10
   103    107   } {
   104         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1} 
   105         -  0 1 1 {SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?)}
          108  +  QUERY PLAN
          109  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1
          110  +  `--SEARCH TABLE t2 USING AUTOMATIC PARTIAL COVERING INDEX (v=?)
   106    111   }
   107    112   
   108    113   do_eqp_test rtree6.2.5 {
   109    114     SELECT * FROM t1,t2 WHERE k=ii AND x1<v
   110    115   } {
   111         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:} 
   112         -  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
          116  +  QUERY PLAN
          117  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 2:
          118  +  `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
   113    119   }
   114    120   
   115    121   do_execsql_test rtree6-3.1 {
   116    122     CREATE VIRTUAL TABLE t3 USING rtree(id, x1, x2, y1, y2);
   117    123     INSERT INTO t3 VALUES(NULL, 1, 1, 2, 2);
   118    124     SELECT * FROM t3 WHERE 
   119    125       x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 

Changes to ext/rtree/rtreeC.test.

    25     25     CREATE TABLE t(x, y);
    26     26   }
    27     27   
    28     28   do_eqp_test 1.1 {
    29     29     SELECT * FROM r_tree, t 
    30     30     WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
    31     31   } {
    32         -  0 0 1 {SCAN TABLE t}
    33         -  0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
           32  +  QUERY PLAN
           33  +  |--SCAN TABLE t
           34  +  `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
    34     35   }
    35     36   
    36     37   do_eqp_test 1.2 {
    37     38     SELECT * FROM t, r_tree
    38     39     WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
    39     40   } {
    40         -  0 0 0 {SCAN TABLE t}
    41         -  0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
           41  +  QUERY PLAN
           42  +  |--SCAN TABLE t
           43  +  `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
    42     44   }
    43     45   
    44     46   do_eqp_test 1.3 {
    45     47     SELECT * FROM t, r_tree
    46     48     WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y
    47     49   } {
    48         -  0 0 0 {SCAN TABLE t}
    49         -  0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
           50  +  QUERY PLAN
           51  +  |--SCAN TABLE t
           52  +  `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
    50     53   }
    51     54   
    52     55   do_eqp_test 1.5 {
    53     56     SELECT * FROM t, r_tree
    54     57   } {
    55         -  0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:}
    56         -  0 1 0 {SCAN TABLE t} 
           58  +  QUERY PLAN
           59  +  |--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:
           60  +  `--SCAN TABLE t
    57     61   }
    58     62   
    59     63   do_execsql_test 2.0 {
    60     64     INSERT INTO t VALUES(0, 0);
    61     65     INSERT INTO t VALUES(0, 1);
    62     66     INSERT INTO t VALUES(0, 2);
    63     67     INSERT INTO t VALUES(0, 3);
................................................................................
    78     82   db close
    79     83   sqlite3 db test.db
    80     84   
    81     85   do_eqp_test 2.1 {
    82     86     SELECT * FROM r_tree, t 
    83     87     WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
    84     88   } {
    85         -  0 0 1 {SCAN TABLE t}
    86         -  0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
           89  +  QUERY PLAN
           90  +  |--SCAN TABLE t
           91  +  `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
    87     92   }
    88     93   
    89     94   do_eqp_test 2.2 {
    90     95     SELECT * FROM t, r_tree
    91     96     WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y
    92     97   } {
    93         -  0 0 0 {SCAN TABLE t}
    94         -  0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
           98  +  QUERY PLAN
           99  +  |--SCAN TABLE t
          100  +  `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
    95    101   }
    96    102   
    97    103   do_eqp_test 2.3 {
    98    104     SELECT * FROM t, r_tree
    99    105     WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y
   100    106   } {
   101         -  0 0 0 {SCAN TABLE t}
   102         -  0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0}
          107  +  QUERY PLAN
          108  +  |--SCAN TABLE t
          109  +  `--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0
   103    110   }
   104    111   
   105    112   do_eqp_test 2.5 {
   106    113     SELECT * FROM t, r_tree
   107    114   } {
   108         -  0 0 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:}
   109         -  0 1 0 {SCAN TABLE t} 
          115  +  QUERY PLAN
          116  +  |--SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:
          117  +  `--SCAN TABLE t
   110    118   }
   111    119   
   112    120   #-------------------------------------------------------------------------
   113    121   # Test that the special CROSS JOIN handling works with rtree tables.
   114    122   #
   115    123   do_execsql_test 3.1 {
   116    124     CREATE TABLE t1(x);
   117    125     CREATE TABLE t2(y);
   118    126     CREATE VIRTUAL TABLE t3 USING rtree(z, x1,x2, y1,y2);
   119    127   }
   120    128   
   121    129   do_eqp_test 3.2.1 { SELECT * FROM t1 CROSS JOIN t2 } {
   122         -  0 0 0 {SCAN TABLE t1} 
   123         -  0 1 1 {SCAN TABLE t2}
          130  +  QUERY PLAN
          131  +  |--SCAN TABLE t1
          132  +  `--SCAN TABLE t2
   124    133   }
   125    134   do_eqp_test 3.2.2 { SELECT * FROM t2 CROSS JOIN t1 } {
   126         -  0 0 0 {SCAN TABLE t2} 0 1 1 {SCAN TABLE t1}
          135  +  QUERY PLAN
          136  +  |--SCAN TABLE t2
          137  +  `--SCAN TABLE t1
   127    138   }
   128    139   
   129    140   do_eqp_test 3.3.1 { SELECT * FROM t1 CROSS JOIN t3 } {
   130         -  0 0 0 {SCAN TABLE t1}
   131         -  0 1 1 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:} 
          141  +  QUERY PLAN
          142  +  |--SCAN TABLE t1
          143  +  `--SCAN TABLE t3 VIRTUAL TABLE INDEX 2:
   132    144   }
   133    145   do_eqp_test 3.3.2 { SELECT * FROM t3 CROSS JOIN t1 } {
   134         -  0 0 0 {SCAN TABLE t3 VIRTUAL TABLE INDEX 2:} 
   135         -  0 1 1 {SCAN TABLE t1}
          146  +  QUERY PLAN
          147  +  |--SCAN TABLE t3 VIRTUAL TABLE INDEX 2:
          148  +  `--SCAN TABLE t1
   136    149   }
   137    150   
   138    151   #--------------------------------------------------------------------
   139    152   # Test that LEFT JOINs are not reordered if the right-hand-side is
   140    153   # a virtual table.
   141    154   #
   142    155   reset_db
................................................................................
   185    198   
   186    199   # First test a query with no ANALYZE data at all. The outer loop is
   187    200   # real table "t1".
   188    201   #
   189    202   do_eqp_test 5.2 {
   190    203     SELECT * FROM t1, rt WHERE x==id;
   191    204   } {
   192         -  0 0 0 {SCAN TABLE t1} 
   193         -  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
          205  +  QUERY PLAN
          206  +  |--SCAN TABLE t1
          207  +  `--SCAN TABLE rt VIRTUAL TABLE INDEX 1:
   194    208   }
   195    209   
   196    210   # Now create enough ANALYZE data to tell SQLite that virtual table "rt"
   197    211   # contains very few rows. This causes it to move "rt" to the outer loop.
   198    212   #
   199    213   do_execsql_test 5.3 {
   200    214     ANALYZE;
................................................................................
   201    215     DELETE FROM sqlite_stat1 WHERE tbl='t1';
   202    216   }
   203    217   db close
   204    218   sqlite3 db test.db
   205    219   do_eqp_test 5.4 {
   206    220     SELECT * FROM t1, rt WHERE x==id;
   207    221   } {
   208         -  0 0 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:} 
   209         -  0 1 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)}
          222  +  QUERY PLAN
          223  +  |--SCAN TABLE rt VIRTUAL TABLE INDEX 2:
          224  +  `--SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)
   210    225   }
   211    226   
   212    227   # Delete the ANALYZE data. "t1" should be the outer loop again.
   213    228   #
   214    229   do_execsql_test 5.5 { DROP TABLE sqlite_stat1; }
   215    230   db close
   216    231   sqlite3 db test.db
   217    232   do_eqp_test 5.6 {
   218    233     SELECT * FROM t1, rt WHERE x==id;
   219    234   } {
   220         -  0 0 0 {SCAN TABLE t1} 
   221         -  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
          235  +  QUERY PLAN
          236  +  |--SCAN TABLE t1
          237  +  `--SCAN TABLE rt VIRTUAL TABLE INDEX 1:
   222    238   }
   223    239   
   224    240   # This time create and attach a database that contains ANALYZE data for
   225    241   # tables of the same names as those used internally by virtual table
   226    242   # "rt". Check that the rtree module is not fooled into using this data.
   227    243   # Table "t1" should remain the outer loop.
   228    244   #
................................................................................
   237    253     db close
   238    254     sqlite3 db test.db
   239    255     execsql { ATTACH 'test.db2' AS aux; }
   240    256   } {}
   241    257   do_eqp_test 5.8 {
   242    258     SELECT * FROM t1, rt WHERE x==id;
   243    259   } {
   244         -  0 0 0 {SCAN TABLE t1} 
   245         -  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
          260  +  QUERY PLAN
          261  +  |--SCAN TABLE t1
          262  +  `--SCAN TABLE rt VIRTUAL TABLE INDEX 1:
   246    263   }
   247    264   
   248    265   #--------------------------------------------------------------------
   249    266   # Test that having a second connection drop the sqlite_stat1 table
   250    267   # before it is required by rtreeConnect() does not cause problems.
   251    268   #
   252    269   ifcapable rtree {
................................................................................
   295    312     INSERT INTO rt VALUES(1, 2, 7, 12, 14);      -- Not a hit
   296    313     INSERT INTO rt VALUES(2, 2, 7, 8, 12);       -- A hit!
   297    314     INSERT INTO rt VALUES(3, 7, 11, 8, 12);      -- Not a hit!
   298    315     INSERT INTO rt VALUES(4, 5, 5, 10, 10);      -- A hit!
   299    316   
   300    317   }
   301    318   
   302         -proc do_eqp_execsql_test {tn sql res} {
   303         -  set query "EXPLAIN QUERY PLAN $sql ; $sql "
   304         -  uplevel [list do_execsql_test $tn $query $res]
          319  +proc do_eqp_execsql_test {tn sql res1 res2} {
          320  +  do_eqp_test $tn.1 $sql $res1
          321  +  do_execsql_test $tn.2 $sql $res2
   305    322   }
   306    323   
   307    324   do_eqp_execsql_test 7.1 {
   308    325     SELECT id FROM xdir, rt, ydir 
   309    326     ON (y1 BETWEEN ymin AND ymax)
   310    327     WHERE (x1 BETWEEN xmin AND xmax);
   311    328   } {
   312         -  0 0 0 {SCAN TABLE xdir} 
   313         -  0 1 2 {SCAN TABLE ydir} 
   314         -  0 2 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1}
          329  +  QUERY PLAN
          330  +  |--SCAN TABLE xdir
          331  +  |--SCAN TABLE ydir
          332  +  `--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B2D3B0D1
          333  +} {
   315    334     2 4
   316    335   }
   317    336   
   318    337   do_eqp_execsql_test 7.2 {
   319    338     SELECT * FROM xdir, rt LEFT JOIN ydir 
   320    339     ON (y1 BETWEEN ymin AND ymax)
   321    340     WHERE (x1 BETWEEN xmin AND xmax);
   322    341   } {
   323         -  0 0 0 {SCAN TABLE xdir} 
   324         -  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
   325         -  0 2 2 {SCAN TABLE ydir} 
   326         -
          342  +  QUERY PLAN
          343  +  |--SCAN TABLE xdir
          344  +  |--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1
          345  +  `--SCAN TABLE ydir
          346  +} {
   327    347     5 1 2 7 12 14 {}
   328    348     5 2 2 7  8 12 10
   329    349     5 4 5 5 10 10 10
   330    350   }
   331    351   
   332    352   do_eqp_execsql_test 7.3 {
   333    353     SELECT id FROM xdir, rt CROSS JOIN ydir 
   334    354     ON (y1 BETWEEN ymin AND ymax)
   335    355     WHERE (x1 BETWEEN xmin AND xmax);
   336    356   } {
   337         -  0 0 0 {SCAN TABLE xdir} 
   338         -  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
   339         -  0 2 2 {SCAN TABLE ydir} 
          357  +  QUERY PLAN
          358  +  |--SCAN TABLE xdir
          359  +  |--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1
          360  +  `--SCAN TABLE ydir
          361  +} {
   340    362     2 4
   341    363   }
   342    364   
   343    365   do_eqp_execsql_test 7.4 {
   344    366     SELECT id FROM rt, xdir CROSS JOIN ydir 
   345    367     ON (y1 BETWEEN ymin AND ymax)
   346    368     WHERE (x1 BETWEEN xmin AND xmax);
   347    369   } {
   348         -  0 0 1 {SCAN TABLE xdir} 
   349         -  0 1 0 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
   350         -  0 2 2 {SCAN TABLE ydir} 
          370  +  QUERY PLAN
          371  +  |--SCAN TABLE xdir
          372  +  |--SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1
          373  +  `--SCAN TABLE ydir
          374  +} {
   351    375     2 4
   352    376   }
   353    377   
   354    378   finish_test

Changes to main.mk.

   498    498   # Databases containing fuzzer test cases
   499    499   #
   500    500   FUZZDATA = \
   501    501     $(TOP)/test/fuzzdata1.db \
   502    502     $(TOP)/test/fuzzdata2.db \
   503    503     $(TOP)/test/fuzzdata3.db \
   504    504     $(TOP)/test/fuzzdata4.db \
   505         -  $(TOP)/test/fuzzdata5.db
          505  +  $(TOP)/test/fuzzdata5.db \
          506  +  $(TOP)/test/fuzzdata6.db
   506    507   
   507    508   # Standard options to testfixture
   508    509   #
   509    510   TESTOPTS = --verbose=file --output=test-out.txt
   510    511   
   511    512   # Extra compiler options for various shell tools
   512    513   #

Changes to src/btree.c.

  3181   3181             pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
  3182   3182       }
  3183   3183     }
  3184   3184   }
  3185   3185   #else
  3186   3186   # define setDefaultSyncFlag(pBt,safety_level)
  3187   3187   #endif
         3188  +
         3189  +/* Forward declaration */
         3190  +static int newDatabase(BtShared*);
         3191  +
  3188   3192   
  3189   3193   /*
  3190   3194   ** Get a reference to pPage1 of the database file.  This will
  3191   3195   ** also acquire a readlock on that file.
  3192   3196   **
  3193   3197   ** SQLITE_OK is returned on success.  If the file is not a
  3194   3198   ** well-formed database file, then SQLITE_CORRUPT is returned.
................................................................................
  3212   3216     /* Do some checking to help insure the file we opened really is
  3213   3217     ** a valid database file. 
  3214   3218     */
  3215   3219     nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
  3216   3220     sqlite3PagerPagecount(pBt->pPager, &nPageFile);
  3217   3221     if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
  3218   3222       nPage = nPageFile;
         3223  +  }
         3224  +  if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){
         3225  +    nPage = 0;
  3219   3226     }
  3220   3227     if( nPage>0 ){
  3221   3228       u32 pageSize;
  3222   3229       u32 usableSize;
  3223   3230       u8 *page1 = pPage1->aData;
  3224   3231       rc = SQLITE_NOTADB;
  3225   3232       /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
................................................................................
  6639   6646     u32 ovflPageSize;
  6640   6647   
  6641   6648     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  6642   6649     pPage->xParseCell(pPage, pCell, pInfo);
  6643   6650     if( pInfo->nLocal==pInfo->nPayload ){
  6644   6651       return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  6645   6652     }
  6646         -  if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
         6653  +  testcase( pCell + pInfo->nSize == pPage->aDataEnd );
         6654  +  testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd );
         6655  +  if( pCell + pInfo->nSize > pPage->aDataEnd ){
  6647   6656       /* Cell extends past end of page */
  6648   6657       return SQLITE_CORRUPT_PAGE(pPage);
  6649   6658     }
  6650   6659     ovflPgno = get4byte(pCell + pInfo->nSize - 4);
  6651   6660     pBt = pPage->pBt;
  6652   6661     assert( pBt->usableSize > 4 );
  6653   6662     ovflPageSize = pBt->usableSize - 4;
................................................................................
  8566   8575   
  8567   8576     if( pFree ){
  8568   8577       sqlite3PageFree(pFree);
  8569   8578     }
  8570   8579     return rc;
  8571   8580   }
  8572   8581   
         8582  +/* Overwrite content from pX into pDest.  Only do the write if the
         8583  +** content is different from what is already there.
         8584  +*/
         8585  +static int btreeOverwriteContent(
         8586  +  MemPage *pPage,           /* MemPage on which writing will occur */
         8587  +  u8 *pDest,                /* Pointer to the place to start writing */
         8588  +  const BtreePayload *pX,   /* Source of data to write */
         8589  +  int iOffset,              /* Offset of first byte to write */
         8590  +  int iAmt                  /* Number of bytes to be written */
         8591  +){
         8592  +  int nData = pX->nData - iOffset;
         8593  +  if( nData<=0 ){
         8594  +    /* Overwritting with zeros */
         8595  +    int i;
         8596  +    for(i=0; i<iAmt && pDest[i]==0; i++){}
         8597  +    if( i<iAmt ){
         8598  +      int rc = sqlite3PagerWrite(pPage->pDbPage);
         8599  +      if( rc ) return rc;
         8600  +      memset(pDest + i, 0, iAmt - i);
         8601  +    }
         8602  +  }else{
         8603  +    if( nData<iAmt ){
         8604  +      /* Mixed read data and zeros at the end.  Make a recursive call
         8605  +      ** to write the zeros then fall through to write the real data */
         8606  +      int rc = btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData,
         8607  +                                 iAmt-nData);
         8608  +      if( rc ) return rc;
         8609  +      iAmt = nData;
         8610  +    }
         8611  +    if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){
         8612  +      int rc = sqlite3PagerWrite(pPage->pDbPage);
         8613  +      if( rc ) return rc;
         8614  +      memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt);
         8615  +    }
         8616  +  }
         8617  +  return SQLITE_OK;
         8618  +}
         8619  +
         8620  +/*
         8621  +** Overwrite the cell that cursor pCur is pointing to with fresh content
         8622  +** contained in pX.
         8623  +*/
         8624  +static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
         8625  +  int iOffset;                        /* Next byte of pX->pData to write */
         8626  +  int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */
         8627  +  int rc;                             /* Return code */
         8628  +  MemPage *pPage = pCur->pPage;       /* Page being written */
         8629  +  BtShared *pBt;                      /* Btree */
         8630  +  Pgno ovflPgno;                      /* Next overflow page to write */
         8631  +  u32 ovflPageSize;                   /* Size to write on overflow page */
         8632  +
         8633  +  if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){
         8634  +    return SQLITE_CORRUPT_BKPT;
         8635  +  }
         8636  +  /* Overwrite the local portion first */
         8637  +  rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
         8638  +                             0, pCur->info.nLocal);
         8639  +  if( rc ) return rc;
         8640  +  if( pCur->info.nLocal==nTotal ) return SQLITE_OK;
         8641  +
         8642  +  /* Now overwrite the overflow pages */
         8643  +  iOffset = pCur->info.nLocal;
         8644  +  assert( nTotal>=0 );
         8645  +  assert( iOffset>=0 );
         8646  +  ovflPgno = get4byte(pCur->info.pPayload + iOffset);
         8647  +  pBt = pPage->pBt;
         8648  +  ovflPageSize = pBt->usableSize - 4;
         8649  +  do{
         8650  +    rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
         8651  +    if( rc ) return rc;
         8652  +    if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){
         8653  +      rc = SQLITE_CORRUPT_BKPT;
         8654  +    }else{
         8655  +      if( iOffset+ovflPageSize<(u32)nTotal ){
         8656  +        ovflPgno = get4byte(pPage->aData);
         8657  +      }else{
         8658  +        ovflPageSize = nTotal - iOffset;
         8659  +      }
         8660  +      rc = btreeOverwriteContent(pPage, pPage->aData+4, pX,
         8661  +                                 iOffset, ovflPageSize);
         8662  +    }
         8663  +    sqlite3PagerUnref(pPage->pDbPage);
         8664  +    if( rc ) return rc;
         8665  +    iOffset += ovflPageSize;
         8666  +  }while( iOffset<nTotal );
         8667  +  return SQLITE_OK;    
         8668  +}
         8669  +
  8573   8670   
  8574   8671   /*
  8575   8672   ** Insert a new record into the BTree.  The content of the new record
  8576   8673   ** is described by the pX object.  The pCur cursor is used only to
  8577   8674   ** define what table the record should be inserted into, and is left
  8578   8675   ** pointing at a random location.
  8579   8676   **
................................................................................
  8656   8753     if( pCur->pKeyInfo==0 ){
  8657   8754       assert( pX->pKey==0 );
  8658   8755       /* If this is an insert into a table b-tree, invalidate any incrblob 
  8659   8756       ** cursors open on the row being replaced */
  8660   8757       invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
  8661   8758   
  8662   8759       /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
  8663         -    ** to a row with the same key as the new entry being inserted.  */
  8664         -    assert( (flags & BTREE_SAVEPOSITION)==0 || 
  8665         -            ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) );
         8760  +    ** to a row with the same key as the new entry being inserted.
         8761  +    */
         8762  +#ifdef SQLITE_DEBUG
         8763  +    if( flags & BTREE_SAVEPOSITION ){
         8764  +      assert( pCur->curFlags & BTCF_ValidNKey );
         8765  +      assert( pX->nKey==pCur->info.nKey );
         8766  +      assert( pCur->info.nSize!=0 );
         8767  +      assert( loc==0 );
         8768  +    }
         8769  +#endif
  8666   8770   
  8667         -    /* If the cursor is currently on the last row and we are appending a
  8668         -    ** new row onto the end, set the "loc" to avoid an unnecessary
  8669         -    ** btreeMoveto() call */
         8771  +    /* On the other hand, BTREE_SAVEPOSITION==0 does not imply
         8772  +    ** that the cursor is not pointing to a row to be overwritten.
         8773  +    ** So do a complete check.
         8774  +    */
  8670   8775       if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
  8671         -      loc = 0;
         8776  +      /* The cursor is pointing to the entry that is to be
         8777  +      ** overwritten */
         8778  +      assert( pX->nData>=0 && pX->nZero>=0 );
         8779  +      if( pCur->info.nSize!=0
         8780  +       && pCur->info.nPayload==(u32)pX->nData+pX->nZero
         8781  +      ){
         8782  +        /* New entry is the same size as the old.  Do an overwrite */
         8783  +        return btreeOverwriteCell(pCur, pX);
         8784  +      }
         8785  +      assert( loc==0 );
  8672   8786       }else if( loc==0 ){
         8787  +      /* The cursor is *not* pointing to the cell to be overwritten, nor
         8788  +      ** to an adjacent cell.  Move the cursor so that it is pointing either
         8789  +      ** to the cell to be overwritten or an adjacent cell.
         8790  +      */
  8673   8791         rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
  8674   8792         if( rc ) return rc;
  8675   8793       }
  8676         -  }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
  8677         -    if( pX->nMem ){
  8678         -      UnpackedRecord r;
  8679         -      r.pKeyInfo = pCur->pKeyInfo;
  8680         -      r.aMem = pX->aMem;
  8681         -      r.nField = pX->nMem;
  8682         -      r.default_rc = 0;
  8683         -      r.errCode = 0;
  8684         -      r.r1 = 0;
  8685         -      r.r2 = 0;
  8686         -      r.eqSeen = 0;
  8687         -      rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
  8688         -    }else{
  8689         -      rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
  8690         -    }
  8691         -    if( rc ) return rc;
         8794  +  }else{
         8795  +    /* This is an index or a WITHOUT ROWID table */
         8796  +
         8797  +    /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
         8798  +    ** to a row with the same key as the new entry being inserted.
         8799  +    */
         8800  +    assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 );
         8801  +
         8802  +    /* If the cursor is not already pointing either to the cell to be
         8803  +    ** overwritten, or if a new cell is being inserted, if the cursor is
         8804  +    ** not pointing to an immediately adjacent cell, then move the cursor
         8805  +    ** so that it does.
         8806  +    */
         8807  +    if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
         8808  +      if( pX->nMem ){
         8809  +        UnpackedRecord r;
         8810  +        r.pKeyInfo = pCur->pKeyInfo;
         8811  +        r.aMem = pX->aMem;
         8812  +        r.nField = pX->nMem;
         8813  +        r.default_rc = 0;
         8814  +        r.errCode = 0;
         8815  +        r.r1 = 0;
         8816  +        r.r2 = 0;
         8817  +        r.eqSeen = 0;
         8818  +        rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
         8819  +      }else{
         8820  +        rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
         8821  +      }
         8822  +      if( rc ) return rc;
         8823  +    }
         8824  +
         8825  +    /* If the cursor is currently pointing to an entry to be overwritten
         8826  +    ** and the new content is the same as as the old, then use the
         8827  +    ** overwrite optimization.
         8828  +    */
         8829  +    if( loc==0 ){
         8830  +      getCellInfo(pCur);
         8831  +      if( pCur->info.nKey==pX->nKey ){
         8832  +        BtreePayload x2;
         8833  +        x2.pData = pX->pKey;
         8834  +        x2.nData = pX->nKey;
         8835  +        x2.nZero = 0;
         8836  +        return btreeOverwriteCell(pCur, &x2);
         8837  +      }
         8838  +    }
         8839  +
  8692   8840     }
  8693   8841     assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
  8694   8842   
  8695   8843     pPage = pCur->pPage;
  8696   8844     assert( pPage->intKey || pX->nKey>=0 );
  8697   8845     assert( pPage->leaf || !pPage->intKey );
  8698   8846   
................................................................................
  9527   9675   ){
  9528   9676     va_list ap;
  9529   9677     if( !pCheck->mxErr ) return;
  9530   9678     pCheck->mxErr--;
  9531   9679     pCheck->nErr++;
  9532   9680     va_start(ap, zFormat);
  9533   9681     if( pCheck->errMsg.nChar ){
  9534         -    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
         9682  +    sqlite3_str_append(&pCheck->errMsg, "\n", 1);
  9535   9683     }
  9536   9684     if( pCheck->zPfx ){
  9537         -    sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
         9685  +    sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
  9538   9686     }
  9539         -  sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
         9687  +  sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
  9540   9688     va_end(ap);
  9541         -  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
         9689  +  if( pCheck->errMsg.accError==SQLITE_NOMEM ){
  9542   9690       pCheck->mallocFailed = 1;
  9543   9691     }
  9544   9692   }
  9545   9693   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  9546   9694   
  9547   9695   #ifndef SQLITE_OMIT_INTEGRITY_CHECK
  9548   9696   
................................................................................
 10120  10268   
 10121  10269     /* Clean  up and report errors.
 10122  10270     */
 10123  10271   integrity_ck_cleanup:
 10124  10272     sqlite3PageFree(sCheck.heap);
 10125  10273     sqlite3_free(sCheck.aPgRef);
 10126  10274     if( sCheck.mallocFailed ){
 10127         -    sqlite3StrAccumReset(&sCheck.errMsg);
        10275  +    sqlite3_str_reset(&sCheck.errMsg);
 10128  10276       sCheck.nErr++;
 10129  10277     }
 10130  10278     *pnErr = sCheck.nErr;
 10131         -  if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
        10279  +  if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
 10132  10280     /* Make sure this analysis did not leave any unref() pages. */
 10133  10281     assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
 10134  10282     sqlite3BtreeLeave(p);
 10135  10283     return sqlite3StrAccumFinish(&sCheck.errMsg);
 10136  10284   }
 10137  10285   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
 10138  10286   

Changes to src/btree.h.

   255    255   #define BTREE_AUXDELETE    0x04  /* not the primary delete operation */
   256    256   #define BTREE_APPEND       0x08  /* Insert is likely an append */
   257    257   
   258    258   /* An instance of the BtreePayload object describes the content of a single
   259    259   ** entry in either an index or table btree.
   260    260   **
   261    261   ** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
   262         -** an arbitrary key and no data.  These btrees have pKey,nKey set to their
   263         -** key and pData,nData,nZero set to zero.
          262  +** an arbitrary key and no data.  These btrees have pKey,nKey set to the
          263  +** key and the pData,nData,nZero fields are uninitialized.  The aMem,nMem
          264  +** fields give an array of Mem objects that are a decomposition of the key.
          265  +** The nMem field might be zero, indicating that no decomposition is available.
   264    266   **
   265    267   ** Table btrees (used for rowid tables) contain an integer rowid used as
   266    268   ** the key and passed in the nKey field.  The pKey field is zero.  
   267    269   ** pData,nData hold the content of the new entry.  nZero extra zero bytes
   268    270   ** are appended to the end of the content when constructing the entry.
          271  +** The aMem,nMem fields are uninitialized for table btrees.
          272  +**
          273  +** Field usage summary:
          274  +**
          275  +**               Table BTrees                   Index Btrees
          276  +**
          277  +**   pKey        always NULL                    encoded key
          278  +**   nKey        the ROWID                      length of pKey
          279  +**   pData       data                           not used
          280  +**   aMem        not used                       decomposed key value
          281  +**   nMem        not used                       entries in aMem
          282  +**   nData       length of pData                not used
          283  +**   nZero       extra zeros after pData        not used
   269    284   **
   270    285   ** This object is used to pass information into sqlite3BtreeInsert().  The
   271    286   ** same information used to be passed as five separate parameters.  But placing
   272    287   ** the information into this object helps to keep the interface more 
   273    288   ** organized and understandable, and it also helps the resulting code to
   274    289   ** run a little faster by using fewer registers for parameter passing.
   275    290   */
   276    291   struct BtreePayload {
   277    292     const void *pKey;       /* Key content for indexes.  NULL for tables */
   278    293     sqlite3_int64 nKey;     /* Size of pKey for indexes.  PRIMARY KEY for tabs */
   279         -  const void *pData;      /* Data for tables.  NULL for indexes */
          294  +  const void *pData;      /* Data for tables. */
   280    295     sqlite3_value *aMem;    /* First of nMem value in the unpacked pKey */
   281    296     u16 nMem;               /* Number of aMem[] value.  Might be zero */
   282    297     int nData;              /* Size of pData.  0 if none. */
   283    298     int nZero;              /* Extra zero data appended after pData,nData */
   284    299   };
   285    300   
   286    301   int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,

Changes to src/build.c.

  3022   3022     assert( pTab!=0 );
  3023   3023     assert( pParse->nErr==0 );
  3024   3024     if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
  3025   3025          && db->init.busy==0
  3026   3026   #if SQLITE_USER_AUTHENTICATION
  3027   3027          && sqlite3UserAuthTable(pTab->zName)==0
  3028   3028   #endif
  3029         -       && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
         3029  +#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX
         3030  +       && sqlite3StrICmp(&pTab->zName[7],"master")!=0
         3031  +#endif
         3032  +       && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0
         3033  + ){
  3030   3034       sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
  3031   3035       goto exit_create_index;
  3032   3036     }
  3033   3037   #ifndef SQLITE_OMIT_VIEW
  3034   3038     if( pTab->pSelect ){
  3035   3039       sqlite3ErrorMsg(pParse, "views may not be indexed");
  3036   3040       goto exit_create_index;
................................................................................
  4201   4205     char *zErr;
  4202   4206     int j;
  4203   4207     StrAccum errMsg;
  4204   4208     Table *pTab = pIdx->pTable;
  4205   4209   
  4206   4210     sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
  4207   4211     if( pIdx->aColExpr ){
  4208         -    sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
         4212  +    sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
  4209   4213     }else{
  4210   4214       for(j=0; j<pIdx->nKeyCol; j++){
  4211   4215         char *zCol;
  4212   4216         assert( pIdx->aiColumn[j]>=0 );
  4213   4217         zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
  4214         -      if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
  4215         -      sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
  4216         -      sqlite3StrAccumAppend(&errMsg, ".", 1);
  4217         -      sqlite3StrAccumAppendAll(&errMsg, zCol);
         4218  +      if( j ) sqlite3_str_append(&errMsg, ", ", 2);
         4219  +      sqlite3_str_appendall(&errMsg, pTab->zName);
         4220  +      sqlite3_str_append(&errMsg, ".", 1);
         4221  +      sqlite3_str_appendall(&errMsg, zCol);
  4218   4222       }
  4219   4223     }
  4220   4224     zErr = sqlite3StrAccumFinish(&errMsg);
  4221   4225     sqlite3HaltConstraint(pParse, 
  4222   4226       IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY 
  4223   4227                               : SQLITE_CONSTRAINT_UNIQUE,
  4224   4228       onError, zErr, P4_DYNAMIC, P5_ConstraintUnique);

Changes to src/expr.c.

  2406   2406               if( aiMap ) aiMap[i] = j;
  2407   2407             }
  2408   2408     
  2409   2409             assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
  2410   2410             if( colUsed==(MASKBIT(nExpr)-1) ){
  2411   2411               /* If we reach this point, that means the index pIdx is usable */
  2412   2412               int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  2413         -#ifndef SQLITE_OMIT_EXPLAIN
  2414         -            sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
  2415         -              sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
  2416         -              P4_DYNAMIC);
  2417         -#endif
         2413  +            ExplainQueryPlan((pParse, 0,
         2414  +                              "USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
  2418   2415               sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
  2419   2416               sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  2420   2417               VdbeComment((v, "%s", pIdx->zName));
  2421   2418               assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
  2422   2419               eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
  2423   2420     
  2424   2421               if( prRhsHasNull ){
................................................................................
  2642   2639           **
  2643   2640           ** Generate code to write the results of the select into the temporary
  2644   2641           ** table allocated and opened above.
  2645   2642           */
  2646   2643           Select *pSelect = pExpr->x.pSelect;
  2647   2644           ExprList *pEList = pSelect->pEList;
  2648   2645   
  2649         -#ifndef SQLITE_OMIT_EXPLAIN
  2650         -        if( pParse->explain==2 ){
  2651         -          char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %sLIST SUBQUERY %d",
  2652         -            jmpIfDynamic>=0?"":"CORRELATED ",
  2653         -            pParse->iNextSelectId
  2654         -          );
  2655         -          sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg,
  2656         -                            P4_DYNAMIC);
  2657         -        }
  2658         -#endif
  2659         -
         2646  +        ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
         2647  +            jmpIfDynamic>=0?"":"CORRELATED "
         2648  +        ));
  2660   2649           assert( !isRowid );
  2661   2650           /* If the LHS and RHS of the IN operator do not match, that
  2662   2651           ** error will have been caught long before we reach this point. */
  2663   2652           if( ALWAYS(pEList->nExpr==nVal) ){
  2664   2653             SelectDest dest;
  2665   2654             int i;
  2666   2655             sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
................................................................................
  2773   2762         Expr *pLimit;                         /* New limit expression */
  2774   2763   
  2775   2764         testcase( pExpr->op==TK_EXISTS );
  2776   2765         testcase( pExpr->op==TK_SELECT );
  2777   2766         assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
  2778   2767         assert( ExprHasProperty(pExpr, EP_xIsSelect) );
  2779   2768   
  2780         -#ifndef SQLITE_OMIT_EXPLAIN
  2781         -      if( pParse->explain==2 ){
  2782         -        char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %sSCALAR SUBQUERY %d",
  2783         -            jmpIfDynamic>=0?"":"CORRELATED ",
  2784         -            pParse->iNextSelectId
  2785         -        );
  2786         -        sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg,
  2787         -                          P4_DYNAMIC);
  2788         -      }
  2789         -#endif
  2790         -
  2791   2769         pSel = pExpr->x.pSelect;
         2770  +      ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
         2771  +            jmpIfDynamic>=0?"":"CORRELATED "));
  2792   2772         nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
  2793   2773         sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
  2794   2774         pParse->nMem += nReg;
  2795   2775         if( pExpr->op==TK_SELECT ){
  2796   2776           dest.eDest = SRT_Mem;
  2797   2777           dest.iSdst = dest.iSDParm;
  2798   2778           dest.nSdst = nReg;
................................................................................
  3547   3527   
  3548   3528     assert( target>0 && target<=pParse->nMem );
  3549   3529     if( v==0 ){
  3550   3530       assert( pParse->db->mallocFailed );
  3551   3531       return 0;
  3552   3532     }
  3553   3533   
         3534  +expr_code_doover:
  3554   3535     if( pExpr==0 ){
  3555   3536       op = TK_NULL;
  3556   3537     }else{
  3557   3538       op = pExpr->op;
  3558   3539     }
  3559   3540     switch( op ){
  3560   3541       case TK_AGG_COLUMN: {
................................................................................
  4007   3988       case TK_BETWEEN: {
  4008   3989         exprCodeBetween(pParse, pExpr, target, 0, 0);
  4009   3990         return target;
  4010   3991       }
  4011   3992       case TK_SPAN:
  4012   3993       case TK_COLLATE: 
  4013   3994       case TK_UPLUS: {
  4014         -      return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
         3995  +      pExpr = pExpr->pLeft;
         3996  +      goto expr_code_doover;
  4015   3997       }
  4016   3998   
  4017   3999       case TK_TRIGGER: {
  4018   4000         /* If the opcode is TK_TRIGGER, then the expression is a reference
  4019   4001         ** to a column in the new.* or old.* pseudo-tables available to
  4020   4002         ** trigger programs. In this case Expr.iTable is set to 1 for the
  4021   4003         ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn

Changes to src/func.c.

   247    247   
   248    248     if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
   249    249       x.nArg = argc-1;
   250    250       x.nUsed = 0;
   251    251       x.apArg = argv+1;
   252    252       sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
   253    253       str.printfFlags = SQLITE_PRINTF_SQLFUNC;
   254         -    sqlite3XPrintf(&str, zFormat, &x);
          254  +    sqlite3_str_appendf(&str, zFormat, &x);
   255    255       n = str.nChar;
   256    256       sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
   257    257                           SQLITE_DYNAMIC);
   258    258     }
   259    259   }
   260    260   
   261    261   /*
................................................................................
  1650   1650         if( argc==2 ){
  1651   1651           zSep = (char*)sqlite3_value_text(argv[1]);
  1652   1652           nSep = sqlite3_value_bytes(argv[1]);
  1653   1653         }else{
  1654   1654           zSep = ",";
  1655   1655           nSep = 1;
  1656   1656         }
  1657         -      if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
         1657  +      if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
  1658   1658       }
  1659   1659       zVal = (char*)sqlite3_value_text(argv[0]);
  1660   1660       nVal = sqlite3_value_bytes(argv[0]);
  1661         -    if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
         1661  +    if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
  1662   1662     }
  1663   1663   }
  1664   1664   static void groupConcatFinalize(sqlite3_context *context){
  1665   1665     StrAccum *pAccum;
  1666   1666     pAccum = sqlite3_aggregate_context(context, 0);
  1667   1667     if( pAccum ){
  1668         -    if( pAccum->accError==STRACCUM_TOOBIG ){
         1668  +    if( pAccum->accError==SQLITE_TOOBIG ){
  1669   1669         sqlite3_result_error_toobig(context);
  1670         -    }else if( pAccum->accError==STRACCUM_NOMEM ){
         1670  +    }else if( pAccum->accError==SQLITE_NOMEM ){
  1671   1671         sqlite3_result_error_nomem(context);
  1672   1672       }else{    
  1673   1673         sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
  1674   1674                             sqlite3_free);
  1675   1675       }
  1676   1676     }
  1677   1677   }

Changes to src/loadext.c.

   430    430     sqlite3_prepare16_v3,
   431    431     sqlite3_bind_pointer,
   432    432     sqlite3_result_pointer,
   433    433     sqlite3_value_pointer,
   434    434     /* Version 3.22.0 and later */
   435    435     sqlite3_vtab_nochange,
   436    436     sqlite3_value_nochange,
   437         -  sqlite3_vtab_collation
          437  +  sqlite3_vtab_collation,
          438  +  /* Version 3.24.0 and later */
          439  +  sqlite3_keyword_count,
          440  +  sqlite3_keyword_name,
          441  +  sqlite3_keyword_check,
          442  +  sqlite3_str_new,
          443  +  sqlite3_str_finish,
          444  +  sqlite3_str_appendf,
          445  +  sqlite3_str_vappendf,
          446  +  sqlite3_str_append,
          447  +  sqlite3_str_appendall,
          448  +  sqlite3_str_appendchar,
          449  +  sqlite3_str_reset,
          450  +  sqlite3_str_errcode,
          451  +  sqlite3_str_length,
          452  +  sqlite3_str_value
   438    453   };
   439    454   
   440    455   /*
   441    456   ** Attempt to load an SQLite extension library contained in the file
   442    457   ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
   443    458   ** default entry point name (sqlite3_extension_init) is used.  Use
   444    459   ** of the default name is recommended.
................................................................................
   496    511   
   497    512     zEntry = zProc ? zProc : "sqlite3_extension_init";
   498    513   
   499    514     handle = sqlite3OsDlOpen(pVfs, zFile);
   500    515   #if SQLITE_OS_UNIX || SQLITE_OS_WIN
   501    516     for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
   502    517       char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
   503         -    int bExists = 0;
   504    518       if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
   505         -    sqlite3OsAccess(pVfs, zAltFile, SQLITE_ACCESS_EXISTS, &bExists);
   506         -    if( bExists )  handle = sqlite3OsDlOpen(pVfs, zAltFile);
          519  +    handle = sqlite3OsDlOpen(pVfs, zAltFile);
   507    520       sqlite3_free(zAltFile);
   508    521     }
   509    522   #endif
   510    523     if( handle==0 ){
   511    524       if( pzErrMsg ){
   512    525         *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
   513    526         if( zErrmsg ){

Changes to src/main.c.

   830    830           { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
   831    831           { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
   832    832           { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
   833    833           { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
   834    834           { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
   835    835           { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
   836    836           { SQLITE_DBCONFIG_TRIGGER_EQP,           SQLITE_TriggerEQP     },
          837  +        { SQLITE_DBCONFIG_RESET_DATABASE,        SQLITE_ResetDatabase  },
   837    838         };
   838    839         unsigned int i;
   839    840         rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
   840    841         for(i=0; i<ArraySize(aFlagOp); i++){
   841    842           if( aFlagOp[i].op==op ){
   842    843             int onoff = va_arg(ap, int);
   843    844             int *pRes = va_arg(ap, int*);

Changes to src/mutex.c.

   354    354   int sqlite3_mutex_notheld(sqlite3_mutex *p){
   355    355     assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
   356    356     return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
   357    357   }
   358    358   #endif
   359    359   
   360    360   #endif /* !defined(SQLITE_MUTEX_OMIT) */
   361         -

Changes to src/os_win.c.

   311    311   /*
   312    312    * The size of the buffer used by sqlite3_win32_write_debug().
   313    313    */
   314    314   #ifndef SQLITE_WIN32_DBG_BUF_SIZE
   315    315   #  define SQLITE_WIN32_DBG_BUF_SIZE   ((int)(4096-sizeof(DWORD)))
   316    316   #endif
   317    317   
   318         -/*
   319         - * The value used with sqlite3_win32_set_directory() to specify that
   320         - * the data directory should be changed.
   321         - */
   322         -#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
   323         -#  define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
   324         -#endif
   325         -
   326         -/*
   327         - * The value used with sqlite3_win32_set_directory() to specify that
   328         - * the temporary directory should be changed.
   329         - */
   330         -#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
   331         -#  define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
   332         -#endif
   333         -
   334    318   /*
   335    319    * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
   336    320    * various Win32 API heap functions instead of our own.
   337    321    */
   338    322   #ifdef SQLITE_WIN32_MALLOC
   339    323   
   340    324   /*
................................................................................
  1923   1907   #ifndef SQLITE_OMIT_AUTOINIT
  1924   1908     if( sqlite3_initialize() ) return 0;
  1925   1909   #endif
  1926   1910     return winUtf8ToMbcs(zText, useAnsi);
  1927   1911   }
  1928   1912   
  1929   1913   /*
  1930         -** This function sets the data directory or the temporary directory based on
  1931         -** the provided arguments.  The type argument must be 1 in order to set the
  1932         -** data directory or 2 in order to set the temporary directory.  The zValue
  1933         -** argument is the name of the directory to use.  The return value will be
  1934         -** SQLITE_OK if successful.
         1914  +** This function is the same as sqlite3_win32_set_directory (below); however,
         1915  +** it accepts a UTF-8 string.
  1935   1916   */
  1936         -int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
         1917  +int sqlite3_win32_set_directory8(
         1918  +  unsigned long type, /* Identifier for directory being set or reset */
         1919  +  const char *zValue  /* New value for directory being set or reset */
         1920  +){
  1937   1921     char **ppDirectory = 0;
  1938   1922   #ifndef SQLITE_OMIT_AUTOINIT
  1939   1923     int rc = sqlite3_initialize();
  1940   1924     if( rc ) return rc;
  1941   1925   #endif
  1942   1926     if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
  1943   1927       ppDirectory = &sqlite3_data_directory;
................................................................................
  1945   1929       ppDirectory = &sqlite3_temp_directory;
  1946   1930     }
  1947   1931     assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
  1948   1932             || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
  1949   1933     );
  1950   1934     assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
  1951   1935     if( ppDirectory ){
  1952         -    char *zValueUtf8 = 0;
         1936  +    char *zCopy = 0;
  1953   1937       if( zValue && zValue[0] ){
  1954         -      zValueUtf8 = winUnicodeToUtf8(zValue);
  1955         -      if ( zValueUtf8==0 ){
         1938  +      zCopy = sqlite3_mprintf("%s", zValue);
         1939  +      if ( zCopy==0 ){
  1956   1940           return SQLITE_NOMEM_BKPT;
  1957   1941         }
  1958   1942       }
  1959   1943       sqlite3_free(*ppDirectory);
  1960         -    *ppDirectory = zValueUtf8;
         1944  +    *ppDirectory = zCopy;
  1961   1945       return SQLITE_OK;
  1962   1946     }
  1963   1947     return SQLITE_ERROR;
  1964   1948   }
         1949  +
         1950  +/*
         1951  +** This function is the same as sqlite3_win32_set_directory (below); however,
         1952  +** it accepts a UTF-16 string.
         1953  +*/
         1954  +int sqlite3_win32_set_directory16(
         1955  +  unsigned long type, /* Identifier for directory being set or reset */
         1956  +  const void *zValue  /* New value for directory being set or reset */
         1957  +){
         1958  +  int rc;
         1959  +  char *zUtf8 = 0;
         1960  +  if( zValue ){
         1961  +    zUtf8 = sqlite3_win32_unicode_to_utf8(zValue);
         1962  +    if( zUtf8==0 ) return SQLITE_NOMEM_BKPT;
         1963  +  }
         1964  +  rc = sqlite3_win32_set_directory8(type, zUtf8);
         1965  +  if( zUtf8 ) sqlite3_free(zUtf8);
         1966  +  return rc;
         1967  +}
         1968  +
         1969  +/*
         1970  +** This function sets the data directory or the temporary directory based on
         1971  +** the provided arguments.  The type argument must be 1 in order to set the
         1972  +** data directory or 2 in order to set the temporary directory.  The zValue
         1973  +** argument is the name of the directory to use.  The return value will be
         1974  +** SQLITE_OK if successful.
         1975  +*/
         1976  +int sqlite3_win32_set_directory(
         1977  +  unsigned long type, /* Identifier for directory being set or reset */
         1978  +  void *zValue        /* New value for directory being set or reset */
         1979  +){
         1980  +  return sqlite3_win32_set_directory16(type, zValue);
         1981  +}
  1965   1982   
  1966   1983   /*
  1967   1984   ** The return value of winGetLastErrorMsg
  1968   1985   ** is zero if the error message fits in the buffer, or non-zero
  1969   1986   ** otherwise (if the message was truncated).
  1970   1987   */
  1971   1988   static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){

Changes to src/pragma.c.

  2212   2212     char cSep = '(';
  2213   2213     StrAccum acc;
  2214   2214     char zBuf[200];
  2215   2215   
  2216   2216     UNUSED_PARAMETER(argc);
  2217   2217     UNUSED_PARAMETER(argv);
  2218   2218     sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  2219         -  sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
         2219  +  sqlite3_str_appendall(&acc, "CREATE TABLE x");
  2220   2220     for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
  2221         -    sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
         2221  +    sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]);
  2222   2222       cSep = ',';
  2223   2223     }
  2224   2224     if( i==0 ){
  2225         -    sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
         2225  +    sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
  2226   2226       cSep = ',';
  2227   2227       i++;
  2228   2228     }
  2229   2229     j = 0;
  2230   2230     if( pPragma->mPragFlg & PragFlg_Result1 ){
  2231         -    sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
         2231  +    sqlite3_str_appendall(&acc, ",arg HIDDEN");
  2232   2232       j++;
  2233   2233     }
  2234   2234     if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
  2235         -    sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
         2235  +    sqlite3_str_appendall(&acc, ",schema HIDDEN");
  2236   2236       j++;
  2237   2237     }
  2238         -  sqlite3StrAccumAppend(&acc, ")", 1);
         2238  +  sqlite3_str_append(&acc, ")", 1);
  2239   2239     sqlite3StrAccumFinish(&acc);
  2240   2240     assert( strlen(zBuf) < sizeof(zBuf)-1 );
  2241   2241     rc = sqlite3_declare_vtab(db, zBuf);
  2242   2242     if( rc==SQLITE_OK ){
  2243   2243       pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
  2244   2244       if( pTab==0 ){
  2245   2245         rc = SQLITE_NOMEM;
................................................................................
  2383   2383         pCsr->azArg[j] = sqlite3_mprintf("%s", zText);
  2384   2384         if( pCsr->azArg[j]==0 ){
  2385   2385           return SQLITE_NOMEM;
  2386   2386         }
  2387   2387       }
  2388   2388     }
  2389   2389     sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
  2390         -  sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
         2390  +  sqlite3_str_appendall(&acc, "PRAGMA ");
  2391   2391     if( pCsr->azArg[1] ){
  2392         -    sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
         2392  +    sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]);
  2393   2393     }
  2394         -  sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
         2394  +  sqlite3_str_appendall(&acc, pTab->pName->zName);
  2395   2395     if( pCsr->azArg[0] ){
  2396         -    sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
         2396  +    sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
  2397   2397     }
  2398   2398     zSql = sqlite3StrAccumFinish(&acc);
  2399   2399     if( zSql==0 ) return SQLITE_NOMEM;
  2400   2400     rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
  2401   2401     sqlite3_free(zSql);
  2402   2402     if( rc!=SQLITE_OK ){
  2403   2403       pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));

Changes to src/prepare.c.

   211    211     **    meta[9]   unused
   212    212     **
   213    213     ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
   214    214     ** the possible values of meta[4].
   215    215     */
   216    216     for(i=0; i<ArraySize(meta); i++){
   217    217       sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
          218  +  }
          219  +  if( (db->flags & SQLITE_ResetDatabase)!=0 ){
          220  +    memset(meta, 0, sizeof(meta));
   218    221     }
   219    222     pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
   220    223   
   221    224     /* If opening a non-empty database, check the text encoding. For the
   222    225     ** main database, set sqlite3.enc to the encoding of the main database.
   223    226     ** For an attached db, it is an error if the encoding is not the same
   224    227     ** as sqlite3.enc.
................................................................................
   609    612     }
   610    613     rc = sParse.rc;
   611    614   
   612    615   #ifndef SQLITE_OMIT_EXPLAIN
   613    616     if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
   614    617       static const char * const azColName[] = {
   615    618          "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
   616         -       "selectid", "order", "from", "detail"
          619  +       "id", "parent", "notused", "detail"
   617    620       };
   618    621       int iFirst, mx;
   619    622       if( sParse.explain==2 ){
   620    623         sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
   621    624         iFirst = 8;
   622    625         mx = 12;
   623    626       }else{

Changes to src/printf.c.

   130    130   }
   131    131   #endif /* SQLITE_OMIT_FLOATING_POINT */
   132    132   
   133    133   /*
   134    134   ** Set the StrAccum object to an error mode.
   135    135   */
   136    136   static void setStrAccumError(StrAccum *p, u8 eError){
   137         -  assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
          137  +  assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
   138    138     p->accError = eError;
   139    139     p->nAlloc = 0;
   140    140   }
   141    141   
   142    142   /*
   143    143   ** Extra argument values from a PrintfArguments object
   144    144   */
................................................................................
   164    164   # define SQLITE_PRINT_BUF_SIZE 70
   165    165   #endif
   166    166   #define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
   167    167   
   168    168   /*
   169    169   ** Render a string given by "fmt" into the StrAccum object.
   170    170   */
   171         -void sqlite3VXPrintf(
   172         -  StrAccum *pAccum,          /* Accumulate results here */
          171  +void sqlite3_str_vappendf(
          172  +  sqlite3_str *pAccum,       /* Accumulate results here */
   173    173     const char *fmt,           /* Format string */
   174    174     va_list ap                 /* arguments */
   175    175   ){
   176    176     int c;                     /* Next character in the format string */
   177    177     char *bufpt;               /* Pointer to the conversion buffer */
   178    178     int precision;             /* Precision of the current field */
   179    179     int length;                /* Length of the field */
................................................................................
   222    222       if( c!='%' ){
   223    223         bufpt = (char *)fmt;
   224    224   #if HAVE_STRCHRNUL
   225    225         fmt = strchrnul(fmt, '%');
   226    226   #else
   227    227         do{ fmt++; }while( *fmt && *fmt != '%' );
   228    228   #endif
   229         -      sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
          229  +      sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
   230    230         if( *fmt==0 ) break;
   231    231       }
   232    232       if( (c=(*++fmt))==0 ){
   233         -      sqlite3StrAccumAppend(pAccum, "%", 1);
          233  +      sqlite3_str_append(pAccum, "%", 1);
   234    234         break;
   235    235       }
   236    236       /* Find out what flags are present */
   237    237       flag_leftjustify = flag_prefix = cThousand =
   238    238        flag_alternateform = flag_altform2 = flag_zeropad = 0;
   239    239       done = 0;
   240    240       do{
................................................................................
   404    404           if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
   405    405             nOut = etBUFSIZE;
   406    406             zOut = buf;
   407    407           }else{
   408    408             u64 n = (u64)precision + 10 + precision/3;
   409    409             zOut = zExtra = sqlite3Malloc( n );
   410    410             if( zOut==0 ){
   411         -            setStrAccumError(pAccum, STRACCUM_NOMEM);
          411  +            setStrAccumError(pAccum, SQLITE_NOMEM);
   412    412               return;
   413    413             }
   414    414             nOut = (int)n;
   415    415           }
   416    416           bufpt = &zOut[nOut-1];
   417    417           if( xtype==etORDINAL ){
   418    418             static const char zOrd[] = "thstndrd";
................................................................................
   529    529           }else{
   530    530             e2 = exp;
   531    531           }
   532    532           if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
   533    533             bufpt = zExtra 
   534    534                 = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
   535    535             if( bufpt==0 ){
   536         -            setStrAccumError(pAccum, STRACCUM_NOMEM);
          536  +            setStrAccumError(pAccum, SQLITE_NOMEM);
   537    537               return;
   538    538             }
   539    539           }
   540    540           zOut = bufpt;
   541    541           nsd = 16 + flag_altform2*10;
   542    542           flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
   543    543           /* The sign in front of the number */
................................................................................
   661    661               buf[3] = 0x80 + (u8)(ch & 0x3f);
   662    662               length = 4;
   663    663             }
   664    664           }
   665    665           if( precision>1 ){
   666    666             width -= precision-1;
   667    667             if( width>1 && !flag_leftjustify ){
   668         -            sqlite3AppendChar(pAccum, width-1, ' ');
          668  +            sqlite3_str_appendchar(pAccum, width-1, ' ');
   669    669               width = 0;
   670    670             }
   671    671             while( precision-- > 1 ){
   672         -            sqlite3StrAccumAppend(pAccum, buf, length);
          672  +            sqlite3_str_append(pAccum, buf, length);
   673    673             }
   674    674           }
   675    675           bufpt = buf;
   676    676           flag_altform2 = 1;
   677    677           goto adjust_width_for_utf8;
   678    678         case etSTRING:
   679    679         case etDYNSTRING:
................................................................................
   751    751             }
   752    752           }
   753    753           needQuote = !isnull && xtype==etSQLESCAPE2;
   754    754           n += i + 3;
   755    755           if( n>etBUFSIZE ){
   756    756             bufpt = zExtra = sqlite3Malloc( n );
   757    757             if( bufpt==0 ){
   758         -            setStrAccumError(pAccum, STRACCUM_NOMEM);
          758  +            setStrAccumError(pAccum, SQLITE_NOMEM);
   759    759               return;
   760    760             }
   761    761           }else{
   762    762             bufpt = buf;
   763    763           }
   764    764           j = 0;
   765    765           if( needQuote ) bufpt[j++] = q;
................................................................................
   775    775         }
   776    776         case etTOKEN: {
   777    777           Token *pToken;
   778    778           if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
   779    779           pToken = va_arg(ap, Token*);
   780    780           assert( bArgList==0 );
   781    781           if( pToken && pToken->n ){
   782         -          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
          782  +          sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
   783    783           }
   784    784           length = width = 0;
   785    785           break;
   786    786         }
   787    787         case etSRCLIST: {
   788    788           SrcList *pSrc;
   789    789           int k;
................................................................................
   791    791           if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
   792    792           pSrc = va_arg(ap, SrcList*);
   793    793           k = va_arg(ap, int);
   794    794           pItem = &pSrc->a[k];
   795    795           assert( bArgList==0 );
   796    796           assert( k>=0 && k<pSrc->nSrc );
   797    797           if( pItem->zDatabase ){
   798         -          sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
   799         -          sqlite3StrAccumAppend(pAccum, ".", 1);
          798  +          sqlite3_str_appendall(pAccum, pItem->zDatabase);
          799  +          sqlite3_str_append(pAccum, ".", 1);
   800    800           }
   801         -        sqlite3StrAccumAppendAll(pAccum, pItem->zName);
          801  +        sqlite3_str_appendall(pAccum, pItem->zName);
   802    802           length = width = 0;
   803    803           break;
   804    804         }
   805    805         default: {
   806    806           assert( xtype==etINVALID );
   807    807           return;
   808    808         }
................................................................................
   813    813       ** the output.  Both length and width are in bytes, not characters,
   814    814       ** at this point.  If the "!" flag was present on string conversions
   815    815       ** indicating that width and precision should be expressed in characters,
   816    816       ** then the values have been translated prior to reaching this point.
   817    817       */
   818    818       width -= length;
   819    819       if( width>0 ){
   820         -      if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
   821         -      sqlite3StrAccumAppend(pAccum, bufpt, length);
   822         -      if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
          820  +      if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
          821  +      sqlite3_str_append(pAccum, bufpt, length);
          822  +      if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
   823    823       }else{
   824         -      sqlite3StrAccumAppend(pAccum, bufpt, length);
          824  +      sqlite3_str_append(pAccum, bufpt, length);
   825    825       }
   826    826   
   827    827       if( zExtra ){
   828    828         sqlite3DbFree(pAccum->db, zExtra);
   829    829         zExtra = 0;
   830    830       }
   831    831     }/* End for loop over the format string */
................................................................................
   838    838   ** Return the number of bytes of text that StrAccum is able to accept
   839    839   ** after the attempted enlargement.  The value returned might be zero.
   840    840   */
   841    841   static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
   842    842     char *zNew;
   843    843     assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
   844    844     if( p->accError ){
   845         -    testcase(p->accError==STRACCUM_TOOBIG);
   846         -    testcase(p->accError==STRACCUM_NOMEM);
          845  +    testcase(p->accError==SQLITE_TOOBIG);
          846  +    testcase(p->accError==SQLITE_NOMEM);
   847    847       return 0;
   848    848     }
   849    849     if( p->mxAlloc==0 ){
   850    850       N = p->nAlloc - p->nChar - 1;
   851         -    setStrAccumError(p, STRACCUM_TOOBIG);
          851  +    setStrAccumError(p, SQLITE_TOOBIG);
   852    852       return N;
   853    853     }else{
   854    854       char *zOld = isMalloced(p) ? p->zText : 0;
   855    855       i64 szNew = p->nChar;
   856    856       szNew += N + 1;
   857    857       if( szNew+p->nChar<=p->mxAlloc ){
   858    858         /* Force exponential buffer size growth as long as it does not overflow,
   859    859         ** to avoid having to call this routine too often */
   860    860         szNew += p->nChar;
   861    861       }
   862    862       if( szNew > p->mxAlloc ){
   863         -      sqlite3StrAccumReset(p);
   864         -      setStrAccumError(p, STRACCUM_TOOBIG);
          863  +      sqlite3_str_reset(p);
          864  +      setStrAccumError(p, SQLITE_TOOBIG);
   865    865         return 0;
   866    866       }else{
   867    867         p->nAlloc = (int)szNew;
   868    868       }
   869    869       if( p->db ){
   870    870         zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
   871    871       }else{
................................................................................
   874    874       if( zNew ){
   875    875         assert( p->zText!=0 || p->nChar==0 );
   876    876         if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
   877    877         p->zText = zNew;
   878    878         p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
   879    879         p->printfFlags |= SQLITE_PRINTF_MALLOCED;
   880    880       }else{
   881         -      sqlite3StrAccumReset(p);
   882         -      setStrAccumError(p, STRACCUM_NOMEM);
          881  +      sqlite3_str_reset(p);
          882  +      setStrAccumError(p, SQLITE_NOMEM);
   883    883         return 0;
   884    884       }
   885    885     }
   886    886     return N;
   887    887   }
   888    888   
   889    889   /*
   890    890   ** Append N copies of character c to the given string buffer.
   891    891   */
   892         -void sqlite3AppendChar(StrAccum *p, int N, char c){
          892  +void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){
   893    893     testcase( p->nChar + (i64)N > 0x7fffffff );
   894    894     if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
   895    895       return;
   896    896     }
   897    897     while( (N--)>0 ) p->zText[p->nChar++] = c;
   898    898   }
   899    899   
   900    900   /*
   901    901   ** The StrAccum "p" is not large enough to accept N new bytes of z[].
   902    902   ** So enlarge if first, then do the append.
   903    903   **
   904         -** This is a helper routine to sqlite3StrAccumAppend() that does special-case
          904  +** This is a helper routine to sqlite3_str_append() that does special-case
   905    905   ** work (enlarging the buffer) using tail recursion, so that the
   906         -** sqlite3StrAccumAppend() routine can use fast calling semantics.
          906  +** sqlite3_str_append() routine can use fast calling semantics.
   907    907   */
   908    908   static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
   909    909     N = sqlite3StrAccumEnlarge(p, N);
   910    910     if( N>0 ){
   911    911       memcpy(&p->zText[p->nChar], z, N);
   912    912       p->nChar += N;
   913    913     }
   914    914   }
   915    915   
   916    916   /*
   917    917   ** Append N bytes of text from z to the StrAccum object.  Increase the
   918    918   ** size of the memory allocation for StrAccum if necessary.
   919    919   */
   920         -void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
          920  +void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
   921    921     assert( z!=0 || N==0 );
   922    922     assert( p->zText!=0 || p->nChar==0 || p->accError );
   923    923     assert( N>=0 );
   924    924     assert( p->accError==0 || p->nAlloc==0 );
   925    925     if( p->nChar+N >= p->nAlloc ){
   926    926       enlargeAndAppend(p,z,N);
   927    927     }else if( N ){
................................................................................
   930    930       memcpy(&p->zText[p->nChar-N], z, N);
   931    931     }
   932    932   }
   933    933   
   934    934   /*
   935    935   ** Append the complete text of zero-terminated string z[] to the p string.
   936    936   */
   937         -void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
   938         -  sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
          937  +void sqlite3_str_appendall(sqlite3_str *p, const char *z){
          938  +  sqlite3_str_append(p, z, sqlite3Strlen30(z));
   939    939   }
   940    940   
   941    941   
   942    942   /*
   943    943   ** Finish off a string by making sure it is zero-terminated.
   944    944   ** Return a pointer to the resulting string.  Return a NULL
   945    945   ** pointer if any kind of error was encountered.
................................................................................
   948    948     char *zText;
   949    949     assert( p->mxAlloc>0 && !isMalloced(p) );
   950    950     zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
   951    951     if( zText ){
   952    952       memcpy(zText, p->zText, p->nChar+1);
   953    953       p->printfFlags |= SQLITE_PRINTF_MALLOCED;
   954    954     }else{
   955         -    setStrAccumError(p, STRACCUM_NOMEM);
          955  +    setStrAccumError(p, SQLITE_NOMEM);
   956    956     }
   957    957     p->zText = zText;
   958    958     return zText;
   959    959   }
   960    960   char *sqlite3StrAccumFinish(StrAccum *p){
   961    961     if( p->zText ){
   962    962       p->zText[p->nChar] = 0;
   963    963       if( p->mxAlloc>0 && !isMalloced(p) ){
   964    964         return strAccumFinishRealloc(p);
   965    965       }
   966    966     }
   967    967     return p->zText;
   968    968   }
          969  +
          970  +/* Finalize a string created using sqlite3_str_new().
          971  +*/
          972  +char *sqlite3_str_finish(sqlite3_str *p){
          973  +  char *z;
          974  +  if( p ){
          975  +    z = sqlite3StrAccumFinish(p);
          976  +    sqlite3_free(p);
          977  +  }else{
          978  +    z = 0;
          979  +  }
          980  +  return z;
          981  +}
          982  +
          983  +/* Return any error code associated with p */
          984  +int sqlite3_str_errcode(sqlite3_str *p){
          985  +  return p ? p->accError : SQLITE_NOMEM;
          986  +}
          987  +
          988  +/* Return the current length of p in bytes */
          989  +int sqlite3_str_length(sqlite3_str *p){
          990  +  return p ? p->nChar : 0;
          991  +}
          992  +
          993  +/* Return the current value for p */
          994  +char *sqlite3_str_value(sqlite3_str *p){
          995  +  if( p==0 || p->nChar==0 ) return 0;
          996  +  p->zText[p->nChar] = 0;
          997  +  return p->zText;
          998  +}
   969    999   
   970   1000   /*
   971   1001   ** Reset an StrAccum string.  Reclaim all malloced memory.
   972   1002   */
   973         -void sqlite3StrAccumReset(StrAccum *p){
         1003  +void sqlite3_str_reset(StrAccum *p){
   974   1004     if( isMalloced(p) ){
   975   1005       sqlite3DbFree(p->db, p->zText);
   976   1006       p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
   977   1007     }
         1008  +  p->nAlloc = 0;
         1009  +  p->nChar = 0;
   978   1010     p->zText = 0;
   979   1011   }
   980   1012   
   981   1013   /*
   982   1014   ** Initialize a string accumulator.
   983   1015   **
   984   1016   ** p:     The accumulator to be initialized.
................................................................................
   997   1029     p->db = db;
   998   1030     p->nAlloc = n;
   999   1031     p->mxAlloc = mx;
  1000   1032     p->nChar = 0;
  1001   1033     p->accError = 0;
  1002   1034     p->printfFlags = 0;
  1003   1035   }
         1036  +
         1037  +/* Allocate and initialize a new dynamic string object */
         1038  +sqlite3_str *sqlite3_str_new(sqlite3 *db){
         1039  +  sqlite3_str *p = sqlite3_malloc64(sizeof(*p));
         1040  +  if( p ){
         1041  +    sqlite3StrAccumInit(p, 0, 0, 0,
         1042  +            db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH);
         1043  +  }
         1044  +  return p;
         1045  +}
  1004   1046   
  1005   1047   /*
  1006   1048   ** Print into memory obtained from sqliteMalloc().  Use the internal
  1007   1049   ** %-conversion extensions.
  1008   1050   */
  1009   1051   char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
  1010   1052     char *z;
  1011   1053     char zBase[SQLITE_PRINT_BUF_SIZE];
  1012   1054     StrAccum acc;
  1013   1055     assert( db!=0 );
  1014   1056     sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
  1015   1057                         db->aLimit[SQLITE_LIMIT_LENGTH]);
  1016   1058     acc.printfFlags = SQLITE_PRINTF_INTERNAL;
  1017         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1059  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1018   1060     z = sqlite3StrAccumFinish(&acc);
  1019         -  if( acc.accError==STRACCUM_NOMEM ){
         1061  +  if( acc.accError==SQLITE_NOMEM ){
  1020   1062       sqlite3OomFault(db);
  1021   1063     }
  1022   1064     return z;
  1023   1065   }
  1024   1066   
  1025   1067   /*
  1026   1068   ** Print into memory obtained from sqliteMalloc().  Use the internal
................................................................................
  1050   1092       return 0;
  1051   1093     }
  1052   1094   #endif
  1053   1095   #ifndef SQLITE_OMIT_AUTOINIT
  1054   1096     if( sqlite3_initialize() ) return 0;
  1055   1097   #endif
  1056   1098     sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
  1057         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1099  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1058   1100     z = sqlite3StrAccumFinish(&acc);
  1059   1101     return z;
  1060   1102   }
  1061   1103   
  1062   1104   /*
  1063   1105   ** Print into memory obtained from sqlite3_malloc()().  Omit the internal
  1064   1106   ** %-conversion extensions.
................................................................................
  1095   1137     if( zBuf==0 || zFormat==0 ) {
  1096   1138       (void)SQLITE_MISUSE_BKPT;
  1097   1139       if( zBuf ) zBuf[0] = 0;
  1098   1140       return zBuf;
  1099   1141     }
  1100   1142   #endif
  1101   1143     sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
  1102         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1144  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1103   1145     zBuf[acc.nChar] = 0;
  1104   1146     return zBuf;
  1105   1147   }
  1106   1148   char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
  1107   1149     char *z;
  1108   1150     va_list ap;
  1109   1151     va_start(ap,zFormat);
................................................................................
  1117   1159   ** We house it in a separate routine from sqlite3_log() to avoid using
  1118   1160   ** stack space on small-stack systems when logging is disabled.
  1119   1161   **
  1120   1162   ** sqlite3_log() must render into a static buffer.  It cannot dynamically
  1121   1163   ** allocate memory because it might be called while the memory allocator
  1122   1164   ** mutex is held.
  1123   1165   **
  1124         -** sqlite3VXPrintf() might ask for *temporary* memory allocations for
         1166  +** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
  1125   1167   ** certain format characters (%q) or for very large precisions or widths.
  1126   1168   ** Care must be taken that any sqlite3_log() calls that occur while the
  1127   1169   ** memory mutex is held do not use these mechanisms.
  1128   1170   */
  1129   1171   static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
  1130   1172     StrAccum acc;                          /* String accumulator */
  1131   1173     char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
  1132   1174   
  1133   1175     sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
  1134         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1176  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1135   1177     sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
  1136   1178                              sqlite3StrAccumFinish(&acc));
  1137   1179   }
  1138   1180   
  1139   1181   /*
  1140   1182   ** Format and write a message to the log if logging is enabled.
  1141   1183   */
................................................................................
  1156   1198   */
  1157   1199   void sqlite3DebugPrintf(const char *zFormat, ...){
  1158   1200     va_list ap;
  1159   1201     StrAccum acc;
  1160   1202     char zBuf[500];
  1161   1203     sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  1162   1204     va_start(ap,zFormat);
  1163         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1205  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1164   1206     va_end(ap);
  1165   1207     sqlite3StrAccumFinish(&acc);
  1166   1208   #ifdef SQLITE_OS_TRACE_PROC
  1167   1209     {
  1168   1210       extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf);
  1169   1211       SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf));
  1170   1212     }
................................................................................
  1173   1215     fflush(stdout);
  1174   1216   #endif
  1175   1217   }
  1176   1218   #endif
  1177   1219   
  1178   1220   
  1179   1221   /*
  1180         -** variable-argument wrapper around sqlite3VXPrintf().  The bFlags argument
         1222  +** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument
  1181   1223   ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
  1182   1224   */
  1183         -void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
         1225  +void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
  1184   1226     va_list ap;
  1185   1227     va_start(ap,zFormat);
  1186         -  sqlite3VXPrintf(p, zFormat, ap);
         1228  +  sqlite3_str_vappendf(p, zFormat, ap);
  1187   1229     va_end(ap);
  1188   1230   }

Changes to src/select.c.

    17     17   /*
    18     18   ** Trace output macros
    19     19   */
    20     20   #if SELECTTRACE_ENABLED
    21     21   /***/ int sqlite3SelectTrace = 0;
    22     22   # define SELECTTRACE(K,P,S,X)  \
    23     23     if(sqlite3SelectTrace&(K))   \
    24         -    sqlite3DebugPrintf("%s/%d/%p: ",(S)->zSelName,(P)->iSelectId,(S)),\
           24  +    sqlite3DebugPrintf("%s/%d/%p: ",(S)->zSelName,(P)->addrExplain,(S)),\
    25     25       sqlite3DebugPrintf X
    26     26   #else
    27     27   # define SELECTTRACE(K,P,S,X)
    28     28   #endif
    29     29   
    30     30   
    31     31   /*
................................................................................
    74     74     u8 nDefer;            /* Number of valid entries in aDefer[] */
    75     75     struct DeferredCsr {
    76     76       Table *pTab;        /* Table definition */
    77     77       int iCsr;           /* Cursor number for table */
    78     78       int nKey;           /* Number of PK columns for table pTab (>=1) */
    79     79     } aDefer[4];
    80     80   #endif
           81  +  struct RowLoadInfo *pDeferredRowLoad;  /* Deferred row loading info or NULL */
    81     82   };
    82     83   #define SORTFLAG_UseSorter  0x01   /* Use SorterOpen instead of OpenEphemeral */
    83     84   
    84     85   /*
    85     86   ** Delete all the content of a Select structure.  Deallocate the structure
    86     87   ** itself only if bFree is true.
    87     88   */
................................................................................
   531    532   /* Forward reference */
   532    533   static KeyInfo *keyInfoFromExprList(
   533    534     Parse *pParse,       /* Parsing context */
   534    535     ExprList *pList,     /* Form the KeyInfo object from this ExprList */
   535    536     int iStart,          /* Begin with this column of pList */
   536    537     int nExtra           /* Add this many extra columns to the end */
   537    538   );
          539  +
          540  +/*
          541  +** An instance of this object holds information (beyond pParse and pSelect)
          542  +** needed to load the next result row that is to be added to the sorter.
          543  +*/
          544  +typedef struct RowLoadInfo RowLoadInfo;
          545  +struct RowLoadInfo {
          546  +  int regResult;               /* Store results in array of registers here */
          547  +  u8 ecelFlags;                /* Flag argument to ExprCodeExprList() */
          548  +#ifdef SQLITE_ENABLE_SORTER_REFERENCES
          549  +  ExprList *pExtra;            /* Extra columns needed by sorter refs */
          550  +  int regExtraResult;          /* Where to load the extra columns */
          551  +#endif
          552  +};
          553  +
          554  +/*
          555  +** This routine does the work of loading query data into an array of
          556  +** registers so that it can be added to the sorter.
          557  +*/
          558  +static void innerLoopLoadRow(
          559  +  Parse *pParse,             /* Statement under construction */
          560  +  Select *pSelect,           /* The query being coded */
          561  +  RowLoadInfo *pInfo         /* Info needed to complete the row load */
          562  +){
          563  +  sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult,
          564  +                          0, pInfo->ecelFlags);
          565  +#ifdef SQLITE_ENABLE_SORTER_REFERENCES
          566  +  if( pInfo->pExtra ){
          567  +    sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0);
          568  +    sqlite3ExprListDelete(pParse->db, pInfo->pExtra);
          569  +  }
          570  +#endif
          571  +}
          572  +
          573  +/*
          574  +** Code the OP_MakeRecord instruction that generates the entry to be
          575  +** added into the sorter.
          576  +**
          577  +** Return the register in which the result is stored.
          578  +*/
          579  +static int makeSorterRecord(
          580  +  Parse *pParse,
          581  +  SortCtx *pSort,
          582  +  Select *pSelect,
          583  +  int regBase,
          584  +  int nBase
          585  +){
          586  +  int nOBSat = pSort->nOBSat;
          587  +  Vdbe *v = pParse->pVdbe;
          588  +  int regOut = ++pParse->nMem;
          589  +  if( pSort->pDeferredRowLoad ){
          590  +    innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad);
          591  +  }
          592  +  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut);
          593  +  return regOut;
          594  +}
   538    595   
   539    596   /*
   540    597   ** Generate code that will push the record in registers regData
   541    598   ** through regData+nData-1 onto the sorter.
   542    599   */
   543    600   static void pushOntoSorter(
   544    601     Parse *pParse,         /* Parser context */
   545    602     SortCtx *pSort,        /* Information about the ORDER BY clause */
   546    603     Select *pSelect,       /* The whole SELECT statement */
   547    604     int regData,           /* First register holding data to be sorted */
   548    605     int regOrigData,       /* First register holding data before packing */
   549         -  int nData,             /* Number of elements in the data array */
          606  +  int nData,             /* Number of elements in the regData data array */
   550    607     int nPrefixReg         /* No. of reg prior to regData available for use */
   551    608   ){
   552    609     Vdbe *v = pParse->pVdbe;                         /* Stmt under construction */
   553    610     int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0);
   554    611     int nExpr = pSort->pOrderBy->nExpr;              /* No. of ORDER BY terms */
   555    612     int nBase = nExpr + bSeq + nData;                /* Fields in sorter record */
   556    613     int regBase;                                     /* Regs for sorter record */
   557         -  int regRecord = ++pParse->nMem;                  /* Assembled sorter record */
          614  +  int regRecord = 0;                               /* Assembled sorter record */
   558    615     int nOBSat = pSort->nOBSat;                      /* ORDER BY terms to skip */
   559    616     int op;                            /* Opcode to add sorter record to sorter */
   560    617     int iLimit;                        /* LIMIT counter */
          618  +  int iSkip = 0;                     /* End of the sorter insert loop */
   561    619   
   562    620     assert( bSeq==0 || bSeq==1 );
          621  +
          622  +  /* Three cases:
          623  +  **   (1) The data to be sorted has already been packed into a Record
          624  +  **       by a prior OP_MakeRecord.  In this case nData==1 and regData
          625  +  **       will be completely unrelated to regOrigData.
          626  +  **   (2) All output columns are included in the sort record.  In that
          627  +  **       case regData==regOrigData.
          628  +  **   (3) Some output columns are omitted from the sort record due to
          629  +  **       the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the
          630  +  **       SQLITE_ECEL_OMITREF optimization, or due to the 
          631  +  **       SortCtx.pDeferredRowLoad optimiation.  In any of these cases
          632  +  **       regOrigData is 0 to prevent this routine from trying to copy
          633  +  **       values that might not yet exist.
          634  +  */
   563    635     assert( nData==1 || regData==regOrigData || regOrigData==0 );
          636  +
   564    637     if( nPrefixReg ){
   565    638       assert( nPrefixReg==nExpr+bSeq );
   566         -    regBase = regData - nExpr - bSeq;
          639  +    regBase = regData - nPrefixReg;
   567    640     }else{
   568    641       regBase = pParse->nMem + 1;
   569    642       pParse->nMem += nBase;
   570    643     }
   571    644     assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
   572    645     iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
   573    646     pSort->labelDone = sqlite3VdbeMakeLabel(v);
................................................................................
   583    656       int regPrevKey;   /* The first nOBSat columns of the previous row */
   584    657       int addrFirst;    /* Address of the OP_IfNot opcode */
   585    658       int addrJmp;      /* Address of the OP_Jump opcode */
   586    659       VdbeOp *pOp;      /* Opcode that opens the sorter */
   587    660       int nKey;         /* Number of sorting key columns, including OP_Sequence */
   588    661       KeyInfo *pKI;     /* Original KeyInfo on the sorter table */
   589    662   
   590         -    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat,regRecord);
          663  +    regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
   591    664       regPrevKey = pParse->nMem+1;
   592    665       pParse->nMem += pSort->nOBSat;
   593    666       nKey = nExpr - pSort->nOBSat + bSeq;
   594    667       if( bSeq ){
   595    668         addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); 
   596    669       }else{
   597    670         addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor);
................................................................................
   634    707       ** If the new record does not need to be inserted into the sorter,
   635    708       ** jump to the next iteration of the loop. Or, if the
   636    709       ** pSort->bOrderedInnerLoop flag is set to indicate that the inner
   637    710       ** loop delivers items in sorted order, jump to the next iteration
   638    711       ** of the outer loop.
   639    712       */
   640    713       int iCsr = pSort->iECursor;
   641         -    int iJmp = sqlite3VdbeCurrentAddr(v)+5+(nOBSat<=0)+pSort->bOrderedInnerLoop;
   642         -    assert( pSort->bOrderedInnerLoop==0 || pSort->bOrderedInnerLoop==1 );
   643    714       sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4);
   644    715       VdbeCoverage(v);
   645    716       sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0);
   646         -    sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, iJmp, regBase+nOBSat, nExpr-nOBSat);
          717  +    iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE,
          718  +                                 iCsr, 0, regBase+nOBSat, nExpr-nOBSat);
   647    719       VdbeCoverage(v);
   648    720       sqlite3VdbeAddOp1(v, OP_Delete, iCsr);
   649    721     }
   650         -  if( nOBSat<=0 ){
   651         -    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat,regRecord);
          722  +  if( regRecord==0 ){
          723  +    regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
   652    724     }
   653    725     if( pSort->sortFlags & SORTFLAG_UseSorter ){
   654    726       op = OP_SorterInsert;
   655    727     }else{
   656    728       op = OP_IdxInsert;
   657    729     }
   658    730     sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
   659    731                          regBase+nOBSat, nBase-nOBSat);
          732  +  if( iSkip ){
          733  +    assert( pSort->bOrderedInnerLoop==0 || pSort->bOrderedInnerLoop==1 );
          734  +    sqlite3VdbeChangeP2(v, iSkip,
          735  +         sqlite3VdbeCurrentAddr(v) + pSort->bOrderedInnerLoop);
          736  +  }
   660    737   }
   661    738   
   662    739   /*
   663    740   ** Add code to implement the OFFSET
   664    741   */
   665    742   static void codeOffset(
   666    743     Vdbe *v,          /* Generate code into this VM */
................................................................................
   738    815     for(i=0; i<pEList->nExpr; i++){
   739    816       struct ExprList_item *pItem = &pEList->a[i];
   740    817       if( pItem->u.x.iOrderByCol==0 ){
   741    818         Expr *pExpr = pItem->pExpr;
   742    819         Table *pTab = pExpr->pTab;
   743    820         if( pExpr->op==TK_COLUMN && pTab && !IsVirtual(pTab)
   744    821          && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
   745         -#if 0
   746         -          && pTab->pSchema && pTab->pSelect==0 && !IsVirtual(pTab)
   747         -#endif
   748    822         ){
   749    823           int j;
   750    824           for(j=0; j<nDefer; j++){
   751    825             if( pSort->aDefer[j].iCsr==pExpr->iTable ) break;
   752    826           }
   753    827           if( j==nDefer ){
   754    828             if( nDefer==ArraySize(pSort->aDefer) ){
................................................................................
   807    881     Vdbe *v = pParse->pVdbe;
   808    882     int i;
   809    883     int hasDistinct;            /* True if the DISTINCT keyword is present */
   810    884     int eDest = pDest->eDest;   /* How to dispose of results */
   811    885     int iParm = pDest->iSDParm; /* First argument to disposal method */
   812    886     int nResultCol;             /* Number of result columns */
   813    887     int nPrefixReg = 0;         /* Number of extra registers before regResult */
          888  +  RowLoadInfo sRowLoadInfo;   /* Info for deferred row loading */
   814    889   
   815    890     /* Usually, regResult is the first cell in an array of memory cells
   816    891     ** containing the current result row. In this case regOrig is set to the
   817    892     ** same value. However, if the results are being sent to the sorter, the
   818    893     ** values for any expressions that are also part of the sort-key are omitted
   819    894     ** from this array. In this case regOrig is set to zero.  */
   820    895     int regResult;              /* Start of memory holding current results */
................................................................................
   859    934     }else if( eDest!=SRT_Exists ){
   860    935   #ifdef SQLITE_ENABLE_SORTER_REFERENCES
   861    936       ExprList *pExtra = 0;
   862    937   #endif
   863    938       /* If the destination is an EXISTS(...) expression, the actual
   864    939       ** values returned by the SELECT are not required.
   865    940       */
   866         -    u8 ecelFlags;
          941  +    u8 ecelFlags;    /* "ecel" is an abbreviation of "ExprCodeExprList" */
          942  +    ExprList *pEList;
   867    943       if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
   868    944         ecelFlags = SQLITE_ECEL_DUP;
   869    945       }else{
   870    946         ecelFlags = 0;
   871    947       }
   872    948       if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
   873    949         /* For each expression in p->pEList that is a copy of an expression in
   874    950         ** the ORDER BY clause (pSort->pOrderBy), set the associated 
   875    951         ** iOrderByCol value to one more than the index of the ORDER BY 
   876    952         ** expression within the sort-key that pushOntoSorter() will generate.
   877    953         ** This allows the p->pEList field to be omitted from the sorted record,
   878    954         ** saving space and CPU cycles.  */
   879    955         ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
          956  +
   880    957         for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
   881    958           int j;
   882    959           if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
   883    960             p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
   884    961           }
   885    962         }
   886    963   #ifdef SQLITE_ENABLE_SORTER_REFERENCES
................................................................................
   893    970           ** composite primary keys in the SortCtx.aDefer[] array.  */
   894    971           VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
   895    972           pOp->p2 += (pExtra->nExpr - pSort->nDefer);
   896    973           pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer);
   897    974           pParse->nMem += pExtra->nExpr;
   898    975         }
   899    976   #endif
   900         -      regOrig = 0;
          977  +
          978  +      /* Adjust nResultCol to account for columns that are omitted
          979  +      ** from the sorter by the optimizations in this branch */
          980  +      pEList = p->pEList;
          981  +      for(i=0; i<pEList->nExpr; i++){
          982  +        if( pEList->a[i].u.x.iOrderByCol>0
          983  +#ifdef SQLITE_ENABLE_SORTER_REFERENCES
          984  +         || pEList->a[i].bSorterRef
          985  +#endif
          986  +        ){
          987  +          nResultCol--;
          988  +          regOrig = 0;
          989  +        }
          990  +      }
          991  +
          992  +      testcase( regOrig );
          993  +      testcase( eDest==SRT_Set );
          994  +      testcase( eDest==SRT_Mem );
          995  +      testcase( eDest==SRT_Coroutine );
          996  +      testcase( eDest==SRT_Output );
   901    997         assert( eDest==SRT_Set || eDest==SRT_Mem 
   902    998              || eDest==SRT_Coroutine || eDest==SRT_Output );
   903    999       }
   904         -    nResultCol = sqlite3ExprCodeExprList(pParse,p->pEList,regResult,
   905         -                                         0,ecelFlags);
         1000  +    sRowLoadInfo.regResult = regResult;
         1001  +    sRowLoadInfo.ecelFlags = ecelFlags;
   906   1002   #ifdef SQLITE_ENABLE_SORTER_REFERENCES
   907         -    if( pExtra ){
   908         -      nResultCol += sqlite3ExprCodeExprList(
   909         -          pParse, pExtra, regResult + nResultCol, 0, 0
   910         -      );
   911         -      sqlite3ExprListDelete(pParse->db, pExtra);
         1003  +    sRowLoadInfo.pExtra = pExtra;
         1004  +    sRowLoadInfo.regExtraResult = regResult + nResultCol;
         1005  +    if( pExtra ) nResultCol += pExtra->nExpr;
         1006  +#endif
         1007  +    if( p->iLimit
         1008  +     && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 
         1009  +     && nPrefixReg>0
         1010  +    ){
         1011  +      assert( pSort!=0 );
         1012  +      assert( hasDistinct==0 );
         1013  +      pSort->pDeferredRowLoad = &sRowLoadInfo;
         1014  +      regOrig = 0;
         1015  +    }else{
         1016  +      innerLoopLoadRow(pParse, p, &sRowLoadInfo);
   912   1017       }
   913         -#endif
   914   1018     }
   915   1019   
   916   1020     /* If the DISTINCT keyword was present on the SELECT statement
   917   1021     ** and this row has been seen before, then do not make this row
   918   1022     ** part of the result.
   919   1023     */
   920   1024     if( hasDistinct ){
................................................................................
  1022   1126           sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0);
  1023   1127           VdbeCoverage(v);
  1024   1128           sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol);
  1025   1129           assert( pSort==0 );
  1026   1130         }
  1027   1131   #endif
  1028   1132         if( pSort ){
  1029         -        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
         1133  +        assert( regResult==regOrig );
         1134  +        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg);
  1030   1135         }else{
  1031   1136           int r2 = sqlite3GetTempReg(pParse);
  1032   1137           sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
  1033   1138           sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
  1034   1139           sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
  1035   1140           sqlite3ReleaseTempReg(pParse, r2);
  1036   1141         }
................................................................................
  1289   1394   **
  1290   1395   **   "USE TEMP B-TREE FOR xxx"
  1291   1396   **
  1292   1397   ** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which
  1293   1398   ** is determined by the zUsage argument.
  1294   1399   */
  1295   1400   static void explainTempTable(Parse *pParse, const char *zUsage){
  1296         -  if( pParse->explain==2 ){
  1297         -    Vdbe *v = pParse->pVdbe;
  1298         -    char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
  1299         -    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
  1300         -  }
         1401  +  ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage));
  1301   1402   }
  1302   1403   
  1303   1404   /*
  1304   1405   ** Assign expression b to lvalue a. A second, no-op, version of this macro
  1305   1406   ** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code
  1306   1407   ** in sqlite3Select() to assign values to structure member variables that
  1307   1408   ** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the
................................................................................
  1311   1412   
  1312   1413   #else
  1313   1414   /* No-op versions of the explainXXX() functions and macros. */
  1314   1415   # define explainTempTable(y,z)
  1315   1416   # define explainSetInteger(y,z)
  1316   1417   #endif
  1317   1418   
  1318         -#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
  1319         -/*
  1320         -** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
  1321         -** is a no-op. Otherwise, it adds a single row of output to the EQP result,
  1322         -** where the caption is of one of the two forms:
  1323         -**
  1324         -**   "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
  1325         -**   "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
  1326         -**
  1327         -** where iSub1 and iSub2 are the integers passed as the corresponding
  1328         -** function parameters, and op is the text representation of the parameter
  1329         -** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
  1330         -** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is 
  1331         -** false, or the second form if it is true.
  1332         -*/
  1333         -static void explainComposite(
  1334         -  Parse *pParse,                  /* Parse context */
  1335         -  int op,                         /* One of TK_UNION, TK_EXCEPT etc. */
  1336         -  int iSub1,                      /* Subquery id 1 */
  1337         -  int iSub2,                      /* Subquery id 2 */
  1338         -  int bUseTmp                     /* True if a temp table was used */
  1339         -){
  1340         -  assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
  1341         -  if( pParse->explain==2 ){
  1342         -    Vdbe *v = pParse->pVdbe;
  1343         -    char *zMsg = sqlite3MPrintf(
  1344         -        pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
  1345         -        bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
  1346         -    );
  1347         -    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
  1348         -  }
  1349         -}
  1350         -#else
  1351         -/* No-op versions of the explainXXX() functions and macros. */
  1352         -# define explainComposite(v,w,x,y,z)
  1353         -#endif
  1354   1419   
  1355   1420   /*
  1356   1421   ** If the inner loop was generated using a non-null pOrderBy argument,
  1357   1422   ** then the results were placed in a sorter.  After the loop is terminated
  1358   1423   ** we need to run the sorter and output the results.  The following
  1359   1424   ** routine generates the code needed to do that.
  1360   1425   */
................................................................................
  1796   1861   #ifndef SQLITE_OMIT_EXPLAIN
  1797   1862     /* If this is an EXPLAIN, skip this step */
  1798   1863     if( pParse->explain ){
  1799   1864       return;
  1800   1865     }
  1801   1866   #endif
  1802   1867   
  1803         -  if( pParse->colNamesSet || db->mallocFailed ) return;
         1868  +  if( pParse->colNamesSet ) return;
  1804   1869     /* Column names are determined by the left-most term of a compound select */
  1805   1870     while( pSelect->pPrior ) pSelect = pSelect->pPrior;
  1806   1871     SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
  1807   1872     pTabList = pSelect->pSrc;
  1808   1873     pEList = pSelect->pEList;
  1809   1874     assert( v!=0 );
  1810   1875     assert( pTabList!=0 );
................................................................................
  2323   2388     }
  2324   2389   
  2325   2390     /* Detach the ORDER BY clause from the compound SELECT */
  2326   2391     p->pOrderBy = 0;
  2327   2392   
  2328   2393     /* Store the results of the setup-query in Queue. */
  2329   2394     pSetup->pNext = 0;
         2395  +  ExplainQueryPlan((pParse, 1, "SETUP"));
  2330   2396     rc = sqlite3Select(pParse, pSetup, &destQueue);
  2331   2397     pSetup->pNext = p;
  2332   2398     if( rc ) goto end_of_recursive_query;
  2333   2399   
  2334   2400     /* Find the next row in the Queue and output that row */
  2335   2401     addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v);
  2336   2402   
................................................................................
  2357   2423     /* Execute the recursive SELECT taking the single row in Current as
  2358   2424     ** the value for the recursive-table. Store the results in the Queue.
  2359   2425     */
  2360   2426     if( p->selFlags & SF_Aggregate ){
  2361   2427       sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
  2362   2428     }else{
  2363   2429       p->pPrior = 0;
         2430  +    ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
  2364   2431       sqlite3Select(pParse, p, &destQueue);
  2365   2432       assert( p->pPrior==0 );
  2366   2433       p->pPrior = pSetup;
  2367   2434     }
  2368   2435   
  2369   2436     /* Keep running the loop until the Queue is empty */
  2370   2437     sqlite3VdbeGoto(v, addrTop);
................................................................................
  2402   2469   ** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
  2403   2470   */
  2404   2471   static int multiSelectValues(
  2405   2472     Parse *pParse,        /* Parsing context */
  2406   2473     Select *p,            /* The right-most of SELECTs to be coded */
  2407   2474     SelectDest *pDest     /* What to do with query results */
  2408   2475   ){
  2409         -  Select *pPrior;
  2410         -  Select *pRightmost = p;
  2411   2476     int nRow = 1;
  2412   2477     int rc = 0;
         2478  +  int bShowAll = p->pLimit==0;
  2413   2479     assert( p->selFlags & SF_MultiValue );
  2414   2480     do{
  2415   2481       assert( p->selFlags & SF_Values );
  2416   2482       assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
  2417   2483       assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
  2418   2484       if( p->pPrior==0 ) break;
  2419   2485       assert( p->pPrior->pNext==p );
  2420   2486       p = p->pPrior;
  2421         -    nRow++;
         2487  +    nRow += bShowAll;
  2422   2488     }while(1);
         2489  +  ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow,
         2490  +                    nRow==1 ? "" : "S"));
  2423   2491     while( p ){
  2424         -    pPrior = p->pPrior;
  2425         -    p->pPrior = 0;
  2426         -    rc = sqlite3Select(pParse, p, pDest);
  2427         -    p->pPrior = pPrior;
  2428         -    if( rc || pRightmost->pLimit ) break;
         2492  +    selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1);
         2493  +    if( !bShowAll ) break;
  2429   2494       p->nSelectRow = nRow;
  2430   2495       p = p->pNext;
  2431   2496     }
  2432   2497     return rc;
  2433   2498   }
  2434   2499   
  2435   2500   /*
................................................................................
  2470   2535   ){
  2471   2536     int rc = SQLITE_OK;   /* Success code from a subroutine */
  2472   2537     Select *pPrior;       /* Another SELECT immediately to our left */
  2473   2538     Vdbe *v;              /* Generate code to this VDBE */
  2474   2539     SelectDest dest;      /* Alternative data destination */
  2475   2540     Select *pDelete = 0;  /* Chain of simple selects to delete */
  2476   2541     sqlite3 *db;          /* Database connection */
  2477         -#ifndef SQLITE_OMIT_EXPLAIN
  2478         -  int iSub1 = 0;        /* EQP id of left-hand query */
  2479         -  int iSub2 = 0;        /* EQP id of right-hand query */
  2480         -#endif
  2481   2542   
  2482   2543     /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  2483   2544     ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  2484   2545     */
  2485   2546     assert( p && p->pPrior );  /* Calling function guarantees this much */
  2486   2547     assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
  2487   2548     db = pParse->db;
................................................................................
  2524   2585     }else
  2525   2586   #endif
  2526   2587   
  2527   2588     /* Compound SELECTs that have an ORDER BY clause are handled separately.
  2528   2589     */
  2529   2590     if( p->pOrderBy ){
  2530   2591       return multiSelectOrderBy(pParse, p, pDest);
  2531         -  }else
  2532         -
  2533         -  /* Generate code for the left and right SELECT statements.
  2534         -  */
  2535         -  switch( p->op ){
  2536         -    case TK_ALL: {
  2537         -      int addr = 0;
  2538         -      int nLimit;
  2539         -      assert( !pPrior->pLimit );
  2540         -      pPrior->iLimit = p->iLimit;
  2541         -      pPrior->iOffset = p->iOffset;
  2542         -      pPrior->pLimit = p->pLimit;
  2543         -      explainSetInteger(iSub1, pParse->iNextSelectId);
  2544         -      rc = sqlite3Select(pParse, pPrior, &dest);
  2545         -      p->pLimit = 0;
  2546         -      if( rc ){
  2547         -        goto multi_select_end;
  2548         -      }
  2549         -      p->pPrior = 0;
  2550         -      p->iLimit = pPrior->iLimit;
  2551         -      p->iOffset = pPrior->iOffset;
  2552         -      if( p->iLimit ){
  2553         -        addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
  2554         -        VdbeComment((v, "Jump ahead if LIMIT reached"));
  2555         -        if( p->iOffset ){
  2556         -          sqlite3VdbeAddOp3(v, OP_OffsetLimit,
  2557         -                            p->iLimit, p->iOffset+1, p->iOffset);
  2558         -        }
  2559         -      }
  2560         -      explainSetInteger(iSub2, pParse->iNextSelectId);
  2561         -      rc = sqlite3Select(pParse, p, &dest);
  2562         -      testcase( rc!=SQLITE_OK );
  2563         -      pDelete = p->pPrior;
  2564         -      p->pPrior = pPrior;
  2565         -      p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
  2566         -      if( pPrior->pLimit
  2567         -       && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
  2568         -       && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
  2569         -      ){
  2570         -        p->nSelectRow = sqlite3LogEst((u64)nLimit);
  2571         -      }
  2572         -      if( addr ){
  2573         -        sqlite3VdbeJumpHere(v, addr);
  2574         -      }
  2575         -      break;
  2576         -    }
  2577         -    case TK_EXCEPT:
  2578         -    case TK_UNION: {
  2579         -      int unionTab;    /* Cursor number of the temporary table holding result */
  2580         -      u8 op = 0;       /* One of the SRT_ operations to apply to self */
  2581         -      int priorOp;     /* The SRT_ operation to apply to prior selects */
  2582         -      Expr *pLimit;    /* Saved values of p->nLimit  */
  2583         -      int addr;
  2584         -      SelectDest uniondest;
  2585         -
  2586         -      testcase( p->op==TK_EXCEPT );
  2587         -      testcase( p->op==TK_UNION );
  2588         -      priorOp = SRT_Union;
  2589         -      if( dest.eDest==priorOp ){
  2590         -        /* We can reuse a temporary table generated by a SELECT to our
  2591         -        ** right.
  2592         -        */
  2593         -        assert( p->pLimit==0 );      /* Not allowed on leftward elements */
  2594         -        unionTab = dest.iSDParm;
  2595         -      }else{
  2596         -        /* We will need to create our own temporary table to hold the
  2597         -        ** intermediate results.
  2598         -        */
  2599         -        unionTab = pParse->nTab++;
         2592  +  }else{
         2593  +
         2594  +#ifndef SQLITE_OMIT_EXPLAIN
         2595  +    if( pPrior->pPrior==0 ){
         2596  +      ExplainQueryPlan((pParse, 1, "COMPOUND QUERY"));
         2597  +      ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY"));
         2598  +    }
         2599  +#endif
         2600  +
         2601  +    /* Generate code for the left and right SELECT statements.
         2602  +    */
         2603  +    switch( p->op ){
         2604  +      case TK_ALL: {
         2605  +        int addr = 0;
         2606  +        int nLimit;
         2607  +        assert( !pPrior->pLimit );
         2608  +        pPrior->iLimit = p->iLimit;
         2609  +        pPrior->iOffset = p->iOffset;
         2610  +        pPrior->pLimit = p->pLimit;
         2611  +        rc = sqlite3Select(pParse, pPrior, &dest);
         2612  +        p->pLimit = 0;
         2613  +        if( rc ){
         2614  +          goto multi_select_end;
         2615  +        }
         2616  +        p->pPrior = 0;
         2617  +        p->iLimit = pPrior->iLimit;
         2618  +        p->iOffset = pPrior->iOffset;
         2619  +        if( p->iLimit ){
         2620  +          addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
         2621  +          VdbeComment((v, "Jump ahead if LIMIT reached"));
         2622  +          if( p->iOffset ){
         2623  +            sqlite3VdbeAddOp3(v, OP_OffsetLimit,
         2624  +                              p->iLimit, p->iOffset+1, p->iOffset);
         2625  +          }
         2626  +        }
         2627  +        ExplainQueryPlan((pParse, 1, "UNION ALL"));
         2628  +        rc = sqlite3Select(pParse, p, &dest);
         2629  +        testcase( rc!=SQLITE_OK );
         2630  +        pDelete = p->pPrior;
         2631  +        p->pPrior = pPrior;
         2632  +        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
         2633  +        if( pPrior->pLimit
         2634  +         && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
         2635  +         && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
         2636  +        ){
         2637  +          p->nSelectRow = sqlite3LogEst((u64)nLimit);
         2638  +        }
         2639  +        if( addr ){
         2640  +          sqlite3VdbeJumpHere(v, addr);
         2641  +        }
         2642  +        break;
         2643  +      }
         2644  +      case TK_EXCEPT:
         2645  +      case TK_UNION: {
         2646  +        int unionTab;    /* Cursor number of the temp table holding result */
         2647  +        u8 op = 0;       /* One of the SRT_ operations to apply to self */
         2648  +        int priorOp;     /* The SRT_ operation to apply to prior selects */
         2649  +        Expr *pLimit;    /* Saved values of p->nLimit  */
         2650  +        int addr;
         2651  +        SelectDest uniondest;
         2652  +  
         2653  +        testcase( p->op==TK_EXCEPT );
         2654  +        testcase( p->op==TK_UNION );
         2655  +        priorOp = SRT_Union;
         2656  +        if( dest.eDest==priorOp ){
         2657  +          /* We can reuse a temporary table generated by a SELECT to our
         2658  +          ** right.
         2659  +          */
         2660  +          assert( p->pLimit==0 );      /* Not allowed on leftward elements */
         2661  +          unionTab = dest.iSDParm;
         2662  +        }else{
         2663  +          /* We will need to create our own temporary table to hold the
         2664  +          ** intermediate results.
         2665  +          */
         2666  +          unionTab = pParse->nTab++;
         2667  +          assert( p->pOrderBy==0 );
         2668  +          addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
         2669  +          assert( p->addrOpenEphm[0] == -1 );
         2670  +          p->addrOpenEphm[0] = addr;
         2671  +          findRightmost(p)->selFlags |= SF_UsesEphemeral;
         2672  +          assert( p->pEList );
         2673  +        }
         2674  +  
         2675  +        /* Code the SELECT statements to our left
         2676  +        */
         2677  +        assert( !pPrior->pOrderBy );
         2678  +        sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
         2679  +        rc = sqlite3Select(pParse, pPrior, &uniondest);
         2680  +        if( rc ){
         2681  +          goto multi_select_end;
         2682  +        }
         2683  +  
         2684  +        /* Code the current SELECT statement
         2685  +        */
         2686  +        if( p->op==TK_EXCEPT ){
         2687  +          op = SRT_Except;
         2688  +        }else{
         2689  +          assert( p->op==TK_UNION );
         2690  +          op = SRT_Union;
         2691  +        }
         2692  +        p->pPrior = 0;
         2693  +        pLimit = p->pLimit;
         2694  +        p->pLimit = 0;
         2695  +        uniondest.eDest = op;
         2696  +        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
         2697  +                          selectOpName(p->op)));
         2698  +        rc = sqlite3Select(pParse, p, &uniondest);
         2699  +        testcase( rc!=SQLITE_OK );
         2700  +        /* Query flattening in sqlite3Select() might refill p->pOrderBy.
         2701  +        ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
         2702  +        sqlite3ExprListDelete(db, p->pOrderBy);
         2703  +        pDelete = p->pPrior;
         2704  +        p->pPrior = pPrior;
         2705  +        p->pOrderBy = 0;
         2706  +        if( p->op==TK_UNION ){
         2707  +          p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
         2708  +        }
         2709  +        sqlite3ExprDelete(db, p->pLimit);
         2710  +        p->pLimit = pLimit;
         2711  +        p->iLimit = 0;
         2712  +        p->iOffset = 0;
         2713  +  
         2714  +        /* Convert the data in the temporary table into whatever form
         2715  +        ** it is that we currently need.
         2716  +        */
         2717  +        assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
         2718  +        if( dest.eDest!=priorOp ){
         2719  +          int iCont, iBreak, iStart;
         2720  +          assert( p->pEList );
         2721  +          iBreak = sqlite3VdbeMakeLabel(v);
         2722  +          iCont = sqlite3VdbeMakeLabel(v);
         2723  +          computeLimitRegisters(pParse, p, iBreak);
         2724  +          sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
         2725  +          iStart = sqlite3VdbeCurrentAddr(v);
         2726  +          selectInnerLoop(pParse, p, unionTab,
         2727  +                          0, 0, &dest, iCont, iBreak);
         2728  +          sqlite3VdbeResolveLabel(v, iCont);
         2729  +          sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
         2730  +          sqlite3VdbeResolveLabel(v, iBreak);
         2731  +          sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
         2732  +        }
         2733  +        break;
         2734  +      }
         2735  +      default: assert( p->op==TK_INTERSECT ); {
         2736  +        int tab1, tab2;
         2737  +        int iCont, iBreak, iStart;
         2738  +        Expr *pLimit;
         2739  +        int addr;
         2740  +        SelectDest intersectdest;
         2741  +        int r1;
         2742  +  
         2743  +        /* INTERSECT is different from the others since it requires
         2744  +        ** two temporary tables.  Hence it has its own case.  Begin
         2745  +        ** by allocating the tables we will need.
         2746  +        */
         2747  +        tab1 = pParse->nTab++;
         2748  +        tab2 = pParse->nTab++;
  2600   2749           assert( p->pOrderBy==0 );
  2601         -        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
         2750  +  
         2751  +        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
  2602   2752           assert( p->addrOpenEphm[0] == -1 );
  2603   2753           p->addrOpenEphm[0] = addr;
  2604   2754           findRightmost(p)->selFlags |= SF_UsesEphemeral;
  2605   2755           assert( p->pEList );
  2606         -      }
  2607         -
  2608         -      /* Code the SELECT statements to our left
  2609         -      */
  2610         -      assert( !pPrior->pOrderBy );
  2611         -      sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
  2612         -      explainSetInteger(iSub1, pParse->iNextSelectId);
  2613         -      rc = sqlite3Select(pParse, pPrior, &uniondest);
  2614         -      if( rc ){
  2615         -        goto multi_select_end;
  2616         -      }
  2617         -
  2618         -      /* Code the current SELECT statement
  2619         -      */
  2620         -      if( p->op==TK_EXCEPT ){
  2621         -        op = SRT_Except;
  2622         -      }else{
  2623         -        assert( p->op==TK_UNION );
  2624         -        op = SRT_Union;
  2625         -      }
  2626         -      p->pPrior = 0;
  2627         -      pLimit = p->pLimit;
  2628         -      p->pLimit = 0;
  2629         -      uniondest.eDest = op;
  2630         -      explainSetInteger(iSub2, pParse->iNextSelectId);
  2631         -      rc = sqlite3Select(pParse, p, &uniondest);
  2632         -      testcase( rc!=SQLITE_OK );
  2633         -      /* Query flattening in sqlite3Select() might refill p->pOrderBy.
  2634         -      ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
  2635         -      sqlite3ExprListDelete(db, p->pOrderBy);
  2636         -      pDelete = p->pPrior;
  2637         -      p->pPrior = pPrior;
  2638         -      p->pOrderBy = 0;
  2639         -      if( p->op==TK_UNION ){
  2640         -        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
  2641         -      }
  2642         -      sqlite3ExprDelete(db, p->pLimit);
  2643         -      p->pLimit = pLimit;
  2644         -      p->iLimit = 0;
  2645         -      p->iOffset = 0;
  2646         -
  2647         -      /* Convert the data in the temporary table into whatever form
  2648         -      ** it is that we currently need.
  2649         -      */
  2650         -      assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
  2651         -      if( dest.eDest!=priorOp ){
  2652         -        int iCont, iBreak, iStart;
         2756  +  
         2757  +        /* Code the SELECTs to our left into temporary table "tab1".
         2758  +        */
         2759  +        sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
         2760  +        rc = sqlite3Select(pParse, pPrior, &intersectdest);
         2761  +        if( rc ){
         2762  +          goto multi_select_end;
         2763  +        }
         2764  +  
         2765  +        /* Code the current SELECT into temporary table "tab2"
         2766  +        */
         2767  +        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
         2768  +        assert( p->addrOpenEphm[1] == -1 );
         2769  +        p->addrOpenEphm[1] = addr;
         2770  +        p->pPrior = 0;
         2771  +        pLimit = p->pLimit;
         2772  +        p->pLimit = 0;
         2773  +        intersectdest.iSDParm = tab2;
         2774  +        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
         2775  +                          selectOpName(p->op)));
         2776  +        rc = sqlite3Select(pParse, p, &intersectdest);
         2777  +        testcase( rc!=SQLITE_OK );
         2778  +        pDelete = p->pPrior;
         2779  +        p->pPrior = pPrior;
         2780  +        if( p->nSelectRow>pPrior->nSelectRow ){
         2781  +          p->nSelectRow = pPrior->nSelectRow;
         2782  +        }
         2783  +        sqlite3ExprDelete(db, p->pLimit);
         2784  +        p->pLimit = pLimit;
         2785  +  
         2786  +        /* Generate code to take the intersection of the two temporary
         2787  +        ** tables.
         2788  +        */
  2653   2789           assert( p->pEList );
  2654   2790           iBreak = sqlite3VdbeMakeLabel(v);
  2655   2791           iCont = sqlite3VdbeMakeLabel(v);
  2656   2792           computeLimitRegisters(pParse, p, iBreak);
  2657         -        sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
  2658         -        iStart = sqlite3VdbeCurrentAddr(v);
  2659         -        selectInnerLoop(pParse, p, unionTab,
         2793  +        sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
         2794  +        r1 = sqlite3GetTempReg(pParse);
         2795  +        iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
         2796  +        sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
         2797  +        VdbeCoverage(v);
         2798  +        sqlite3ReleaseTempReg(pParse, r1);
         2799  +        selectInnerLoop(pParse, p, tab1,
  2660   2800                           0, 0, &dest, iCont, iBreak);
  2661   2801           sqlite3VdbeResolveLabel(v, iCont);
  2662         -        sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
         2802  +        sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
  2663   2803           sqlite3VdbeResolveLabel(v, iBreak);
  2664         -        sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
  2665         -      }
  2666         -      break;
  2667         -    }
  2668         -    default: assert( p->op==TK_INTERSECT ); {
  2669         -      int tab1, tab2;
  2670         -      int iCont, iBreak, iStart;
  2671         -      Expr *pLimit;
  2672         -      int addr;
  2673         -      SelectDest intersectdest;
  2674         -      int r1;
  2675         -
  2676         -      /* INTERSECT is different from the others since it requires
  2677         -      ** two temporary tables.  Hence it has its own case.  Begin
  2678         -      ** by allocating the tables we will need.
  2679         -      */
  2680         -      tab1 = pParse->nTab++;
  2681         -      tab2 = pParse->nTab++;
  2682         -      assert( p->pOrderBy==0 );
  2683         -
  2684         -      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
  2685         -      assert( p->addrOpenEphm[0] == -1 );
  2686         -      p->addrOpenEphm[0] = addr;
  2687         -      findRightmost(p)->selFlags |= SF_UsesEphemeral;
  2688         -      assert( p->pEList );
  2689         -
  2690         -      /* Code the SELECTs to our left into temporary table "tab1".
  2691         -      */
  2692         -      sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
  2693         -      explainSetInteger(iSub1, pParse->iNextSelectId);
  2694         -      rc = sqlite3Select(pParse, pPrior, &intersectdest);
  2695         -      if( rc ){
  2696         -        goto multi_select_end;
  2697         -      }
  2698         -
  2699         -      /* Code the current SELECT into temporary table "tab2"
  2700         -      */
  2701         -      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
  2702         -      assert( p->addrOpenEphm[1] == -1 );
  2703         -      p->addrOpenEphm[1] = addr;
  2704         -      p->pPrior = 0;
  2705         -      pLimit = p->pLimit;
  2706         -      p->pLimit = 0;
  2707         -      intersectdest.iSDParm = tab2;
  2708         -      explainSetInteger(iSub2, pParse->iNextSelectId);
  2709         -      rc = sqlite3Select(pParse, p, &intersectdest);
  2710         -      testcase( rc!=SQLITE_OK );
  2711         -      pDelete = p->pPrior;
  2712         -      p->pPrior = pPrior;
  2713         -      if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
  2714         -      sqlite3ExprDelete(db, p->pLimit);
  2715         -      p->pLimit = pLimit;
  2716         -
  2717         -      /* Generate code to take the intersection of the two temporary
  2718         -      ** tables.
  2719         -      */
  2720         -      assert( p->pEList );
  2721         -      iBreak = sqlite3VdbeMakeLabel(v);
  2722         -      iCont = sqlite3VdbeMakeLabel(v);
  2723         -      computeLimitRegisters(pParse, p, iBreak);
  2724         -      sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
  2725         -      r1 = sqlite3GetTempReg(pParse);
  2726         -      iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
  2727         -      sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
  2728         -      sqlite3ReleaseTempReg(pParse, r1);
  2729         -      selectInnerLoop(pParse, p, tab1,
  2730         -                      0, 0, &dest, iCont, iBreak);
  2731         -      sqlite3VdbeResolveLabel(v, iCont);
  2732         -      sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
  2733         -      sqlite3VdbeResolveLabel(v, iBreak);
  2734         -      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
  2735         -      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
  2736         -      break;
  2737         -    }
  2738         -  }
  2739         -
  2740         -  explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
  2741         -
         2804  +        sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
         2805  +        sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
         2806  +        break;
         2807  +      }
         2808  +    }
         2809  +  
         2810  +  #ifndef SQLITE_OMIT_EXPLAIN
         2811  +    if( p->pNext==0 ){
         2812  +      ExplainQueryPlanPop(pParse);
         2813  +    }
         2814  +  #endif
         2815  +  }
         2816  +  
  2742   2817     /* Compute collating sequences used by 
  2743   2818     ** temporary tables needed to implement the compound select.
  2744   2819     ** Attach the KeyInfo structure to all temporary tables.
  2745   2820     **
  2746   2821     ** This section is run by the right-most SELECT statement only.
  2747   2822     ** SELECT statements to the left always skip this part.  The right-most
  2748   2823     ** SELECT might also skip this part if it has no ORDER BY clause and
................................................................................
  3072   3147     int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
  3073   3148     KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
  3074   3149     KeyInfo *pKeyMerge;   /* Comparison information for merging rows */
  3075   3150     sqlite3 *db;          /* Database connection */
  3076   3151     ExprList *pOrderBy;   /* The ORDER BY clause */
  3077   3152     int nOrderBy;         /* Number of terms in the ORDER BY clause */
  3078   3153     int *aPermute;        /* Mapping from ORDER BY terms to result set columns */
  3079         -#ifndef SQLITE_OMIT_EXPLAIN
  3080         -  int iSub1;            /* EQP id of left-hand query */
  3081         -  int iSub2;            /* EQP id of right-hand query */
  3082         -#endif
  3083   3154   
  3084   3155     assert( p->pOrderBy!=0 );
  3085   3156     assert( pKeyDup==0 ); /* "Managed" code needs this.  Ticket #3382. */
  3086   3157     db = pParse->db;
  3087   3158     v = pParse->pVdbe;
  3088   3159     assert( v!=0 );       /* Already thrown the error if VDBE alloc failed */
  3089   3160     labelEnd = sqlite3VdbeMakeLabel(v);
................................................................................
  3195   3266     regAddrA = ++pParse->nMem;
  3196   3267     regAddrB = ++pParse->nMem;
  3197   3268     regOutA = ++pParse->nMem;
  3198   3269     regOutB = ++pParse->nMem;
  3199   3270     sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
  3200   3271     sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
  3201   3272   
         3273  +  ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op)));
         3274  +
  3202   3275     /* Generate a coroutine to evaluate the SELECT statement to the
  3203   3276     ** left of the compound operator - the "A" select.
  3204   3277     */
  3205   3278     addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
  3206   3279     addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
  3207   3280     VdbeComment((v, "left SELECT"));
  3208   3281     pPrior->iLimit = regLimitA;
  3209         -  explainSetInteger(iSub1, pParse->iNextSelectId);
         3282  +  ExplainQueryPlan((pParse, 1, "LEFT"));
  3210   3283     sqlite3Select(pParse, pPrior, &destA);
  3211   3284     sqlite3VdbeEndCoroutine(v, regAddrA);
  3212   3285     sqlite3VdbeJumpHere(v, addr1);
  3213   3286   
  3214   3287     /* Generate a coroutine to evaluate the SELECT statement on 
  3215   3288     ** the right - the "B" select
  3216   3289     */
................................................................................
  3217   3290     addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
  3218   3291     addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
  3219   3292     VdbeComment((v, "right SELECT"));
  3220   3293     savedLimit = p->iLimit;
  3221   3294     savedOffset = p->iOffset;
  3222   3295     p->iLimit = regLimitB;
  3223   3296     p->iOffset = 0;  
  3224         -  explainSetInteger(iSub2, pParse->iNextSelectId);
         3297  +  ExplainQueryPlan((pParse, 1, "RIGHT"));
  3225   3298     sqlite3Select(pParse, p, &destB);
  3226   3299     p->iLimit = savedLimit;
  3227   3300     p->iOffset = savedOffset;
  3228   3301     sqlite3VdbeEndCoroutine(v, regAddrB);
  3229   3302   
  3230   3303     /* Generate a subroutine that outputs the current row of the A
  3231   3304     ** select as the next output row of the compound select.
................................................................................
  3329   3402       sqlite3SelectDelete(db, p->pPrior);
  3330   3403     }
  3331   3404     p->pPrior = pPrior;
  3332   3405     pPrior->pNext = p;
  3333   3406   
  3334   3407     /*** TBD:  Insert subroutine calls to close cursors on incomplete
  3335   3408     **** subqueries ****/
  3336         -  explainComposite(pParse, p->op, iSub1, iSub2, 0);
         3409  +  ExplainQueryPlanPop(pParse);
  3337   3410     return pParse->nErr!=0;
  3338   3411   }
  3339   3412   #endif
  3340   3413   
  3341   3414   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  3342   3415   
  3343   3416   /* An instance of the SubstContext object describes an substitution edit
................................................................................
  5117   5190   static void explainSimpleCount(
  5118   5191     Parse *pParse,                  /* Parse context */
  5119   5192     Table *pTab,                    /* Table being queried */
  5120   5193     Index *pIdx                     /* Index used to optimize scan, or NULL */
  5121   5194   ){
  5122   5195     if( pParse->explain==2 ){
  5123   5196       int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
  5124         -    char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
         5197  +    sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s",
  5125   5198           pTab->zName,
  5126   5199           bCover ? " USING COVERING INDEX " : "",
  5127   5200           bCover ? pIdx->zName : ""
  5128   5201       );
  5129         -    sqlite3VdbeAddOp4(
  5130         -        pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
  5131         -    );
  5132   5202     }
  5133   5203   }
  5134   5204   #else
  5135   5205   # define explainSimpleCount(a,b,c)
  5136   5206   #endif
  5137   5207   
  5138   5208   /*
................................................................................
  5337   5407     SortCtx sSort;         /* Info on how to code the ORDER BY clause */
  5338   5408     AggInfo sAggInfo;      /* Information used by aggregate queries */
  5339   5409     int iEnd;              /* Address of the end of the query */
  5340   5410     sqlite3 *db;           /* The database connection */
  5341   5411     ExprList *pMinMaxOrderBy = 0;  /* Added ORDER BY for min/max queries */
  5342   5412     u8 minMaxFlag;                 /* Flag for min/max queries */
  5343   5413   
  5344         -#ifndef SQLITE_OMIT_EXPLAIN
  5345         -  int iRestoreSelectId = pParse->iSelectId;
  5346         -  pParse->iSelectId = pParse->iNextSelectId++;
  5347         -#endif
  5348         -
  5349   5414     db = pParse->db;
         5415  +  v = sqlite3GetVdbe(pParse);
  5350   5416     if( p==0 || db->mallocFailed || pParse->nErr ){
  5351   5417       return 1;
  5352   5418     }
  5353   5419     if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  5354   5420     memset(&sAggInfo, 0, sizeof(sAggInfo));
  5355   5421   #if SELECTTRACE_ENABLED
  5356         -#ifndef SQLITE_OMIT_EXPLAIN
  5357         -  p->iSelectId = pParse->iSelectId;
  5358         -#endif
  5359         -  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->iSelectId));
         5422  +  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
  5360   5423     if( sqlite3SelectTrace & 0x100 ){
  5361   5424       sqlite3TreeViewSelect(0, p, 0);
  5362   5425     }
  5363   5426   #endif
  5364   5427   
  5365   5428     assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
  5366   5429     assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
................................................................................
  5389   5452   #if SELECTTRACE_ENABLED
  5390   5453     if( sqlite3SelectTrace & 0x104 ){
  5391   5454       SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
  5392   5455       sqlite3TreeViewSelect(0, p, 0);
  5393   5456     }
  5394   5457   #endif
  5395   5458   
  5396         -  /* Get a pointer the VDBE under construction, allocating a new VDBE if one
  5397         -  ** does not already exist */
  5398         -  v = sqlite3GetVdbe(pParse);
  5399         -  if( v==0 ) goto select_end;
  5400   5459     if( pDest->eDest==SRT_Output ){
  5401   5460       generateColumnNames(pParse, p);
  5402   5461     }
  5403   5462   
  5404   5463     /* Try to various optimizations (flattening subqueries, and strength
  5405   5464     ** reduction of join operators) in the FROM clause up into the main query
  5406   5465     */
................................................................................
  5487   5546     /* Handle compound SELECT statements using the separate multiSelect()
  5488   5547     ** procedure.
  5489   5548     */
  5490   5549     if( p->pPrior ){
  5491   5550       rc = multiSelect(pParse, p, pDest);
  5492   5551   #if SELECTTRACE_ENABLED
  5493   5552       SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
  5494         -    if( pParse->iSelectId==0 && (sqlite3SelectTrace & 0x2000)!=0 ){
         5553  +    if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
  5495   5554         sqlite3TreeViewSelect(0, p, 0);
  5496   5555       }
  5497   5556   #endif
  5498         -    explainSetInteger(pParse->iSelectId, iRestoreSelectId);
         5557  +    if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
  5499   5558       return rc;
  5500   5559     }
  5501   5560   #endif
  5502   5561   
  5503   5562     /* For each term in the FROM clause, do two things:
  5504   5563     ** (1) Authorized unreferenced tables
  5505   5564     ** (2) Generate code for all sub-queries
................................................................................
  5603   5662         int addrTop = sqlite3VdbeCurrentAddr(v)+1;
  5604   5663        
  5605   5664         pItem->regReturn = ++pParse->nMem;
  5606   5665         sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
  5607   5666         VdbeComment((v, "%s", pItem->pTab->zName));
  5608   5667         pItem->addrFillSub = addrTop;
  5609   5668         sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
  5610         -      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
         5669  +      ExplainQueryPlan((pParse, 1, "CO-ROUTINE 0x%p", pSub));
  5611   5670         sqlite3Select(pParse, pSub, &dest);
  5612   5671         pItem->pTab->nRowLogEst = pSub->nSelectRow;
  5613   5672         pItem->fg.viaCoroutine = 1;
  5614   5673         pItem->regResult = dest.iSdst;
  5615   5674         sqlite3VdbeEndCoroutine(v, pItem->regReturn);
  5616   5675         sqlite3VdbeJumpHere(v, addrTop-1);
  5617   5676         sqlite3ClearTempRegCache(pParse);
................................................................................
  5638   5697           VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
  5639   5698         }else{
  5640   5699           VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
  5641   5700         }
  5642   5701         pPrior = isSelfJoinView(pTabList, pItem);
  5643   5702         if( pPrior ){
  5644   5703           sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
  5645         -        explainSetInteger(pItem->iSelectId, pPrior->iSelectId);
  5646   5704           assert( pPrior->pSelect!=0 );
  5647   5705           pSub->nSelectRow = pPrior->pSelect->nSelectRow;
  5648   5706         }else{
  5649   5707           sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
  5650         -        explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
         5708  +        ExplainQueryPlan((pParse, 1, "MATERIALIZE 0x%p", pSub));
  5651   5709           sqlite3Select(pParse, pSub, &dest);
  5652   5710         }
  5653   5711         pItem->pTab->nRowLogEst = pSub->nSelectRow;
  5654   5712         if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
  5655   5713         retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
  5656   5714         VdbeComment((v, "end %s", pItem->pTab->zName));
  5657   5715         sqlite3VdbeChangeP1(v, topAddr, retAddr);
................................................................................
  6281   6339     */
  6282   6340   select_end:
  6283   6341     sqlite3ExprListDelete(db, pMinMaxOrderBy);
  6284   6342     sqlite3DbFree(db, sAggInfo.aCol);
  6285   6343     sqlite3DbFree(db, sAggInfo.aFunc);
  6286   6344   #if SELECTTRACE_ENABLED
  6287   6345     SELECTTRACE(0x1,pParse,p,("end processing\n"));
  6288         -  if( pParse->iSelectId==0 && (sqlite3SelectTrace & 0x2000)!=0 ){
         6346  +  if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
  6289   6347       sqlite3TreeViewSelect(0, p, 0);
  6290   6348     }
  6291   6349   #endif
  6292         -  explainSetInteger(pParse->iSelectId, iRestoreSelectId);
         6350  +  ExplainQueryPlanPop(pParse);
  6293   6351     return rc;
  6294   6352   }

Changes to src/shell.c.in.

   977    977     sqlite3expert *pExpert;
   978    978     int bVerbose;
   979    979   };
   980    980   
   981    981   /* A single line in the EQP output */
   982    982   typedef struct EQPGraphRow EQPGraphRow;
   983    983   struct EQPGraphRow {
   984         -  int iSelectId;        /* The SelectID for this row */
          984  +  int iEqpId;           /* ID for this row */
          985  +  int iParentId;        /* ID of the parent row */
   985    986     EQPGraphRow *pNext;   /* Next row in sequence */
   986    987     char zText[1];        /* Text to display for this row */
   987    988   };
   988    989   
   989    990   /* All EQP output is collected into an instance of the following */
   990    991   typedef struct EQPGraph EQPGraph;
   991    992   struct EQPGraph {
................................................................................
   999   1000   ** instance of the following structure.
  1000   1001   */
  1001   1002   typedef struct ShellState ShellState;
  1002   1003   struct ShellState {
  1003   1004     sqlite3 *db;           /* The database */
  1004   1005     u8 autoExplain;        /* Automatically turn on .explain mode */
  1005   1006     u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
         1007  +  u8 autoEQPtest;        /* autoEQP is in test mode */
  1006   1008     u8 statsOn;            /* True to display memory stats before each finalize */
  1007   1009     u8 scanstatsOn;        /* True to display scan stats before each finalize */
  1008   1010     u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
  1009   1011     u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
  1010   1012     u8 nEqpLevel;          /* Depth of the EQP output graph */
  1011   1013     unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
  1012   1014     int outCount;          /* Revert to stdout when reaching zero */
................................................................................
  1049   1051   #endif
  1050   1052     ExpertInfo expert;        /* Valid if previous command was ".expert OPT..." */
  1051   1053   };
  1052   1054   
  1053   1055   
  1054   1056   /* Allowed values for ShellState.autoEQP
  1055   1057   */
  1056         -#define AUTOEQP_off      0
  1057         -#define AUTOEQP_on       1
  1058         -#define AUTOEQP_trigger  2
  1059         -#define AUTOEQP_full     3
         1058  +#define AUTOEQP_off      0           /* Automatic EXPLAIN QUERY PLAN is off */
         1059  +#define AUTOEQP_on       1           /* Automatic EQP is on */
         1060  +#define AUTOEQP_trigger  2           /* On and also show plans for triggers */
         1061  +#define AUTOEQP_full     3           /* Show full EXPLAIN */
  1060   1062   
  1061   1063   /* Allowed values for ShellState.openMode
  1062   1064   */
  1063   1065   #define SHELL_OPEN_UNSPEC     0      /* No open-mode specified */
  1064   1066   #define SHELL_OPEN_NORMAL     1      /* Normal database file */
  1065   1067   #define SHELL_OPEN_APPENDVFS  2      /* Use appendvfs */
  1066   1068   #define SHELL_OPEN_ZIPFILE    3      /* Use the zipfile virtual table */
................................................................................
  1663   1665     }
  1664   1666     return 1;
  1665   1667   }
  1666   1668   
  1667   1669   /*
  1668   1670   ** Add a new entry to the EXPLAIN QUERY PLAN data
  1669   1671   */
  1670         -static void eqp_append(ShellState *p, int iSelectId, const char *zText){
         1672  +static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
  1671   1673     EQPGraphRow *pNew;
  1672   1674     int nText = strlen30(zText);
         1675  +  if( p->autoEQPtest ){
         1676  +    utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
         1677  +  }
  1673   1678     pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
  1674   1679     if( pNew==0 ) shell_out_of_memory();
  1675         -  pNew->iSelectId = iSelectId;
         1680  +  pNew->iEqpId = iEqpId;
         1681  +  pNew->iParentId = p2;
  1676   1682     memcpy(pNew->zText, zText, nText+1);
  1677   1683     pNew->pNext = 0;
  1678   1684     if( p->sGraph.pLast ){
  1679   1685       p->sGraph.pLast->pNext = pNew;
  1680   1686     }else{
  1681   1687       p->sGraph.pRow = pNew;
  1682   1688     }
................................................................................
  1692   1698     for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
  1693   1699       pNext = pRow->pNext;
  1694   1700       sqlite3_free(pRow);
  1695   1701     }
  1696   1702     memset(&p->sGraph, 0, sizeof(p->sGraph));
  1697   1703   }
  1698   1704   
  1699         -/* Return the next EXPLAIN QUERY PLAN line with iSelectId that occurs after
         1705  +/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
  1700   1706   ** pOld, or return the first such line if pOld is NULL
  1701   1707   */
  1702         -static EQPGraphRow *eqp_next_row(ShellState *p, int iSelectId, EQPGraphRow *pOld){
         1708  +static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
  1703   1709     EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
  1704         -  while( pRow && pRow->iSelectId!=iSelectId ) pRow = pRow->pNext;
         1710  +  while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
  1705   1711     return pRow;
  1706   1712   }
  1707   1713   
  1708         -/* Render a single level of the graph shell having iSelectId.  Called
         1714  +/* Render a single level of the graph that has iEqpId as its parent.  Called
  1709   1715   ** recursively to render sublevels.
  1710   1716   */
  1711         -static void eqp_render_level(ShellState *p, int iSelectId){
         1717  +static void eqp_render_level(ShellState *p, int iEqpId){
  1712   1718     EQPGraphRow *pRow, *pNext;
  1713         -  int i;
  1714   1719     int n = strlen30(p->sGraph.zPrefix);
  1715   1720     char *z;
  1716         -  for(pRow = eqp_next_row(p, iSelectId, 0); pRow; pRow = pNext){
  1717         -    pNext = eqp_next_row(p, iSelectId, pRow);
         1721  +  for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
         1722  +    pNext = eqp_next_row(p, iEqpId, pRow);
  1718   1723       z = pRow->zText;
  1719   1724       utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
  1720         -    if( n<sizeof(p->sGraph.zPrefix)-7 && (z = strstr(z, " SUBQUER"))!=0 ){
         1725  +    if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
  1721   1726         memcpy(&p->sGraph.zPrefix[n], pNext ? "|  " : "   ", 4);
  1722         -      if( strncmp(z, " SUBQUERY ", 9)==0 && (i = atoi(z+10))>iSelectId ){
  1723         -        eqp_render_level(p, i);
  1724         -      }else if( strncmp(z, " SUBQUERIES ", 12)==0 ){
  1725         -        i = atoi(z+12);
  1726         -        if( i>iSelectId ){
  1727         -          utf8_printf(p->out, "%s|--SUBQUERY %d\n", p->sGraph.zPrefix, i);
  1728         -          memcpy(&p->sGraph.zPrefix[n+3],"|  ",4);
  1729         -          eqp_render_level(p, i);
  1730         -        }
  1731         -        z = strstr(z, " AND ");
  1732         -        if( z && (i = atoi(z+5))>iSelectId ){
  1733         -          p->sGraph.zPrefix[n+3] = 0;
  1734         -          utf8_printf(p->out, "%s`--SUBQUERY %d\n", p->sGraph.zPrefix, i);
  1735         -          memcpy(&p->sGraph.zPrefix[n+3],"   ",4);
  1736         -          eqp_render_level(p, i);
  1737         -        }
  1738         -      }
         1727  +      eqp_render_level(p, pRow->iEqpId);
  1739   1728         p->sGraph.zPrefix[n] = 0;
  1740   1729       }
  1741   1730     }
  1742   1731   }
  1743   1732   
  1744   1733   /*
  1745   1734   ** Display and reset the EXPLAIN QUERY PLAN data
................................................................................
  2110   2099           if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
  2111   2100           utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
  2112   2101         }
  2113   2102         utf8_printf(p->out, "%s", p->rowSeparator);
  2114   2103         break;
  2115   2104       }
  2116   2105       case MODE_EQP: {
  2117         -      eqp_append(p, atoi(azArg[0]), azArg[3]);
         2106  +      eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
  2118   2107         break;
  2119   2108       }
  2120   2109     }
  2121   2110     return 0;
  2122   2111   }
  2123   2112   
  2124   2113   /*
................................................................................
  2952   2941             sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
  2953   2942           }
  2954   2943           zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
  2955   2944           rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
  2956   2945           if( rc==SQLITE_OK ){
  2957   2946             while( sqlite3_step(pExplain)==SQLITE_ROW ){
  2958   2947               const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
  2959         -            int iSelectId = sqlite3_column_int(pExplain, 0);
         2948  +            int iEqpId = sqlite3_column_int(pExplain, 0);
         2949  +            int iParentId = sqlite3_column_int(pExplain, 1);
  2960   2950               if( zEQPLine[0]=='-' ) eqp_render(pArg);
  2961         -            eqp_append(pArg, iSelectId, zEQPLine);
         2951  +            eqp_append(pArg, iEqpId, iParentId, zEQPLine);
  2962   2952             }
  2963   2953             eqp_render(pArg);
  2964   2954           }
  2965   2955           sqlite3_finalize(pExplain);
  2966   2956           sqlite3_free(zEQP);
  2967   2957           if( pArg->autoEQP>=AUTOEQP_full ){
  2968   2958             /* Also do an EXPLAIN for ".eqp full" mode */
................................................................................
  3329   3319   #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  3330   3320     ".archive ...           Manage SQL archives: \".archive --help\" for details\n"
  3331   3321   #endif
  3332   3322   #ifndef SQLITE_OMIT_AUTHORIZATION
  3333   3323     ".auth ON|OFF           Show authorizer callbacks\n"
  3334   3324   #endif
  3335   3325     ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
         3326  +  "                         Add \"--append\" to open using appendvfs.\n"
  3336   3327     ".bail on|off           Stop after hitting an error.  Default OFF\n"
  3337   3328     ".binary on|off         Turn binary output on or off.  Default OFF\n"
  3338   3329     ".cd DIRECTORY          Change the working directory to DIRECTORY\n"
  3339   3330     ".changes on|off        Show number of rows changed by SQL\n"
  3340   3331     ".check GLOB            Fail if output since .testcase does not match\n"
  3341   3332     ".clone NEWDB           Clone data into NEWDB from the existing database\n"
  3342   3333     ".databases             List names and files of attached databases\n"
         3334  +  ".dbconfig ?op? ?val?   List or change sqlite3_db_config() options\n"
  3343   3335     ".dbinfo ?DB?           Show status information about the database\n"
  3344   3336     ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
  3345   3337     "                         If TABLE specified, only dump tables matching\n"
  3346   3338     "                         LIKE pattern TABLE.\n"
  3347   3339     ".echo on|off           Turn command echo on or off\n"
  3348   3340     ".eqp on|off|full       Enable or disable automatic EXPLAIN QUERY PLAN\n"
  3349   3341     ".excel                 Display the output of next command in a spreadsheet\n"
................................................................................
  3545   3537   ** one of the SHELL_OPEN_* constants.
  3546   3538   **
  3547   3539   ** If the file does not exist or is empty but its name looks like a ZIP
  3548   3540   ** archive and the dfltZip flag is true, then assume it is a ZIP archive.
  3549   3541   ** Otherwise, assume an ordinary database regardless of the filename if
  3550   3542   ** the type cannot be determined from content.
  3551   3543   */
  3552         -static int deduceDatabaseType(const char *zName, int dfltZip){
         3544  +int deduceDatabaseType(const char *zName, int dfltZip){
  3553   3545     FILE *f = fopen(zName, "rb");
  3554   3546     size_t n;
  3555   3547     int rc = SHELL_OPEN_UNSPEC;
  3556   3548     char zBuf[100];
  3557   3549     if( f==0 ){
  3558   3550       if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ) return SHELL_OPEN_ZIPFILE;
  3559   3551       return SHELL_OPEN_NORMAL;
................................................................................
  3565   3557     }else{
  3566   3558       fseek(f, -22, SEEK_END);
  3567   3559       n = fread(zBuf, 22, 1, f);
  3568   3560       if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
  3569   3561          && zBuf[3]==0x06 ){
  3570   3562         rc = SHELL_OPEN_ZIPFILE;
  3571   3563       }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
  3572         -      return SHELL_OPEN_ZIPFILE;
         3564  +      rc = SHELL_OPEN_ZIPFILE;
  3573   3565       }
  3574   3566     }
  3575   3567     fclose(f);
  3576   3568     return rc;  
  3577   3569   }
  3578   3570   
  3579   3571   /*
  3580   3572   ** Make sure the database is open.  If it is not, then open it.  If
  3581   3573   ** the database fails to open, print an error message and exit.
  3582   3574   */
  3583   3575   static void open_db(ShellState *p, int keepAlive){
  3584   3576     if( p->db==0 ){
  3585         -    if( p->openMode==SHELL_OPEN_UNSPEC && access(p->zDbFilename,0)==0 ){
  3586         -      p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 0);
         3577  +    if( p->openMode==SHELL_OPEN_UNSPEC ){
         3578  +      if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
         3579  +        p->openMode = SHELL_OPEN_NORMAL;
         3580  +      }else if( access(p->zDbFilename,0)==0 ){
         3581  +        p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 0);
         3582  +      }
  3587   3583       }
  3588   3584       switch( p->openMode ){
  3589   3585         case SHELL_OPEN_APPENDVFS: {
  3590   3586           sqlite3_open_v2(p->zDbFilename, &p->db, 
  3591   3587              SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
  3592   3588           break;
  3593   3589         }
................................................................................
  3680   3676     int nLine = strlen30(zLine);
  3681   3677     int i, iStart;
  3682   3678     sqlite3_stmt *pStmt = 0;
  3683   3679     char *zSql;
  3684   3680     char zBuf[1000];
  3685   3681   
  3686   3682     if( nLine>sizeof(zBuf)-30 ) return;
  3687         -  if( zLine[0]=='.' ) return;
         3683  +  if( zLine[0]=='.' || zLine[0]=='#') return;
  3688   3684     for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
  3689   3685     if( i==nLine-1 ) return;
  3690   3686     iStart = i+1;
  3691   3687     memcpy(zBuf, zLine, iStart);
  3692   3688     zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
  3693   3689                            "  FROM completion(%Q,%Q) ORDER BY 1",
  3694   3690                            &zLine[iStart], zLine);
................................................................................
  5621   5617      || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
  5622   5618     ){
  5623   5619       const char *zDestFile = 0;
  5624   5620       const char *zDb = 0;
  5625   5621       sqlite3 *pDest;
  5626   5622       sqlite3_backup *pBackup;
  5627   5623       int j;
         5624  +    const char *zVfs = 0;
  5628   5625       for(j=1; j<nArg; j++){
  5629   5626         const char *z = azArg[j];
  5630   5627         if( z[0]=='-' ){
  5631         -        while( z[0]=='-' ) z++;
  5632         -        /* No options to process at this time */
         5628  +        if( z[1]=='-' ) z++;
         5629  +        if( strcmp(z, "-append")==0 ){
         5630  +          zVfs = "apndvfs";
         5631  +        }else
  5633   5632           {
  5634   5633             utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
  5635   5634             return 1;
  5636   5635           }
  5637   5636         }else if( zDestFile==0 ){
  5638   5637           zDestFile = azArg[j];
  5639   5638         }else if( zDb==0 ){
  5640   5639           zDb = zDestFile;
  5641   5640           zDestFile = azArg[j];
  5642   5641         }else{
  5643         -        raw_printf(stderr, "too many arguments to .backup\n");
         5642  +        raw_printf(stderr, "Usage: .backup ?DB? ?--append? FILENAME\n");
  5644   5643           return 1;
  5645   5644         }
  5646   5645       }
  5647   5646       if( zDestFile==0 ){
  5648   5647         raw_printf(stderr, "missing FILENAME argument on .backup\n");
  5649   5648         return 1;
  5650   5649       }
  5651   5650       if( zDb==0 ) zDb = "main";
  5652         -    rc = sqlite3_open(zDestFile, &pDest);
         5651  +    rc = sqlite3_open_v2(zDestFile, &pDest, 
         5652  +                  SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
  5653   5653       if( rc!=SQLITE_OK ){
  5654   5654         utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
  5655   5655         sqlite3_close(pDest);
  5656   5656         return 1;
  5657   5657       }
  5658   5658       open_db(p, 0);
  5659   5659       pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
................................................................................
  5778   5778       if( zErrMsg ){
  5779   5779         utf8_printf(stderr,"Error: %s\n", zErrMsg);
  5780   5780         sqlite3_free(zErrMsg);
  5781   5781         rc = 1;
  5782   5782       }
  5783   5783     }else
  5784   5784   
  5785         -  if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
         5785  +  if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
         5786  +    static const struct DbConfigChoices {const char *zName; int op;} aDbConfig[] = {
         5787  +        { "enable_fkey",      SQLITE_DBCONFIG_ENABLE_FKEY            },
         5788  +        { "enable_trigger",   SQLITE_DBCONFIG_ENABLE_TRIGGER         },
         5789  +        { "fts3_tokenizer",   SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER  },
         5790  +        { "load_extension",   SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION  },
         5791  +        { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE       },
         5792  +        { "enable_qpsg",      SQLITE_DBCONFIG_ENABLE_QPSG            },
         5793  +        { "trigger_eqp",      SQLITE_DBCONFIG_TRIGGER_EQP            },
         5794  +        { "reset_database",   SQLITE_DBCONFIG_RESET_DATABASE         },
         5795  +    };
         5796  +    int ii, v;
         5797  +    open_db(p, 0);
         5798  +    for(ii=0; ii<ArraySize(aDbConfig); ii++){
         5799  +      if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
         5800  +      if( nArg>=3 ){
         5801  +        sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
         5802  +      }
         5803  +      sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
         5804  +      utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
         5805  +      if( nArg>1 ) break;
         5806  +    }
         5807  +    if( nArg>1 && ii==ArraySize(aDbConfig) ){
         5808  +      utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
         5809  +      utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
         5810  +    }   
         5811  +  }else
         5812  +
         5813  +  if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
  5786   5814       rc = shell_dbinfo_command(p, nArg, azArg);
  5787   5815     }else
  5788   5816   
  5789   5817     if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
  5790   5818       const char *zLike = 0;
  5791   5819       int i;
  5792   5820       int savedShowHeader = p->showHeader;
................................................................................
  5881   5909         raw_printf(stderr, "Usage: .echo on|off\n");
  5882   5910         rc = 1;
  5883   5911       }
  5884   5912     }else
  5885   5913   
  5886   5914     if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
  5887   5915       if( nArg==2 ){
         5916  +      p->autoEQPtest = 0;
  5888   5917         if( strcmp(azArg[1],"full")==0 ){
  5889   5918           p->autoEQP = AUTOEQP_full;
  5890   5919         }else if( strcmp(azArg[1],"trigger")==0 ){
  5891   5920           p->autoEQP = AUTOEQP_trigger;
         5921  +      }else if( strcmp(azArg[1],"test")==0 ){
         5922  +        p->autoEQP = AUTOEQP_on;
         5923  +        p->autoEQPtest = 1;
  5892   5924         }else{
  5893   5925           p->autoEQP = (u8)booleanValue(azArg[1]);
  5894   5926         }
  5895   5927       }else{
  5896   5928         raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n");
  5897   5929         rc = 1;
  5898   5930       }
................................................................................
  5973   6005         raw_printf(p->out, "/* No STAT tables available */\n");
  5974   6006       }else{
  5975   6007         raw_printf(p->out, "ANALYZE sqlite_master;\n");
  5976   6008         sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
  5977   6009                      callback, &data, &zErrMsg);
  5978   6010         data.cMode = data.mode = MODE_Insert;
  5979   6011         data.zDestTable = "sqlite_stat1";
  5980         -      shell_exec(p, "SELECT * FROM sqlite_stat1", &zErrMsg);
         6012  +      shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
  5981   6013         data.zDestTable = "sqlite_stat3";
  5982         -      shell_exec(p, "SELECT * FROM sqlite_stat3", &zErrMsg);
         6014  +      shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
  5983   6015         data.zDestTable = "sqlite_stat4";
  5984         -      shell_exec(p, "SELECT * FROM sqlite_stat4", &zErrMsg);
         6016  +      shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
  5985   6017         raw_printf(p->out, "ANALYZE sqlite_master;\n");
  5986   6018       }
  5987   6019     }else
  5988   6020   
  5989   6021     if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
  5990   6022       if( nArg==2 ){
  5991   6023         p->showHeader = booleanValue(azArg[1]);
................................................................................
  7177   7209           if( strcmp(z,"debug")==0 ){
  7178   7210             bDebug = 1;
  7179   7211           }else
  7180   7212           {
  7181   7213             utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
  7182   7214                         azArg[i], azArg[0]);
  7183   7215             raw_printf(stderr, "Should be one of: --schema"
  7184         -                             " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n");
         7216  +                             " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n");
  7185   7217             rc = 1;
  7186   7218             goto meta_command_exit;
  7187   7219           }
  7188   7220         }else if( zLike ){
  7189   7221           raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
  7190   7222           rc = 1;
  7191   7223           goto meta_command_exit;
................................................................................
  7865   7897     zSql[nSql+1] = 0;
  7866   7898     rc = sqlite3_complete(zSql);
  7867   7899     zSql[nSql] = 0;
  7868   7900     return rc;
  7869   7901   }
  7870   7902   
  7871   7903   /*
  7872         -** Run a single line of SQL
         7904  +** Run a single line of SQL.  Return the number of errors.
  7873   7905   */
  7874   7906   static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
  7875   7907     int rc;
  7876   7908     char *zErrMsg = 0;
  7877   7909   
  7878   7910     open_db(p, 0);
  7879   7911     if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
................................................................................
  7938   7970         seenInterrupt = 0;
  7939   7971       }
  7940   7972       lineno++;
  7941   7973       if( nSql==0 && _all_whitespace(zLine) ){
  7942   7974         if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
  7943   7975         continue;
  7944   7976       }
  7945         -    if( zLine && zLine[0]=='.' && nSql==0 ){
         7977  +    if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
  7946   7978         if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
  7947         -      rc = do_meta_command(zLine, p);
  7948         -      if( rc==2 ){ /* exit requested */
  7949         -        break;
  7950         -      }else if( rc ){
  7951         -        errCnt++;
         7979  +      if( zLine[0]=='.' ){
         7980  +        rc = do_meta_command(zLine, p);
         7981  +        if( rc==2 ){ /* exit requested */
         7982  +          break;
         7983  +        }else if( rc ){
         7984  +          errCnt++;
         7985  +        }
  7952   7986         }
  7953   7987         continue;
  7954   7988       }
  7955   7989       if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
  7956   7990         memcpy(zLine,";",2);
  7957   7991       }
  7958   7992       nLine = strlen30(zLine);
................................................................................
  7986   8020         }
  7987   8021       }else if( nSql && _all_whitespace(zSql) ){
  7988   8022         if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
  7989   8023         nSql = 0;
  7990   8024       }
  7991   8025     }
  7992   8026     if( nSql && !_all_whitespace(zSql) ){
  7993         -    runOneSqlLine(p, zSql, in, startline);
         8027  +    errCnt += runOneSqlLine(p, zSql, in, startline);
  7994   8028     }
  7995   8029     free(zSql);
  7996   8030     free(zLine);
  7997   8031     return errCnt>0;
  7998   8032   }
  7999   8033   
  8000   8034   /*

Changes to src/sqlite.h.in.

  2108   2108   ** behavior. The first parameter passed to this operation is an integer -
  2109   2109   ** positive to enable output for trigger programs, or zero to disable it,
  2110   2110   ** or negative to leave the setting unchanged.
  2111   2111   ** The second parameter is a pointer to an integer into which is written 
  2112   2112   ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if 
  2113   2113   ** it is not disabled, 1 if it is.  
  2114   2114   ** </dd>
         2115  +**
         2116  +** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
         2117  +** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
         2118  +** [VACUUM] in order to reset a database back to an empty database
         2119  +** with no schema and no content. The following process works even for
         2120  +** a badly corrupted database file:
         2121  +** <ol>
         2122  +** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
         2123  +** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
         2124  +** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
         2125  +** </ol>
         2126  +** Because resetting a database is destructive and irreversible, the
         2127  +** process requires the use of this obscure API and multiple steps to help
         2128  +** ensure that it does not happen by accident.
         2129  +** </dd>
  2115   2130   ** </dl>
  2116   2131   */
  2117   2132   #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
  2118   2133   #define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
  2119   2134   #define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
  2120   2135   #define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
  2121   2136   #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
  2122   2137   #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
  2123   2138   #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
  2124   2139   #define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
  2125   2140   #define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
  2126         -#define SQLITE_DBCONFIG_MAX                   1008 /* Largest DBCONFIG */
         2141  +#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
         2142  +#define SQLITE_DBCONFIG_MAX                   1009 /* Largest DBCONFIG */
  2127   2143   
  2128   2144   /*
  2129   2145   ** CAPI3REF: Enable Or Disable Extended Result Codes
  2130   2146   ** METHOD: sqlite3
  2131   2147   **
  2132   2148   ** ^The sqlite3_extended_result_codes() routine enables or disables the
  2133   2149   ** [extended result codes] feature of SQLite. ^The extended result
................................................................................
  5505   5521   ** using [sqlite3_free].
  5506   5522   ** Hence, if this variable is modified directly, either it should be
  5507   5523   ** made NULL or made to point to memory obtained from [sqlite3_malloc]
  5508   5524   ** or else the use of the [data_store_directory pragma] should be avoided.
  5509   5525   */
  5510   5526   SQLITE_EXTERN char *sqlite3_data_directory;
  5511   5527   
         5528  +/*
         5529  +** CAPI3REF: Win32 Specific Interface
         5530  +**
         5531  +** These interfaces are available only on Windows.  The
         5532  +** [sqlite3_win32_set_directory] interface is used to set the value associated
         5533  +** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
         5534  +** zValue, depending on the value of the type parameter.  The zValue parameter
         5535  +** should be NULL to cause the previous value to be freed via [sqlite3_free];
         5536  +** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
         5537  +** prior to being used.  The [sqlite3_win32_set_directory] interface returns
         5538  +** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
         5539  +** or [SQLITE_NOMEM] if memory could not be allocated.  The value of the
         5540  +** [sqlite3_data_directory] variable is intended to act as a replacement for
         5541  +** the current directory on the sub-platforms of Win32 where that concept is
         5542  +** not present, e.g. WinRT and UWP.  The [sqlite3_win32_set_directory8] and
         5543  +** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
         5544  +** sqlite3_win32_set_directory interface except the string parameter must be
         5545  +** UTF-8 or UTF-16, respectively.
         5546  +*/
         5547  +int sqlite3_win32_set_directory(
         5548  +  unsigned long type, /* Identifier for directory being set or reset */
         5549  +  void *zValue        /* New value for directory being set or reset */
         5550  +);
         5551  +int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
         5552  +int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
         5553  +
         5554  +/*
         5555  +** CAPI3REF: Win32 Directory Types
         5556  +**
         5557  +** These macros are only available on Windows.  They define the allowed values
         5558  +** for the type argument to the [sqlite3_win32_set_directory] interface.
         5559  +*/
         5560  +#define SQLITE_WIN32_DATA_DIRECTORY_TYPE  1
         5561  +#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE  2
         5562  +
  5512   5563   /*
  5513   5564   ** CAPI3REF: Test For Auto-Commit Mode
  5514   5565   ** KEYWORDS: {autocommit mode}
  5515   5566   ** METHOD: sqlite3
  5516   5567   **
  5517   5568   ** ^The sqlite3_get_autocommit() interface returns non-zero or
  5518   5569   ** zero if the given database connection is or is not in autocommit mode,
................................................................................
  7058   7109   ** parsing ambiguity.  For example, the statement
  7059   7110   ** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
  7060   7111   ** creates a new table named "BEGIN" with three columns named
  7061   7112   ** "REPLACE", "PRAGMA", and "END".  Nevertheless, best practice is to avoid
  7062   7113   ** using keywords as identifiers.  Common techniques used to avoid keyword
  7063   7114   ** name collisions include:
  7064   7115   ** <ul>
  7065         -** <li> Put all indentifier names inside double-quotes.  This is the official
         7116  +** <li> Put all identifier names inside double-quotes.  This is the official
  7066   7117   **      SQL way to escape identifier names.
  7067   7118   ** <li> Put identifier names inside &#91;...&#93;.  This is not standard SQL,
  7068   7119   **      but it is what SQL Server does and so lots of programmers use this
  7069   7120   **      technique.
  7070   7121   ** <li> Begin every identifier with the letter "Z" as no SQL keywords start
  7071   7122   **      with "Z".
  7072   7123   ** <li> Include a digit somewhere in every identifier name.
................................................................................
  7077   7128   ** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
  7078   7129   ** new keywords may be added to future releases of SQLite.
  7079   7130   */
  7080   7131   int sqlite3_keyword_count(void);
  7081   7132   int sqlite3_keyword_name(int,const char**,int*);
  7082   7133   int sqlite3_keyword_check(const char*,int);
  7083   7134   
         7135  +/*
         7136  +** CAPI3REF: Dynamic String Object
         7137  +** KEYWORDS: {dynamic string}
         7138  +**
         7139  +** An instance of the sqlite3_str object contains a dynamically-sized
         7140  +** string under construction.
         7141  +**
         7142  +** The lifecycle of an sqlite3_str object is as follows:
         7143  +** <ol>
         7144  +** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
         7145  +** <li> ^Text is appended to the sqlite3_str object using various
         7146  +** methods, such as [sqlite3_str_appendf()].
         7147  +** <li> ^The sqlite3_str object is destroyed and the string it created
         7148  +** is returned using the [sqlite3_str_finish()] interface.
         7149  +** </ol>
         7150  +*/
         7151  +typedef struct sqlite3_str sqlite3_str;
         7152  +
         7153  +/*
         7154  +** CAPI3REF: Create A New Dynamic String Object
         7155  +** CONSTRUCTOR: sqlite3_str
         7156  +**
         7157  +** ^The [sqlite3_str_new(D)] interface allocates and initializes
         7158  +** a new [sqlite3_str]
         7159  +** object.  ^The [sqlite3_str_new()] interface returns NULL on an out-of-memory
         7160  +** condition.  To avoid memory leaks, the object returned by
         7161  +** [sqlite3_str_new()] must be freed by a subsequent call to 
         7162  +** [sqlite3_str_finish(X)].
         7163  +**
         7164  +** The D parameter to [sqlite3_str_new(D)] may be NULL.  If the
         7165  +** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
         7166  +** length of the string contained in the [sqlite3_str] object will be
         7167  +** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
         7168  +** of [SQLITE_MAX_LENGTH].
         7169  +*/
         7170  +sqlite3_str *sqlite3_str_new(sqlite3*);
         7171  +
         7172  +/*
         7173  +** CAPI3REF: Finalize A Dynamic String
         7174  +** DESTRUCTOR: sqlite3_str
         7175  +**
         7176  +** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
         7177  +** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
         7178  +** that contains the constructed string.  The calling application should
         7179  +** pass the returned value to [sqlite3_free()] to avoid a memory leak.
         7180  +** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
         7181  +** errors were encountered during construction of the string.  ^The
         7182  +** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
         7183  +** string in [sqlite3_str] object X is zero bytes long.
         7184  +*/
         7185  +char *sqlite3_str_finish(sqlite3_str*);
         7186  +
         7187  +/*
         7188  +** CAPI3REF: Add Content To A Dynamic String
         7189  +** METHOD: sqlite3_str
         7190  +**
         7191  +** These interfaces add content to an sqlite3_str object previously obtained
         7192  +** from [sqlite3_str_new()].
         7193  +**
         7194  +** ^The [sqlite3_str_appendf(X,F,...)] and 
         7195  +** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
         7196  +** functionality of SQLite to append formatted text onto the end of 
         7197  +** [sqlite3_str] object X.
         7198  +**
         7199  +** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
         7200  +** onto the end of the [sqlite3_str] object X.  N must be non-negative.
         7201  +** S must contain at least N non-zero bytes of content.  To append a
         7202  +** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
         7203  +** method instead.
         7204  +**
         7205  +** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
         7206  +** zero-terminated string S onto the end of [sqlite3_str] object X.
         7207  +**
         7208  +** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
         7209  +** single-byte character C onto the end of [sqlite3_str] object X.
         7210  +** ^This method can be used, for example, to add whitespace indentation.
         7211  +**
         7212  +** ^The [sqlite3_str_reset(X)] method resets the string under construction
         7213  +** inside [sqlite3_str] object X back to zero bytes in length.  
         7214  +**
         7215  +** These methods do not return a result code.  ^If an error occurs, that fact
         7216  +** is recorded in the [sqlite3_str] object and can be recovered by a
         7217  +** subsequent call to [sqlite3_str_errcode(X)].
         7218  +*/
         7219  +void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
         7220  +void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
         7221  +void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
         7222  +void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
         7223  +void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
         7224  +void sqlite3_str_reset(sqlite3_str*);
         7225  +
         7226  +/*
         7227  +** CAPI3REF: Status Of A Dynamic String
         7228  +** METHOD: sqlite3_str
         7229  +**
         7230  +** These interfaces return the current status of an [sqlite3_str] object.
         7231  +**
         7232  +** ^If any prior errors have occurred while constructing the dynamic string
         7233  +** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
         7234  +** an appropriate error code.  ^The [sqlite3_str_errcode(X)] method returns
         7235  +** [SQLITE_NOMEM] following any out-of-memory error, or
         7236  +** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
         7237  +** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
         7238  +**
         7239  +** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
         7240  +** of the dynamic string under construction in [sqlite3_str] object X.
         7241  +** ^The length returned by [sqlite3_str_length(X)] does not include the
         7242  +** zero-termination byte.
         7243  +**
         7244  +** ^The [sqlite3_str_value(X)] method returns a pointer to the current
         7245  +** content of the dynamic string under construction in X.  The value
         7246  +** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
         7247  +** and might be freed or altered by any subsequent method on the same
         7248  +** [sqlite3_str] object.  Applications must not used the pointer returned
         7249  +** [sqlite3_str_value(X)] after any subsequent method call on the same
         7250  +** object.  ^Applications may change the content of the string returned
         7251  +** by [sqlite3_str_value(X)] as long as they do not write into any bytes
         7252  +** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
         7253  +** write any byte after any subsequent sqlite3_str method call.
         7254  +*/
         7255  +int sqlite3_str_errcode(sqlite3_str*);
         7256  +int sqlite3_str_length(sqlite3_str*);
         7257  +char *sqlite3_str_value(sqlite3_str*);
         7258  +
  7084   7259   /*
  7085   7260   ** CAPI3REF: SQLite Runtime Status
  7086   7261   **
  7087   7262   ** ^These interfaces are used to retrieve runtime status information
  7088   7263   ** about the performance of SQLite, and optionally to reset various
  7089   7264   ** highwater marks.  ^The first argument is an integer code for
  7090   7265   ** the specific parameter to measure.  ^(Recognized integer codes

Changes to src/sqlite3ext.h.

   291    291                         sqlite3_stmt**,const void**);
   292    292     int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
   293    293     void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
   294    294     void *(*value_pointer)(sqlite3_value*,const char*);
   295    295     int (*vtab_nochange)(sqlite3_context*);
   296    296     int (*value_nochange)(sqlite3_value*);
   297    297     const char *(*vtab_collation)(sqlite3_index_info*,int);
          298  +  /* Version 3.24.0 and later */
          299  +  int (*keyword_count)(void);
          300  +  int (*keyword_name)(int,const char**,int*);
          301  +  int (*keyword_check)(const char*,int);
          302  +  sqlite3_str *(*str_new)(sqlite3*);
          303  +  char *(*str_finish)(sqlite3_str*);
          304  +  void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
          305  +  void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
          306  +  void (*str_append)(sqlite3_str*, const char *zIn, int N);
          307  +  void (*str_appendall)(sqlite3_str*, const char *zIn);
          308  +  void (*str_appendchar)(sqlite3_str*, int N, char C);
          309  +  void (*str_reset)(sqlite3_str*);
          310  +  int (*str_errcode)(sqlite3_str*);
          311  +  int (*str_length)(sqlite3_str*);
          312  +  char *(*str_value)(sqlite3_str*);
   298    313   };
   299    314   
   300    315   /*
   301    316   ** This is the function signature used for all extension entry points.  It
   302    317   ** is also defined in the file "loadext.c".
   303    318   */
   304    319   typedef int (*sqlite3_loadext_entry)(
................................................................................
   561    576   #define sqlite3_bind_pointer           sqlite3_api->bind_pointer
   562    577   #define sqlite3_result_pointer         sqlite3_api->result_pointer
   563    578   #define sqlite3_value_pointer          sqlite3_api->value_pointer
   564    579   /* Version 3.22.0 and later */
   565    580   #define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
   566    581   #define sqlite3_value_nochange         sqlite3_api->value_nochange
   567    582   #define sqlite3_vtab_collation         sqlite3_api->vtab_collation
          583  +/* Version 3.24.0 and later */
          584  +#define sqlite3_keyword_count          sqlite3_api->keyword_count
          585  +#define sqlite3_keyword_name           sqlite3_api->keyword_name
          586  +#define sqlite3_keyword_check          sqlite3_api->keyword_check
          587  +#define sqlite3_str_new                sqlite3_api->str_new
          588  +#define sqlite3_str_finish             sqlite3_api->str_finish
          589  +#define sqlite3_str_appendf            sqlite3_api->str_appendf
          590  +#define sqlite3_str_vappendf           sqlite3_api->str_vappendf
          591  +#define sqlite3_str_append             sqlite3_api->str_append
          592  +#define sqlite3_str_appendall          sqlite3_api->str_appendall
          593  +#define sqlite3_str_appendchar         sqlite3_api->str_appendchar
          594  +#define sqlite3_str_reset              sqlite3_api->str_reset
          595  +#define sqlite3_str_errcode            sqlite3_api->str_errcode
          596  +#define sqlite3_str_length             sqlite3_api->str_length
          597  +#define sqlite3_str_value              sqlite3_api->str_value
   568    598   #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
   569    599   
   570    600   #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   571    601     /* This case when the file really is being compiled as a loadable 
   572    602     ** extension */
   573    603   # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
   574    604   # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/sqliteInt.h.

  1089   1089   typedef struct PrintfArguments PrintfArguments;
  1090   1090   typedef struct RowSet RowSet;
  1091   1091   typedef struct Savepoint Savepoint;
  1092   1092   typedef struct Select Select;
  1093   1093   typedef struct SQLiteThread SQLiteThread;
  1094   1094   typedef struct SelectDest SelectDest;
  1095   1095   typedef struct SrcList SrcList;
  1096         -typedef struct StrAccum StrAccum;
         1096  +typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
  1097   1097   typedef struct Table Table;
  1098   1098   typedef struct TableLock TableLock;
  1099   1099   typedef struct Token Token;
  1100   1100   typedef struct TreeView TreeView;
  1101   1101   typedef struct Trigger Trigger;
  1102   1102   typedef struct TriggerPrg TriggerPrg;
  1103   1103   typedef struct TriggerStep TriggerStep;
................................................................................
  1503   1503   #define SQLITE_EnableTrigger  0x00040000  /* True to enable triggers */
  1504   1504   #define SQLITE_DeferFKs       0x00080000  /* Defer all FK constraints */
  1505   1505   #define SQLITE_QueryOnly      0x00100000  /* Disable database changes */
  1506   1506   #define SQLITE_CellSizeCk     0x00200000  /* Check btree cell sizes on load */
  1507   1507   #define SQLITE_Fts3Tokenizer  0x00400000  /* Enable fts3_tokenizer(2) */
  1508   1508   #define SQLITE_EnableQPSG     0x00800000  /* Query Planner Stability Guarantee*/
  1509   1509   #define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
         1510  +#define SQLITE_ResetDatabase  0x02000000  /* Reset the database */
  1510   1511   
  1511   1512   /* Flags used only if debugging */
  1512   1513   #ifdef SQLITE_DEBUG
  1513   1514   #define SQLITE_SqlTrace       0x08000000  /* Debug print SQL as it executes */
  1514   1515   #define SQLITE_VdbeListing    0x10000000  /* Debug listings of VDBE programs */
  1515   1516   #define SQLITE_VdbeTrace      0x20000000  /* True to trace VDBE execution */
  1516   1517   #define SQLITE_VdbeAddopTrace 0x40000000  /* Trace sqlite3VdbeAddOp() calls */
................................................................................
  2605   2606         unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
  2606   2607         unsigned isIndexedBy :1;   /* True if there is an INDEXED BY clause */
  2607   2608         unsigned isTabFunc :1;     /* True if table-valued-function syntax */
  2608   2609         unsigned isCorrelated :1;  /* True if sub-query is correlated */
  2609   2610         unsigned viaCoroutine :1;  /* Implemented as a co-routine */
  2610   2611         unsigned isRecursive :1;   /* True for recursive reference in WITH */
  2611   2612       } fg;
  2612         -#ifndef SQLITE_OMIT_EXPLAIN
  2613         -    u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
  2614         -#endif
  2615   2613       int iCursor;      /* The VDBE cursor number used to access this table */
  2616   2614       Expr *pOn;        /* The ON clause of a join */
  2617   2615       IdList *pUsing;   /* The USING clause of a join */
  2618   2616       Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
  2619   2617       union {
  2620   2618         char *zIndexedBy;    /* Identifier from "INDEXED BY <zIndex>" clause */
  2621   2619         ExprList *pFuncArg;  /* Arguments to table-valued-function */
................................................................................
  2755   2753     int iIdxCur;              /* Index of the first index cursor */
  2756   2754   };
  2757   2755   
  2758   2756   /*
  2759   2757   ** An instance of the following structure contains all information
  2760   2758   ** needed to generate code for a single SELECT statement.
  2761   2759   **
  2762         -** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
  2763         -** If there is a LIMIT clause, the parser sets nLimit to the value of the
  2764         -** limit and nOffset to the value of the offset (or 0 if there is not
  2765         -** offset).  But later on, nLimit and nOffset become the memory locations
  2766         -** in the VDBE that record the limit and offset counters.
         2760  +** See the header comment on the computeLimitRegisters() routine for a
         2761  +** detailed description of the meaning of the iLimit and iOffset fields.
  2767   2762   **
  2768   2763   ** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
  2769   2764   ** These addresses must be stored so that we can go back and fill in
  2770   2765   ** the P4_KEYINFO and P2 parameters later.  Neither the KeyInfo nor
  2771   2766   ** the number of columns in P2 can be computed at the same time
  2772   2767   ** as the OP_OpenEphm instruction is coded because not
  2773   2768   ** enough information about the compound query is known at that point.
................................................................................
  2779   2774     ExprList *pEList;      /* The fields of the result */
  2780   2775     u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  2781   2776     LogEst nSelectRow;     /* Estimated number of result rows */
  2782   2777     u32 selFlags;          /* Various SF_* values */
  2783   2778     int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
  2784   2779   #if SELECTTRACE_ENABLED
  2785   2780     char zSelName[12];     /* Symbolic name of this SELECT use for debugging */
  2786         -  u32 iSelectId;         /* EXPLAIN QUERY PLAN select ID */
  2787   2781   #endif
  2788   2782     int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
  2789   2783     SrcList *pSrc;         /* The FROM clause */
  2790   2784     Expr *pWhere;          /* The WHERE clause */
  2791   2785     ExprList *pGroupBy;    /* The GROUP BY clause */
  2792   2786     Expr *pHaving;         /* The HAVING clause */
  2793   2787     ExprList *pOrderBy;    /* The ORDER BY clause */
................................................................................
  2820   2814   #define SF_NestedFrom     0x00800  /* Part of a parenthesized FROM clause */
  2821   2815   #define SF_MinMaxAgg      0x01000  /* Aggregate containing min() or max() */
  2822   2816   #define SF_Recursive      0x02000  /* The recursive part of a recursive CTE */
  2823   2817   #define SF_FixedLimit     0x04000  /* nSelectRow set by a constant LIMIT */
  2824   2818   #define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
  2825   2819   #define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
  2826   2820   #define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
  2827         -#define SF_ComplexResult  0x40000  /* Result set contains subquery or function */
  2828         -
         2821  +#define SF_ComplexResult  0x40000  /* Result contains subquery or function */
  2829   2822   
  2830   2823   /*
  2831   2824   ** The results of a SELECT can be distributed in several ways, as defined
  2832   2825   ** by one of the following macros.  The "SRT" prefix means "SELECT Result
  2833   2826   ** Type".
  2834   2827   **
  2835   2828   **     SRT_Union       Store results as a key in a temporary index
................................................................................
  3091   3084     u8 explain;               /* True if the EXPLAIN flag is found on the query */
  3092   3085   #ifndef SQLITE_OMIT_VIRTUALTABLE
  3093   3086     u8 declareVtab;           /* True if inside sqlite3_declare_vtab() */
  3094   3087     int nVtabLock;            /* Number of virtual tables to lock */
  3095   3088   #endif
  3096   3089     int nHeight;              /* Expression tree height of current sub-select */
  3097   3090   #ifndef SQLITE_OMIT_EXPLAIN
  3098         -  int iSelectId;            /* ID of current select for EXPLAIN output */
  3099         -  int iNextSelectId;        /* Next available select ID for EXPLAIN output */
         3091  +  int addrExplain;          /* Address of current OP_Explain opcode */
  3100   3092   #endif
  3101   3093     VList *pVList;            /* Mapping between variable names and numbers */
  3102   3094     Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
  3103   3095     const char *zTail;        /* All SQL text past the last semicolon parsed */
  3104   3096     Table *pNewTable;         /* A table being constructed by CREATE TABLE */
  3105   3097     Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  3106   3098     const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
................................................................................
  3278   3270     const Token *pName; /* Name of the container - used for error messages */
  3279   3271   };
  3280   3272   
  3281   3273   /*
  3282   3274   ** An objected used to accumulate the text of a string where we
  3283   3275   ** do not necessarily know how big the string will be in the end.
  3284   3276   */
  3285         -struct StrAccum {
         3277  +struct sqlite3_str {
  3286   3278     sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
  3287   3279     char *zText;         /* The string collected so far */
  3288   3280     u32  nAlloc;         /* Amount of space allocated in zText */
  3289   3281     u32  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
  3290   3282     u32  nChar;          /* Length of the string so far */
  3291         -  u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
         3283  +  u8   accError;       /* SQLITE_NOMEM or SQLITE_TOOBIG */
  3292   3284     u8   printfFlags;    /* SQLITE_PRINTF flags below */
  3293   3285   };
  3294         -#define STRACCUM_NOMEM   1
  3295         -#define STRACCUM_TOOBIG  2
  3296   3286   #define SQLITE_PRINTF_INTERNAL 0x01  /* Internal-use-only converters allowed */
  3297   3287   #define SQLITE_PRINTF_SQLFUNC  0x02  /* SQL function arguments to VXPrintf */
  3298   3288   #define SQLITE_PRINTF_MALLOCED 0x04  /* True if xText is allocated space */
  3299   3289   
  3300   3290   #define isMalloced(X)  (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
  3301   3291   
  3302   3292   
................................................................................
  3657   3647   */
  3658   3648   struct PrintfArguments {
  3659   3649     int nArg;                /* Total number of arguments */
  3660   3650     int nUsed;               /* Number of arguments used so far */
  3661   3651     sqlite3_value **apArg;   /* The argument values */
  3662   3652   };
  3663   3653   
  3664         -void sqlite3VXPrintf(StrAccum*, const char*, va_list);
  3665         -void sqlite3XPrintf(StrAccum*, const char*, ...);
  3666   3654   char *sqlite3MPrintf(sqlite3*,const char*, ...);
  3667   3655   char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
  3668   3656   #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
  3669   3657     void sqlite3DebugPrintf(const char*, ...);
  3670   3658   #endif
  3671   3659   #if defined(SQLITE_TEST)
  3672   3660     void *sqlite3TestTextToPtr(const char*);
................................................................................
  4181   4169   );
  4182   4170   void sqlite3OomFault(sqlite3*);
  4183   4171   void sqlite3OomClear(sqlite3*);
  4184   4172   int sqlite3ApiExit(sqlite3 *db, int);
  4185   4173   int sqlite3OpenTempDatabase(Parse *);
  4186   4174   
  4187   4175   void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
  4188         -void sqlite3StrAccumAppend(StrAccum*,const char*,int);
  4189         -void sqlite3StrAccumAppendAll(StrAccum*,const char*);
  4190         -void sqlite3AppendChar(StrAccum*,int,char);
  4191   4176   char *sqlite3StrAccumFinish(StrAccum*);
  4192         -void sqlite3StrAccumReset(StrAccum*);
  4193   4177   void sqlite3SelectDestInit(SelectDest*,int,int);
  4194   4178   Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
  4195   4179   
  4196   4180   void sqlite3BackupRestart(sqlite3_backup *);
  4197   4181   void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
  4198   4182   
  4199   4183   #ifndef SQLITE_OMIT_SUBQUERY

Changes to src/test1.c.

  7414   7414     } aSetting[] = {
  7415   7415       { "FKEY",            SQLITE_DBCONFIG_ENABLE_FKEY },
  7416   7416       { "TRIGGER",         SQLITE_DBCONFIG_ENABLE_TRIGGER },
  7417   7417       { "FTS3_TOKENIZER",  SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
  7418   7418       { "LOAD_EXTENSION",  SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
  7419   7419       { "NO_CKPT_ON_CLOSE",SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
  7420   7420       { "QPSG",            SQLITE_DBCONFIG_ENABLE_QPSG },
         7421  +    { "TRIGGER_EQP",     SQLITE_DBCONFIG_TRIGGER_EQP },
         7422  +    { "RESET_DB",        SQLITE_DBCONFIG_RESET_DATABASE },
  7421   7423     };
  7422   7424     int i;
  7423   7425     int v;
  7424   7426     const char *zSetting;
  7425   7427     sqlite3 *db;
  7426   7428   
  7427   7429     if( objc!=4 ){

Changes to src/treeview.c.

    54     54     va_list ap;
    55     55     int i;
    56     56     StrAccum acc;
    57     57     char zBuf[500];
    58     58     sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
    59     59     if( p ){
    60     60       for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
    61         -      sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
           61  +      sqlite3_str_append(&acc, p->bLine[i] ? "|   " : "    ", 4);
    62     62       }
    63         -    sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
           63  +    sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
    64     64     }
    65     65     if( zFormat!=0 ){
    66     66       va_start(ap, zFormat);
    67         -    sqlite3VXPrintf(&acc, zFormat, ap);
           67  +    sqlite3_str_vappendf(&acc, zFormat, ap);
    68     68       va_end(ap);
    69     69       assert( acc.nChar>0 );
    70         -    sqlite3StrAccumAppend(&acc, "\n", 1);
           70  +    sqlite3_str_append(&acc, "\n", 1);
    71     71     }
    72     72     sqlite3StrAccumFinish(&acc);
    73     73     fprintf(stdout,"%s", zBuf);
    74     74     fflush(stdout);
    75     75   }
    76     76   
    77     77   /*
................................................................................
    97     97     if( pWith->nCte>0 ){
    98     98       pView = sqlite3TreeViewPush(pView, 1);
    99     99       for(i=0; i<pWith->nCte; i++){
   100    100         StrAccum x;
   101    101         char zLine[1000];
   102    102         const struct Cte *pCte = &pWith->a[i];
   103    103         sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
   104         -      sqlite3XPrintf(&x, "%s", pCte->zName);
          104  +      sqlite3_str_appendf(&x, "%s", pCte->zName);
   105    105         if( pCte->pCols && pCte->pCols->nExpr>0 ){
   106    106           char cSep = '(';
   107    107           int j;
   108    108           for(j=0; j<pCte->pCols->nExpr; j++){
   109         -          sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
          109  +          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
   110    110             cSep = ',';
   111    111           }
   112         -        sqlite3XPrintf(&x, ")");
          112  +        sqlite3_str_appendf(&x, ")");
   113    113         }
   114         -      sqlite3XPrintf(&x, " AS");
          114  +      sqlite3_str_appendf(&x, " AS");
   115    115         sqlite3StrAccumFinish(&x);
   116    116         sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
   117    117         sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
   118    118         sqlite3TreeViewPop(pView);
   119    119       }
   120    120       sqlite3TreeViewPop(pView);
   121    121     }
................................................................................
   137    137       sqlite3TreeViewWith(pView, p->pWith, 1);
   138    138       cnt = 1;
   139    139       sqlite3TreeViewPush(pView, 1);
   140    140     }
   141    141     do{
   142    142   #if SELECTTRACE_ENABLED
   143    143       sqlite3TreeViewLine(pView,
   144         -      "SELECT%s%s (%s/%d/%p) selFlags=0x%x nSelectRow=%d",
          144  +      "SELECT%s%s (%s/%p) selFlags=0x%x nSelectRow=%d",
   145    145         ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
   146    146         ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
   147         -      p->zSelName, p->iSelectId, p, p->selFlags,
          147  +      p->zSelName, p, p->selFlags,
   148    148         (int)p->nSelectRow
   149    149       );
   150    150   #else
   151    151       sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
   152    152         ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
   153    153         ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
   154    154         (int)p->nSelectRow
................................................................................
   172    172         pView = sqlite3TreeViewPush(pView, (n--)>0);
   173    173         sqlite3TreeViewLine(pView, "FROM");
   174    174         for(i=0; i<p->pSrc->nSrc; i++){
   175    175           struct SrcList_item *pItem = &p->pSrc->a[i];
   176    176           StrAccum x;
   177    177           char zLine[100];
   178    178           sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
   179         -        sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
          179  +        sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
   180    180           if( pItem->zDatabase ){
   181         -          sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
          181  +          sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
   182    182           }else if( pItem->zName ){
   183         -          sqlite3XPrintf(&x, " %s", pItem->zName);
          183  +          sqlite3_str_appendf(&x, " %s", pItem->zName);
   184    184           }
   185    185           if( pItem->pTab ){
   186         -          sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
          186  +          sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
   187    187           }
   188    188           if( pItem->zAlias ){
   189         -          sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
          189  +          sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
   190    190           }
   191    191           if( pItem->fg.jointype & JT_LEFT ){
   192         -          sqlite3XPrintf(&x, " LEFT-JOIN");
          192  +          sqlite3_str_appendf(&x, " LEFT-JOIN");
   193    193           }
   194    194           sqlite3StrAccumFinish(&x);
   195    195           sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
   196    196           if( pItem->pSelect ){
   197    197             sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
   198    198           }
   199    199           if( pItem->fg.isTabFunc ){

Changes to src/update.c.

   598    598     for(i=0; i<pTab->nCol; i++){
   599    599       if( i==pTab->iPKey ){
   600    600         sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
   601    601       }else{
   602    602         j = aXRef[i];
   603    603         if( j>=0 ){
   604    604           sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
   605         -        if( tmask&TRIGGER_BEFORE ){
   606         -          /* Must preserve copied values even in case the original is
   607         -          ** reloaded in the After-BEFORE-trigger-reload-loop below.
   608         -          ** Ticket d85fffd6ffe856092ed8daefa811b1e399706b28 */
   609         -          sqlite3VdbeSwapOpcode(v, -1, OP_SCopy, OP_Copy);
   610         -        }
   611    605         }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
   612    606           /* This branch loads the value of a column that will not be changed 
   613    607           ** into a register. This is done if there are no BEFORE triggers, or
   614    608           ** if there are one or more BEFORE triggers that use this value via
   615    609           ** a new.* reference in a trigger program.
   616    610           */
   617    611           testcase( i==31 );
   618    612           testcase( i==32 );
   619    613           sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
          614  +        if( tmask & TRIGGER_BEFORE ){
          615  +          /* This value will be recomputed in After-BEFORE-trigger-reload-loop
          616  +          ** below, so make sure that it is not cached and reused.
          617  +          ** Ticket d85fffd6ffe856092ed8daefa811b1e399706b28. */
          618  +          sqlite3ExprCacheRemove(pParse, regNew+i, 1);
          619  +        }
   620    620         }else{
   621    621           sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
   622    622         }
   623    623       }
   624    624     }
   625    625   
   626    626     /* Fire any BEFORE UPDATE triggers. This happens before constraints are

Changes to src/vacuum.c.

    35     35   
    36     36     /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
    37     37     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
    38     38     if( rc!=SQLITE_OK ) return rc;
    39     39     while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
    40     40       const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
    41     41       assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
    42         -    assert( sqlite3_strnicmp(zSubSql,"SELECT",6)!=0 || CORRUPT_DB );
    43         -    if( zSubSql && zSubSql[0]!='S' ){
           42  +    /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX,
           43  +    ** or INSERT.  Historically there have been attacks that first
           44  +    ** corrupt the sqlite_master.sql field with other kinds of statements
           45  +    ** then run VACUUM to get those statements to execute at inappropriate
           46  +    ** times. */
           47  +    if( zSubSql
           48  +     && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0)
           49  +    ){
    44     50         rc = execSql(db, pzErrMsg, zSubSql);
    45     51         if( rc!=SQLITE_OK ) break;
    46     52       }
    47     53     }
    48     54     assert( rc!=SQLITE_ROW );
    49     55     if( rc==SQLITE_DONE ) rc = SQLITE_OK;
    50     56     if( rc ){
................................................................................
   249    255         " WHERE type='table'AND name<>'sqlite_sequence'"
   250    256         " AND coalesce(rootpage,1)>0",
   251    257         zDbMain
   252    258     );
   253    259     if( rc!=SQLITE_OK ) goto end_of_vacuum;
   254    260     rc = execSqlF(db, pzErrMsg,
   255    261         "SELECT sql FROM \"%w\".sqlite_master"
   256         -      " WHERE type='index' AND length(sql)>10",
          262  +      " WHERE type='index'",
   257    263         zDbMain
   258    264     );
   259    265     if( rc!=SQLITE_OK ) goto end_of_vacuum;
   260    266     db->init.iDb = 0;
   261    267   
   262    268     /* Loop through the tables in the main database. For each, do
   263    269     ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy

Changes to src/vdbe.h.

   193    193   #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
   194    194     void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
   195    195     void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
   196    196   #else
   197    197   # define sqlite3VdbeVerifyNoMallocRequired(A,B)
   198    198   # define sqlite3VdbeVerifyNoResultRow(A)
   199    199   #endif
   200         -VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
          200  +VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
          201  +#ifndef SQLITE_OMIT_EXPLAIN
          202  +  void sqlite3VdbeExplain(Parse*,u8,const char*,...);
          203  +  void sqlite3VdbeExplainPop(Parse*);
          204  +  int sqlite3VdbeExplainParent(Parse*);
          205  +# define ExplainQueryPlan(P)        sqlite3VdbeExplain P
          206  +# define ExplainQueryPlanPop(P)     sqlite3VdbeExplainPop(P)
          207  +# define ExplainQueryPlanParent(P)  sqlite3VdbeExplainParent(P)
          208  +#else
          209  +# define ExplainQueryPlan(P)
          210  +# define ExplainQueryPlanPop(P)
          211  +# define ExplainQueryPlanParent(P) 0
          212  +#endif
   201    213   void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
   202    214   void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
   203         -void sqlite3VdbeSwapOpcode(Vdbe*, u32 addr, u8, u8);
   204    215   void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
   205    216   void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
   206    217   void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
   207    218   void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
   208    219   void sqlite3VdbeJumpHere(Vdbe*, int addr);
   209    220   int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
   210    221   int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);

Changes to src/vdbeaux.c.

   299    299     int p4type          /* P4 operand type */
   300    300   ){
   301    301     char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8);
   302    302     if( p4copy ) memcpy(p4copy, zP4, 8);
   303    303     return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
   304    304   }
   305    305   
          306  +#ifndef SQLITE_OMIT_EXPLAIN
          307  +/*
          308  +** Return the address of the current EXPLAIN QUERY PLAN baseline.
          309  +** 0 means "none".
          310  +*/
          311  +int sqlite3VdbeExplainParent(Parse *pParse){
          312  +  VdbeOp *pOp;
          313  +  if( pParse->addrExplain==0 ) return 0;
          314  +  pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain);
          315  +  return pOp->p2;
          316  +}
          317  +
          318  +/*
          319  +** Add a new OP_Explain opcode.
          320  +**
          321  +** If the bPush flag is true, then make this opcode the parent for
          322  +** subsequent Explains until sqlite3VdbeExplainPop() is called.
          323  +*/
          324  +void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
          325  +  if( pParse->explain==2 ){
          326  +    char *zMsg;
          327  +    Vdbe *v = pParse->pVdbe;
          328  +    va_list ap;
          329  +    int iThis;
          330  +    va_start(ap, zFmt);
          331  +    zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
          332  +    va_end(ap);
          333  +    v = pParse->pVdbe;
          334  +    iThis = v->nOp;
          335  +    sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
          336  +                      zMsg, P4_DYNAMIC);
          337  +    if( bPush) pParse->addrExplain = iThis;
          338  +  }
          339  +}
          340  +
          341  +/*
          342  +** Pop the EXPLAIN QUERY PLAN stack one level.
          343  +*/
          344  +void sqlite3VdbeExplainPop(Parse *pParse){
          345  +  pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
          346  +}
          347  +#endif /* SQLITE_OMIT_EXPLAIN */
          348  +
   306    349   /*
   307    350   ** Add an OP_ParseSchema opcode.  This routine is broken out from
   308    351   ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
   309    352   ** as having been used.
   310    353   **
   311    354   ** The zWhere string must have been obtained from sqlite3_malloc().
   312    355   ** This routine will take ownership of the allocated memory.
................................................................................
   839    882     sqlite3VdbeGetOp(p,addr)->p3 = val;
   840    883   }
   841    884   void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
   842    885     assert( p->nOp>0 || p->db->mallocFailed );
   843    886     if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
   844    887   }
   845    888   
   846         -/* Change the opcode to iNew if it was previously iOld */
   847         -void sqlite3VdbeSwapOpcode(Vdbe *p, u32 addr, u8 iOld, u8 iNew){
   848         -  VdbeOp *pOp = sqlite3VdbeGetOp(p,addr);
   849         -  if( pOp->opcode==iOld ) pOp->opcode = iNew;
   850         -}
   851         -
   852    889   /*
   853    890   ** Change the P2 operand of instruction addr so that it points to
   854    891   ** the address of the next instruction to be coded.
   855    892   */
   856    893   void sqlite3VdbeJumpHere(Vdbe *p, int addr){
   857    894     sqlite3VdbeChangeP2(p, addr, p->nOp);
   858    895   }
................................................................................
  1265   1302   ** Translate the P4.pExpr value for an OP_CursorHint opcode into text
  1266   1303   ** that can be displayed in the P4 column of EXPLAIN output.
  1267   1304   */
  1268   1305   static void displayP4Expr(StrAccum *p, Expr *pExpr){
  1269   1306     const char *zOp = 0;
  1270   1307     switch( pExpr->op ){
  1271   1308       case TK_STRING:
  1272         -      sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
         1309  +      sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
  1273   1310         break;
  1274   1311       case TK_INTEGER:
  1275         -      sqlite3XPrintf(p, "%d", pExpr->u.iValue);
         1312  +      sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
  1276   1313         break;
  1277   1314       case TK_NULL:
  1278         -      sqlite3XPrintf(p, "NULL");
         1315  +      sqlite3_str_appendf(p, "NULL");
  1279   1316         break;
  1280   1317       case TK_REGISTER: {
  1281         -      sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
         1318  +      sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
  1282   1319         break;
  1283   1320       }
  1284   1321       case TK_COLUMN: {
  1285   1322         if( pExpr->iColumn<0 ){
  1286         -        sqlite3XPrintf(p, "rowid");
         1323  +        sqlite3_str_appendf(p, "rowid");
  1287   1324         }else{
  1288         -        sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
         1325  +        sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
  1289   1326         }
  1290   1327         break;
  1291   1328       }
  1292   1329       case TK_LT:      zOp = "LT";      break;
  1293   1330       case TK_LE:      zOp = "LE";      break;
  1294   1331       case TK_GT:      zOp = "GT";      break;
  1295   1332       case TK_GE:      zOp = "GE";      break;
................................................................................
  1313   1350       case TK_UPLUS:   zOp = "PLUS";    break;
  1314   1351       case TK_BITNOT:  zOp = "BITNOT";  break;
  1315   1352       case TK_NOT:     zOp = "NOT";     break;
  1316   1353       case TK_ISNULL:  zOp = "ISNULL";  break;
  1317   1354       case TK_NOTNULL: zOp = "NOTNULL"; break;
  1318   1355   
  1319   1356       default:
  1320         -      sqlite3XPrintf(p, "%s", "expr");
         1357  +      sqlite3_str_appendf(p, "%s", "expr");
  1321   1358         break;
  1322   1359     }
  1323   1360   
  1324   1361     if( zOp ){
  1325         -    sqlite3XPrintf(p, "%s(", zOp);
         1362  +    sqlite3_str_appendf(p, "%s(", zOp);
  1326   1363       displayP4Expr(p, pExpr->pLeft);
  1327   1364       if( pExpr->pRight ){
  1328         -      sqlite3StrAccumAppend(p, ",", 1);
         1365  +      sqlite3_str_append(p, ",", 1);
  1329   1366         displayP4Expr(p, pExpr->pRight);
  1330   1367       }
  1331         -    sqlite3StrAccumAppend(p, ")", 1);
         1368  +    sqlite3_str_append(p, ")", 1);
  1332   1369     }
  1333   1370   }
  1334   1371   #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
  1335   1372   
  1336   1373   
  1337   1374   #if VDBE_DISPLAY_P4
  1338   1375   /*
................................................................................
  1345   1382     assert( nTemp>=20 );
  1346   1383     sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
  1347   1384     switch( pOp->p4type ){
  1348   1385       case P4_KEYINFO: {
  1349   1386         int j;
  1350   1387         KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  1351   1388         assert( pKeyInfo->aSortOrder!=0 );
  1352         -      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField);
         1389  +      sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
  1353   1390         for(j=0; j<pKeyInfo->nKeyField; j++){
  1354   1391           CollSeq *pColl = pKeyInfo->aColl[j];
  1355   1392           const char *zColl = pColl ? pColl->zName : "";
  1356   1393           if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
  1357         -        sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
         1394  +        sqlite3_str_appendf(&x, ",%s%s", 
         1395  +               pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
  1358   1396         }
  1359         -      sqlite3StrAccumAppend(&x, ")", 1);
         1397  +      sqlite3_str_append(&x, ")", 1);
  1360   1398         break;
  1361   1399       }
  1362   1400   #ifdef SQLITE_ENABLE_CURSOR_HINTS
  1363   1401       case P4_EXPR: {
  1364   1402         displayP4Expr(&x, pOp->p4.pExpr);
  1365   1403         break;
  1366   1404       }
  1367   1405   #endif
  1368   1406       case P4_COLLSEQ: {
  1369   1407         CollSeq *pColl = pOp->p4.pColl;
  1370         -      sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
         1408  +      sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
  1371   1409         break;
  1372   1410       }
  1373   1411       case P4_FUNCDEF: {
  1374   1412         FuncDef *pDef = pOp->p4.pFunc;
  1375         -      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
         1413  +      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
  1376   1414         break;
  1377   1415       }
  1378   1416   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
  1379   1417       case P4_FUNCCTX: {
  1380   1418         FuncDef *pDef = pOp->p4.pCtx->pFunc;
  1381         -      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
         1419  +      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
  1382   1420         break;
  1383   1421       }
  1384   1422   #endif
  1385   1423       case P4_INT64: {
  1386         -      sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
         1424  +      sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
  1387   1425         break;
  1388   1426       }
  1389   1427       case P4_INT32: {
  1390         -      sqlite3XPrintf(&x, "%d", pOp->p4.i);
         1428  +      sqlite3_str_appendf(&x, "%d", pOp->p4.i);
  1391   1429         break;
  1392   1430       }
  1393   1431       case P4_REAL: {
  1394         -      sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
         1432  +      sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
  1395   1433         break;
  1396   1434       }
  1397   1435       case P4_MEM: {
  1398   1436         Mem *pMem = pOp->p4.pMem;
  1399   1437         if( pMem->flags & MEM_Str ){
  1400   1438           zP4 = pMem->z;
  1401   1439         }else if( pMem->flags & MEM_Int ){
  1402         -        sqlite3XPrintf(&x, "%lld", pMem->u.i);
         1440  +        sqlite3_str_appendf(&x, "%lld", pMem->u.i);
  1403   1441         }else if( pMem->flags & MEM_Real ){
  1404         -        sqlite3XPrintf(&x, "%.16g", pMem->u.r);
         1442  +        sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
  1405   1443         }else if( pMem->flags & MEM_Null ){
  1406   1444           zP4 = "NULL";
  1407   1445         }else{
  1408   1446           assert( pMem->flags & MEM_Blob );
  1409   1447           zP4 = "(blob)";
  1410   1448         }
  1411   1449         break;
  1412   1450       }
  1413   1451   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1414   1452       case P4_VTAB: {
  1415   1453         sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
  1416         -      sqlite3XPrintf(&x, "vtab:%p", pVtab);
         1454  +      sqlite3_str_appendf(&x, "vtab:%p", pVtab);
  1417   1455         break;
  1418   1456       }
  1419   1457   #endif
  1420   1458       case P4_INTARRAY: {
  1421   1459         int i;
  1422   1460         int *ai = pOp->p4.ai;
  1423   1461         int n = ai[0];   /* The first element of an INTARRAY is always the
  1424   1462                          ** count of the number of elements to follow */
  1425   1463         for(i=1; i<=n; i++){
  1426         -        sqlite3XPrintf(&x, ",%d", ai[i]);
         1464  +        sqlite3_str_appendf(&x, ",%d", ai[i]);
  1427   1465         }
  1428   1466         zTemp[0] = '[';
  1429         -      sqlite3StrAccumAppend(&x, "]", 1);
         1467  +      sqlite3_str_append(&x, "]", 1);
  1430   1468         break;
  1431   1469       }
  1432   1470       case P4_SUBPROGRAM: {
  1433         -      sqlite3XPrintf(&x, "program");
         1471  +      sqlite3_str_appendf(&x, "program");
  1434   1472         break;
  1435   1473       }
  1436   1474       case P4_DYNBLOB:
  1437   1475       case P4_ADVANCE: {
  1438   1476         zTemp[0] = 0;
  1439   1477         break;
  1440   1478       }
  1441   1479       case P4_TABLE: {
  1442         -      sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
         1480  +      sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
  1443   1481         break;
  1444   1482       }
  1445   1483       default: {
  1446   1484         zP4 = pOp->p4.z;
  1447   1485         if( zP4==0 ){
  1448   1486           zP4 = zTemp;
  1449   1487           zTemp[0] = 0;

Changes to src/vdbetrace.c.

    89     89     db = p->db;
    90     90     sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), 
    91     91                         db->aLimit[SQLITE_LIMIT_LENGTH]);
    92     92     if( db->nVdbeExec>1 ){
    93     93       while( *zRawSql ){
    94     94         const char *zStart = zRawSql;
    95     95         while( *(zRawSql++)!='\n' && *zRawSql );
    96         -      sqlite3StrAccumAppend(&out, "-- ", 3);
           96  +      sqlite3_str_append(&out, "-- ", 3);
    97     97         assert( (zRawSql - zStart) > 0 );
    98         -      sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
           98  +      sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
    99     99       }
   100    100     }else if( p->nVar==0 ){
   101         -    sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
          101  +    sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql));
   102    102     }else{
   103    103       while( zRawSql[0] ){
   104    104         n = findNextHostParameter(zRawSql, &nToken);
   105    105         assert( n>0 );
   106         -      sqlite3StrAccumAppend(&out, zRawSql, n);
          106  +      sqlite3_str_append(&out, zRawSql, n);
   107    107         zRawSql += n;
   108    108         assert( zRawSql[0] || nToken==0 );
   109    109         if( nToken==0 ) break;
   110    110         if( zRawSql[0]=='?' ){
   111    111           if( nToken>1 ){
   112    112             assert( sqlite3Isdigit(zRawSql[1]) );
   113    113             sqlite3GetInt32(&zRawSql[1], &idx);
................................................................................
   125    125           assert( idx>0 );
   126    126         }
   127    127         zRawSql += nToken;
   128    128         nextIndex = idx + 1;
   129    129         assert( idx>0 && idx<=p->nVar );
   130    130         pVar = &p->aVar[idx-1];
   131    131         if( pVar->flags & MEM_Null ){
   132         -        sqlite3StrAccumAppend(&out, "NULL", 4);
          132  +        sqlite3_str_append(&out, "NULL", 4);
   133    133         }else if( pVar->flags & MEM_Int ){
   134         -        sqlite3XPrintf(&out, "%lld", pVar->u.i);
          134  +        sqlite3_str_appendf(&out, "%lld", pVar->u.i);
   135    135         }else if( pVar->flags & MEM_Real ){
   136         -        sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
          136  +        sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
   137    137         }else if( pVar->flags & MEM_Str ){
   138    138           int nOut;  /* Number of bytes of the string text to include in output */
   139    139   #ifndef SQLITE_OMIT_UTF16
   140    140           u8 enc = ENC(db);
   141    141           if( enc!=SQLITE_UTF8 ){
   142    142             memset(&utf8, 0, sizeof(utf8));
   143    143             utf8.db = db;
   144    144             sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
   145    145             if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
   146         -            out.accError = STRACCUM_NOMEM;
          146  +            out.accError = SQLITE_NOMEM;
   147    147               out.nAlloc = 0;
   148    148             }
   149    149             pVar = &utf8;
   150    150           }
   151    151   #endif
   152    152           nOut = pVar->n;
   153    153   #ifdef SQLITE_TRACE_SIZE_LIMIT
   154    154           if( nOut>SQLITE_TRACE_SIZE_LIMIT ){
   155    155             nOut = SQLITE_TRACE_SIZE_LIMIT;
   156    156             while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
   157    157           }
   158    158   #endif    
   159         -        sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
          159  +        sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z);
   160    160   #ifdef SQLITE_TRACE_SIZE_LIMIT
   161    161           if( nOut<pVar->n ){
   162         -          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
          162  +          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
   163    163           }
   164    164   #endif
   165    165   #ifndef SQLITE_OMIT_UTF16
   166    166           if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
   167    167   #endif
   168    168         }else if( pVar->flags & MEM_Zero ){
   169         -        sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
          169  +        sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero);
   170    170         }else{
   171    171           int nOut;  /* Number of bytes of the blob to include in output */
   172    172           assert( pVar->flags & MEM_Blob );
   173         -        sqlite3StrAccumAppend(&out, "x'", 2);
          173  +        sqlite3_str_append(&out, "x'", 2);
   174    174           nOut = pVar->n;
   175    175   #ifdef SQLITE_TRACE_SIZE_LIMIT
   176    176           if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
   177    177   #endif
   178    178           for(i=0; i<nOut; i++){
   179         -          sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
          179  +          sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff);
   180    180           }
   181         -        sqlite3StrAccumAppend(&out, "'", 1);
          181  +        sqlite3_str_append(&out, "'", 1);
   182    182   #ifdef SQLITE_TRACE_SIZE_LIMIT
   183    183           if( nOut<pVar->n ){
   184         -          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
          184  +          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
   185    185           }
   186    186   #endif
   187    187         }
   188    188       }
   189    189     }
   190         -  if( out.accError ) sqlite3StrAccumReset(&out);
          190  +  if( out.accError ) sqlite3_str_reset(&out);
   191    191     return sqlite3StrAccumFinish(&out);
   192    192   }
   193    193   
   194    194   #endif /* #ifndef SQLITE_OMIT_TRACE */

Changes to src/where.c.

  2858   2858           pNew->nSkip = 0;
  2859   2859           pNew->u.btree.pIndex = 0;
  2860   2860           pNew->nLTerm = 1;
  2861   2861           pNew->aLTerm[0] = pTerm;
  2862   2862           /* TUNING: One-time cost for computing the automatic index is
  2863   2863           ** estimated to be X*N*log2(N) where N is the number of rows in
  2864   2864           ** the table being indexed and where X is 7 (LogEst=28) for normal
  2865         -        ** tables or 1.375 (LogEst=4) for views and subqueries.  The value
         2865  +        ** tables or 0.5 (LogEst=-10) for views and subqueries.  The value
  2866   2866           ** of X is smaller for views and subqueries so that the query planner
  2867   2867           ** will be more aggressive about generating automatic indexes for
  2868   2868           ** those objects, since there is no opportunity to add schema
  2869   2869           ** indexes on subqueries and views. */
  2870         -        pNew->rSetup = rLogSize + rSize + 4;
         2870  +        pNew->rSetup = rLogSize + rSize;
  2871   2871           if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
  2872         -          pNew->rSetup += 24;
         2872  +          pNew->rSetup += 28;
         2873  +        }else{
         2874  +          pNew->rSetup -= 10;
  2873   2875           }
  2874   2876           ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
  2875   2877           if( pNew->rSetup<0 ) pNew->rSetup = 0;
  2876   2878           /* TUNING: Each index lookup yields 20 rows in the table.  This
  2877   2879           ** is more than the usual guess of 10 rows, since we have no way
  2878   2880           ** of knowing how selective the index will ultimately be.  It would
  2879   2881           ** not be unreasonable to make this value much larger. */
................................................................................
  4001   4003           LogEst rUnsorted;                 /* Unsorted cost of (pFrom+pWLoop) */
  4002   4004           i8 isOrdered = pFrom->isOrdered;  /* isOrdered for (pFrom+pWLoop) */
  4003   4005           Bitmask maskNew;                  /* Mask of src visited by (..) */
  4004   4006           Bitmask revMask = 0;              /* Mask of rev-order loops for (..) */
  4005   4007   
  4006   4008           if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
  4007   4009           if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
  4008         -        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){
         4010  +        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){
  4009   4011             /* Do not use an automatic index if the this loop is expected
  4010         -          ** to run less than 2 times. */
         4012  +          ** to run less than 1.25 times.  It is tempting to also exclude
         4013  +          ** automatic index usage on an outer loop, but sometimes an automatic
         4014  +          ** index is useful in the outer loop of a correlated subquery. */
  4011   4015             assert( 10==sqlite3LogEst(2) );
  4012   4016             continue;
  4013   4017           }
         4018  +
  4014   4019           /* At this point, pWLoop is a candidate to be the next loop. 
  4015   4020           ** Compute its cost */
  4016   4021           rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
  4017   4022           rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted);
  4018   4023           nOut = pFrom->nRow + pWLoop->nOut;
  4019   4024           maskNew = pFrom->maskLoop | pWLoop->maskSelf;
  4020   4025           if( isOrdered<0 ){
................................................................................
  4588   4593     /* Special case: No FROM clause
  4589   4594     */
  4590   4595     if( nTabList==0 ){
  4591   4596       if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr;
  4592   4597       if( wctrlFlags & WHERE_WANT_DISTINCT ){
  4593   4598         pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
  4594   4599       }
         4600  +    ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
  4595   4601     }else{
  4596   4602       /* Assign a bit from the bitmask to every term in the FROM clause.
  4597   4603       **
  4598   4604       ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
  4599   4605       **
  4600   4606       ** The rule of the previous sentence ensures thta if X is the bitmask for
  4601   4607       ** a table T, then X-1 is the bitmask for all other tables to the left of T.
................................................................................
  4983   4989       if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
  4984   4990         constructAutomaticIndex(pParse, &pWInfo->sWC,
  4985   4991                   &pTabList->a[pLevel->iFrom], notReady, pLevel);
  4986   4992         if( db->mallocFailed ) goto whereBeginError;
  4987   4993       }
  4988   4994   #endif
  4989   4995       addrExplain = sqlite3WhereExplainOneScan(
  4990         -        pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
         4996  +        pParse, pTabList, pLevel, wctrlFlags
  4991   4997       );
  4992   4998       pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
  4993   4999       notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
  4994   5000       pWInfo->iContinue = pLevel->addrCont;
  4995   5001       if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
  4996   5002         sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
  4997   5003       }

Changes to src/whereInt.h.

   463    463   
   464    464   /* wherecode.c: */
   465    465   #ifndef SQLITE_OMIT_EXPLAIN
   466    466   int sqlite3WhereExplainOneScan(
   467    467     Parse *pParse,                  /* Parse context */
   468    468     SrcList *pTabList,              /* Table list this loop refers to */
   469    469     WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
   470         -  int iLevel,                     /* Value for "level" column of output */
   471         -  int iFrom,                      /* Value for "from" column of output */
   472    470     u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
   473    471   );
   474    472   #else
   475         -# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0
          473  +# define sqlite3WhereExplainOneScan(u,v,w,x) 0
   476    474   #endif /* SQLITE_OMIT_EXPLAIN */
   477    475   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   478    476   void sqlite3WhereAddScanStatus(
   479    477     Vdbe *v,                        /* Vdbe to add scanstatus entry to */
   480    478     SrcList *pSrclist,              /* FROM clause pLvl reads data from */
   481    479     WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
   482    480     int addrExplain                 /* Address of OP_Explain (or 0) */

Changes to src/wherecode.c.

    47     47     int iTerm,                  /* Zero-based index of first term. */
    48     48     int bAnd,                   /* Non-zero to append " AND " */
    49     49     const char *zOp             /* Name of the operator */
    50     50   ){
    51     51     int i;
    52     52   
    53     53     assert( nTerm>=1 );
    54         -  if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
           54  +  if( bAnd ) sqlite3_str_append(pStr, " AND ", 5);
    55     55   
    56         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
           56  +  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
    57     57     for(i=0; i<nTerm; i++){
    58         -    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
    59         -    sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
           58  +    if( i ) sqlite3_str_append(pStr, ",", 1);
           59  +    sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i));
    60     60     }
    61         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
           61  +  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
    62     62   
    63         -  sqlite3StrAccumAppend(pStr, zOp, 1);
           63  +  sqlite3_str_append(pStr, zOp, 1);
    64     64   
    65         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
           65  +  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
    66     66     for(i=0; i<nTerm; i++){
    67         -    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
    68         -    sqlite3StrAccumAppend(pStr, "?", 1);
           67  +    if( i ) sqlite3_str_append(pStr, ",", 1);
           68  +    sqlite3_str_append(pStr, "?", 1);
    69     69     }
    70         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
           70  +  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
    71     71   }
    72     72   
    73     73   /*
    74     74   ** Argument pLevel describes a strategy for scanning table pTab. This 
    75     75   ** function appends text to pStr that describes the subset of table
    76     76   ** rows scanned by the strategy in the form of an SQL expression.
    77     77   **
................................................................................
    87     87   static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
    88     88     Index *pIndex = pLoop->u.btree.pIndex;
    89     89     u16 nEq = pLoop->u.btree.nEq;
    90     90     u16 nSkip = pLoop->nSkip;
    91     91     int i, j;
    92     92   
    93     93     if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
    94         -  sqlite3StrAccumAppend(pStr, " (", 2);
           94  +  sqlite3_str_append(pStr, " (", 2);
    95     95     for(i=0; i<nEq; i++){
    96     96       const char *z = explainIndexColumnName(pIndex, i);
    97         -    if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
    98         -    sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
           97  +    if( i ) sqlite3_str_append(pStr, " AND ", 5);
           98  +    sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
    99     99     }
   100    100   
   101    101     j = i;
   102    102     if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
   103    103       explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">");
   104    104       i = 1;
   105    105     }
   106    106     if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
   107    107       explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
   108    108     }
   109         -  sqlite3StrAccumAppend(pStr, ")", 1);
          109  +  sqlite3_str_append(pStr, ")", 1);
   110    110   }
   111    111   
   112    112   /*
   113    113   ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
   114    114   ** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
   115    115   ** defined at compile-time. If it is not a no-op, a single OP_Explain opcode 
   116    116   ** is added to the output to describe the table scan strategy in pLevel.
................................................................................
   118    118   ** If an OP_Explain opcode is added to the VM, its address is returned.
   119    119   ** Otherwise, if no OP_Explain is coded, zero is returned.
   120    120   */
   121    121   int sqlite3WhereExplainOneScan(
   122    122     Parse *pParse,                  /* Parse context */
   123    123     SrcList *pTabList,              /* Table list this loop refers to */
   124    124     WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
   125         -  int iLevel,                     /* Value for "level" column of output */
   126         -  int iFrom,                      /* Value for "from" column of output */
   127    125     u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
   128    126   ){
   129    127     int ret = 0;
   130    128   #if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
   131    129     if( sqlite3ParseToplevel(pParse)->explain==2 )
   132    130   #endif
   133    131     {
   134    132       struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
   135    133       Vdbe *v = pParse->pVdbe;      /* VM being constructed */
   136    134       sqlite3 *db = pParse->db;     /* Database handle */
   137         -    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
   138    135       int isSearch;                 /* True for a SEARCH. False for SCAN. */
   139    136       WhereLoop *pLoop;             /* The controlling WhereLoop object */
   140    137       u32 flags;                    /* Flags that describe this loop */
   141    138       char *zMsg;                   /* Text to add to EQP output */
   142    139       StrAccum str;                 /* EQP output string */
   143    140       char zBuf[100];               /* Initial space for EQP output string */
   144    141   
................................................................................
   147    144       if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0;
   148    145   
   149    146       isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
   150    147               || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
   151    148               || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
   152    149   
   153    150       sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
   154         -    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
          151  +    sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN");
   155    152       if( pItem->pSelect ){
   156         -      sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
          153  +      sqlite3_str_appendf(&str, " SUBQUERY 0x%p", pItem->pSelect);
   157    154       }else{
   158         -      sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
          155  +      sqlite3_str_appendf(&str, " TABLE %s", pItem->zName);
   159    156       }
   160    157   
   161    158       if( pItem->zAlias ){
   162         -      sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
          159  +      sqlite3_str_appendf(&str, " AS %s", pItem->zAlias);
   163    160       }
   164    161       if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
   165    162         const char *zFmt = 0;
   166    163         Index *pIdx;
   167    164   
   168    165         assert( pLoop->u.btree.pIndex!=0 );
   169    166         pIdx = pLoop->u.btree.pIndex;
................................................................................
   178    175           zFmt = "AUTOMATIC COVERING INDEX";
   179    176         }else if( flags & WHERE_IDX_ONLY ){
   180    177           zFmt = "COVERING INDEX %s";
   181    178         }else{
   182    179           zFmt = "INDEX %s";
   183    180         }
   184    181         if( zFmt ){
   185         -        sqlite3StrAccumAppend(&str, " USING ", 7);
   186         -        sqlite3XPrintf(&str, zFmt, pIdx->zName);
          182  +        sqlite3_str_append(&str, " USING ", 7);
          183  +        sqlite3_str_appendf(&str, zFmt, pIdx->zName);
   187    184           explainIndexRange(&str, pLoop);
   188    185         }
   189    186       }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
   190    187         const char *zRangeOp;
   191    188         if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
   192    189           zRangeOp = "=";
   193    190         }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
................................................................................
   194    191           zRangeOp = ">? AND rowid<";
   195    192         }else if( flags&WHERE_BTM_LIMIT ){
   196    193           zRangeOp = ">";
   197    194         }else{
   198    195           assert( flags&WHERE_TOP_LIMIT);
   199    196           zRangeOp = "<";
   200    197         }
   201         -      sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
          198  +      sqlite3_str_appendf(&str, 
          199  +          " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
   202    200       }
   203    201   #ifndef SQLITE_OMIT_VIRTUALTABLE
   204    202       else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
   205         -      sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
          203  +      sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
   206    204                     pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
   207    205       }
   208    206   #endif
   209    207   #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
   210    208       if( pLoop->nOut>=10 ){
   211         -      sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
          209  +      sqlite3_str_appendf(&str, " (~%llu rows)",
          210  +             sqlite3LogEstToInt(pLoop->nOut));
   212    211       }else{
   213         -      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
          212  +      sqlite3_str_append(&str, " (~1 row)", 9);
   214    213       }
   215    214   #endif
   216    215       zMsg = sqlite3StrAccumFinish(&str);
   217         -    ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
          216  +    ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
          217  +                            pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
   218    218     }
   219    219     return ret;
   220    220   }
   221    221   #endif /* SQLITE_OMIT_EXPLAIN */
   222    222   
   223    223   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   224    224   /*
................................................................................
  1930   1930       }
  1931   1931   
  1932   1932       /* Run a separate WHERE clause for each term of the OR clause.  After
  1933   1933       ** eliminating duplicates from other WHERE clauses, the action for each
  1934   1934       ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
  1935   1935       */
  1936   1936       wctrlFlags =  WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
         1937  +    ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR"));
  1937   1938       for(ii=0; ii<pOrWc->nTerm; ii++){
  1938   1939         WhereTerm *pOrTerm = &pOrWc->a[ii];
  1939   1940         if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
  1940   1941           WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
  1941   1942           Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
  1942   1943           int jmp1 = 0;                   /* Address of jump operation */
  1943   1944           assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 
................................................................................
  1951   1952           WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
  1952   1953           pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
  1953   1954                                         wctrlFlags, iCovCur);
  1954   1955           assert( pSubWInfo || pParse->nErr || db->mallocFailed );
  1955   1956           if( pSubWInfo ){
  1956   1957             WhereLoop *pSubLoop;
  1957   1958             int addrExplain = sqlite3WhereExplainOneScan(
  1958         -              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
         1959  +              pParse, pOrTab, &pSubWInfo->a[0], 0
  1959   1960             );
  1960   1961             sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
  1961   1962   
  1962   1963             /* This is the sub-WHERE clause body.  First skip over
  1963   1964             ** duplicate rows from prior sub-WHERE clauses, and record the
  1964   1965             ** rowid (or PRIMARY KEY) for the current row so that the same
  1965   1966             ** row will be skipped in subsequent sub-WHERE clauses.
................................................................................
  2050   2051             }
  2051   2052   
  2052   2053             /* Finish the loop through table entries that match term pOrTerm. */
  2053   2054             sqlite3WhereEnd(pSubWInfo);
  2054   2055           }
  2055   2056         }
  2056   2057       }
         2058  +    ExplainQueryPlanPop(pParse);
  2057   2059       pLevel->u.pCovidx = pCov;
  2058   2060       if( pCov ) pLevel->iIdxCur = iCovCur;
  2059   2061       if( pAndExpr ){
  2060   2062         pAndExpr->pLeft = 0;
  2061   2063         sqlite3ExprDelete(db, pAndExpr);
  2062   2064       }
  2063   2065       sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));

Changes to test/analyze3.test.

   114    114   
   115    115   # The first of the following two SELECT statements visits 99 rows. So
   116    116   # it is better to use the index. But the second visits every row in 
   117    117   # the table (1000 in total) so it is better to do a full-table scan.
   118    118   #
   119    119   do_eqp_test analyze3-1.1.2 {
   120    120     SELECT sum(y) FROM t1 WHERE x>200 AND x<300
   121         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
          121  +} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
   122    122   do_eqp_test analyze3-1.1.3 {
   123    123     SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 
   124         -} {0 0 0 {SCAN TABLE t1}}
          124  +} {SCAN TABLE t1}
   125    125   
   126    126   # 2017-06-26:  Verify that the SQLITE_DBCONFIG_ENABLE_QPSG setting disables
   127    127   # the use of bound parameters by STAT4
   128    128   #
   129    129   db cache flush
   130    130   unset -nocomplain l
   131    131   unset -nocomplain u
   132    132   do_eqp_test analyze3-1.1.3.100 {
   133    133     SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
   134         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
          134  +} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
   135    135   set l 200
   136    136   set u 300
   137    137   do_eqp_test analyze3-1.1.3.101 {
   138    138     SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
   139         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
          139  +} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
   140    140   set l 0
   141    141   set u 1100
   142    142   do_eqp_test analyze3-1.1.3.102 {
   143    143     SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
   144         -} {0 0 0 {SCAN TABLE t1}}
          144  +} {SCAN TABLE t1}
   145    145   db cache flush
   146    146   sqlite3_db_config db ENABLE_QPSG 1
   147    147   do_eqp_test analyze3-1.1.3.103 {
   148    148     SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
   149         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}}
          149  +} {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?)}
   150    150   db cache flush
   151    151   sqlite3_db_config db ENABLE_QPSG 0
   152    152   do_eqp_test analyze3-1.1.3.104 {
   153    153     SELECT sum(y) FROM t1 WHERE x>$l AND x<$u
   154         -} {0 0 0 {SCAN TABLE t1}}
          154  +} {SCAN TABLE t1}
   155    155   
   156    156   do_test analyze3-1.1.4 {
   157    157     sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
   158    158   } {199 0 14850}
   159    159   do_test analyze3-1.1.5 {
   160    160     set l [string range "200" 0 end]
   161    161     set u [string range "300" 0 end]
................................................................................
   197    197   } {}
   198    198   do_execsql_test analyze3-2.1.x {
   199    199     SELECT count(*) FROM t2 WHERE x>1 AND x<2;
   200    200     SELECT count(*) FROM t2 WHERE x>0 AND x<99;
   201    201   } {200 990}
   202    202   do_eqp_test analyze3-1.2.2 {
   203    203     SELECT sum(y) FROM t2 WHERE x>1 AND x<2
   204         -} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}}
          204  +} {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?)}
   205    205   do_eqp_test analyze3-1.2.3 {
   206    206     SELECT sum(y) FROM t2 WHERE x>0 AND x<99
   207         -} {0 0 0 {SCAN TABLE t2}}
          207  +} {SCAN TABLE t2}
   208    208   
   209    209   do_test analyze3-1.2.4 {
   210    210     sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
   211    211   } {161 0 4760}
   212    212   do_test analyze3-1.2.5 {
   213    213     set l [string range "12" 0 end]
   214    214     set u [string range "20" 0 end]
................................................................................
   249    249   } {}
   250    250   do_execsql_test analyze3-1.3.x {
   251    251     SELECT count(*) FROM t3 WHERE x>200 AND x<300;
   252    252     SELECT count(*) FROM t3 WHERE x>0 AND x<1100
   253    253   } {99 1000}
   254    254   do_eqp_test analyze3-1.3.2 {
   255    255     SELECT sum(y) FROM t3 WHERE x>200 AND x<300
   256         -} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}}
          256  +} {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?)}
   257    257   do_eqp_test analyze3-1.3.3 {
   258    258     SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
   259         -} {0 0 0 {SCAN TABLE t3}}
          259  +} {SCAN TABLE t3}
   260    260   
   261    261   do_test analyze3-1.3.4 {
   262    262     sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
   263    263   } {199 0 14850}
   264    264   do_test analyze3-1.3.5 {
   265    265     set l [string range "200" 0 end]
   266    266     set u [string range "300" 0 end]
................................................................................
   304    304       append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
   305    305       execsql { INSERT INTO t1 VALUES($i, $t) }
   306    306     }
   307    307     execsql COMMIT
   308    308   } {}
   309    309   do_eqp_test analyze3-2.2 {
   310    310     SELECT count(a) FROM t1 WHERE b LIKE 'a%'
   311         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}}
          311  +} {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?)}
   312    312   do_eqp_test analyze3-2.3 {
   313    313     SELECT count(a) FROM t1 WHERE b LIKE '%a'
   314         -} {0 0 0 {SCAN TABLE t1}}
          314  +} {SCAN TABLE t1}
   315    315   
   316    316   # Return the first argument if like_match_blobs is true (the default)
   317    317   # or the second argument if not
   318    318   #
   319    319   proc ilmb {a b} {
   320    320     ifcapable like_match_blobs {return $a}
   321    321     return $b
................................................................................
   694    694     }
   695    695     execsql COMMIT
   696    696     execsql ANALYZE
   697    697   } {}
   698    698   
   699    699   do_eqp_test analyze3-6-3 {
   700    700     SELECT * FROM t1 WHERE a = 5 AND c = 13;
   701         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
          701  +} {SEARCH TABLE t1 USING INDEX i2 (c=?)}
   702    702   
   703    703   do_eqp_test analyze3-6-2 {
   704    704     SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
   705         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
          705  +} {SEARCH TABLE t1 USING INDEX i2 (c=?)}
   706    706   
   707    707   #-----------------------------------------------------------------------------
   708    708   # 2015-04-20.
   709    709   # Memory leak in sqlite3Stat4ProbeFree().  (Discovered while fuzzing.)
   710    710   #
   711    711   do_execsql_test analyze-7.1 {
   712    712     DROP TABLE IF EXISTS t1;

Changes to test/analyze4.test.

    34     34       INSERT INTO t1 SELECT a+32, b FROM t1;
    35     35       INSERT INTO t1 SELECT a+64, b FROM t1;
    36     36       ANALYZE;
    37     37     }
    38     38   
    39     39     # Should choose the t1a index since it is more specific than t1b.
    40     40     db eval {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=5 AND b IS NULL}
    41         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           41  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    42     42   
    43     43   # Verify that the t1b index shows that it does not narrow down the
    44     44   # search any at all.
    45     45   #
    46     46   do_test analyze4-1.1 {
    47     47     db eval {
    48     48       SELECT idx, stat FROM sqlite_stat1 WHERE tbl='t1' ORDER BY idx;

Changes to test/analyze6.test.

    57     57   # The lowest cost plan is to scan CAT and for each integer there, do a single
    58     58   # lookup of the first corresponding entry in EV then read off the equal values
    59     59   # in EV.  (Prior to the 2011-03-04 enhancement to where.c, this query would
    60     60   # have used EV for the outer loop instead of CAT - which was about 3x slower.)
    61     61   #
    62     62   do_test analyze6-1.1 {
    63     63     eqp {SELECT count(*) FROM ev, cat WHERE x=y}
    64         -} {0 0 1 {SCAN TABLE cat USING COVERING INDEX catx} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?)}}
           64  +} {/*SCAN TABLE cat USING COVERING INDEX catx*SEARCH TABLE ev USING COVERING INDEX evy (y=?)*/}
    65     65   
    66     66   # The same plan is chosen regardless of the order of the tables in the
    67     67   # FROM clause.
    68     68   #
    69         -do_test analyze6-1.2 {
    70         -  eqp {SELECT count(*) FROM cat, ev WHERE x=y}
    71         -} {0 0 0 {SCAN TABLE cat USING COVERING INDEX catx} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?)}}
           69  +do_eqp_test analyze6-1.2 {
           70  +  SELECT count(*) FROM cat, ev WHERE x=y
           71  +} {
           72  +  QUERY PLAN
           73  +  |--SCAN TABLE cat USING COVERING INDEX catx
           74  +  `--SEARCH TABLE ev USING COVERING INDEX evy (y=?)
           75  +}
    72     76   
    73     77   
    74     78   # Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30
    75     79   # If ANALYZE is run on an empty table, make sure indices are used
    76     80   # on the table.
    77     81   #
    78     82   do_test analyze6-2.1 {
    79     83     execsql {
    80     84       CREATE TABLE t201(x INTEGER PRIMARY KEY, y UNIQUE, z);
    81     85       CREATE INDEX t201z ON t201(z);
    82     86       ANALYZE;
    83     87     }
    84     88     eqp {SELECT * FROM t201 WHERE z=5}
    85         -} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
           89  +} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/}
    86     90   do_test analyze6-2.2 {
    87     91     eqp {SELECT * FROM t201 WHERE y=5}
    88         -} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}}
           92  +} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/}
    89     93   do_test analyze6-2.3 {
    90     94     eqp {SELECT * FROM t201 WHERE x=5}
    91         -} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}}
           95  +} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/}
    92     96   do_test analyze6-2.4 {
    93     97     execsql {
    94     98       INSERT INTO t201 VALUES(1,2,3),(2,3,4),(3,4,5);
    95     99       ANALYZE t201;
    96    100     }
    97    101     eqp {SELECT * FROM t201 WHERE z=5}
    98         -} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
          102  +} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/}
    99    103   do_test analyze6-2.5 {
   100    104     eqp {SELECT * FROM t201 WHERE y=5}
   101         -} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}}
          105  +} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/}
   102    106   do_test analyze6-2.6 {
   103    107     eqp {SELECT * FROM t201 WHERE x=5}
   104         -} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}}
          108  +} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/}
   105    109   do_test analyze6-2.7 {
   106    110     execsql {
   107    111       INSERT INTO t201 VALUES(4,5,7);
   108    112       INSERT INTO t201 SELECT x+100, y+100, z+100 FROM t201;
   109    113       INSERT INTO t201 SELECT x+200, y+200, z+200 FROM t201;
   110    114       INSERT INTO t201 SELECT x+400, y+400, z+400 FROM t201;
   111    115       ANALYZE t201;
   112    116     }
   113    117     eqp {SELECT * FROM t201 WHERE z=5}
   114         -} {0 0 0 {SEARCH TABLE t201 USING INDEX t201z (z=?)}}
          118  +} {/*SEARCH TABLE t201 USING INDEX t201z (z=?)*/}
   115    119   do_test analyze6-2.8 {
   116    120     eqp {SELECT * FROM t201 WHERE y=5}
   117         -} {0 0 0 {SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)}}
          121  +} {/*SEARCH TABLE t201 USING INDEX sqlite_autoindex_t201_1 (y=?)*/}
   118    122   do_test analyze6-2.9 {
   119    123     eqp {SELECT * FROM t201 WHERE x=5}
   120         -} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}}
          124  +} {/*SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)*/}
   121    125   
   122    126   finish_test

Changes to test/analyze7.test.

    33     33       CREATE INDEX t1b ON t1(b);
    34     34       CREATE INDEX t1cd ON t1(c,d);
    35     35       CREATE VIRTUAL TABLE nums USING wholenumber;
    36     36       INSERT INTO t1 SELECT value, value, value/100, value FROM nums
    37     37                       WHERE value BETWEEN 1 AND 256;
    38     38       EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;
    39     39     }
    40         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           40  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    41     41   do_test analyze7-1.1 {
    42     42     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
    43         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
           43  +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
    44     44   do_test analyze7-1.2 {
    45     45     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
    46         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
           46  +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    47     47   
    48     48   # Run an analyze on one of the three indices.  Verify that this
    49     49   # effects the row-count estimate on the one query that uses that
    50     50   # one index.
    51     51   #
    52     52   do_test analyze7-2.0 {
    53     53     execsql {ANALYZE t1a;}
    54     54     db cache flush
    55     55     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;}
    56         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           56  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    57     57   do_test analyze7-2.1 {
    58     58     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
    59         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
           59  +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
    60     60   do_test analyze7-2.2 {
    61     61     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
    62         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
           62  +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    63     63   
    64     64   # Verify that since the query planner now things that t1a is more
    65     65   # selective than t1b, it prefers to use t1a.
    66     66   #
    67     67   do_test analyze7-2.3 {
    68     68     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
    69         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           69  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    70     70   
    71     71   # Run an analysis on another of the three indices.  Verify  that this
    72     72   # new analysis works and does not disrupt the previous analysis.
    73     73   #
    74     74   do_test analyze7-3.0 {
    75     75     execsql {ANALYZE t1cd;}
    76     76     db cache flush;
    77     77     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123;}
    78         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           78  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    79     79   do_test analyze7-3.1 {
    80     80     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
    81         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
           81  +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
    82     82   do_test analyze7-3.2.1 {
    83     83     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
    84         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
           84  +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    85     85   ifcapable stat4||stat3 {
    86     86     # If ENABLE_STAT4 is defined, SQLite comes up with a different estimated
    87     87     # row count for (c=2) than it does for (c=?).
    88     88     do_test analyze7-3.2.2 {
    89     89       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
    90         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
           90  +  } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    91     91   } else {
    92     92     # If ENABLE_STAT4 is not defined, the expected row count for (c=2) is the
    93     93     # same as that for (c=?).
    94     94     do_test analyze7-3.2.3 {
    95     95       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
    96         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?)}}
           96  +  } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    97     97   }
    98     98   do_test analyze7-3.3 {
    99     99     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
   100         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
          100  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
   101    101   
   102    102   ifcapable {!stat4 && !stat3} {
   103    103     do_test analyze7-3.4 {
   104    104       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123}
   105         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
          105  +  } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
   106    106     do_test analyze7-3.5 {
   107    107       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123}
   108         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
          108  +  } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
   109    109   }
   110    110   do_test analyze7-3.6 {
   111    111     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123}
   112         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)}}
          112  +} {/*SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)*/}
   113    113   
   114    114   finish_test

Changes to test/analyze8.test.

    57     57   # with a==100.  And so for those cases, choose the t1b index.
    58     58   #
    59     59   # Buf ro a==99 and a==101, there are far fewer rows so choose
    60     60   # the t1a index.
    61     61   #
    62     62   do_test 1.1 {
    63     63     eqp {SELECT * FROM t1 WHERE a=100 AND b=55}
    64         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
           64  +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
    65     65   do_test 1.2 {
    66     66     eqp {SELECT * FROM t1 WHERE a=99 AND b=55}
    67         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           67  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    68     68   do_test 1.3 {
    69     69     eqp {SELECT * FROM t1 WHERE a=101 AND b=55}
    70         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           70  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    71     71   do_test 1.4 {
    72     72     eqp {SELECT * FROM t1 WHERE a=100 AND b=56}
    73         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
           73  +} {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
    74     74   do_test 1.5 {
    75     75     eqp {SELECT * FROM t1 WHERE a=99 AND b=56}
    76         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           76  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    77     77   do_test 1.6 {
    78     78     eqp {SELECT * FROM t1 WHERE a=101 AND b=56}
    79         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
           79  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    80     80   do_test 2.1 {
    81     81     eqp {SELECT * FROM t1 WHERE a=100 AND b BETWEEN 50 AND 54}
    82         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
           82  +} {/*SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)*/}
    83     83   
    84     84   # There are many more values of c between 0 and 100000 than there are
    85     85   # between 800000 and 900000.  So t1c is more selective for the latter
    86     86   # range.
    87     87   # 
    88     88   # Test 3.2 is a little unstable. It depends on the planner estimating
    89     89   # that (b BETWEEN 30 AND 34) will match more rows than (c BETWEEN
................................................................................
    95     95   do_execsql_test 3.0 {
    96     96     SELECT count(*) FROM t1 WHERE b BETWEEN 30 AND 34;
    97     97     SELECT count(*) FROM t1 WHERE c BETWEEN 0 AND 100000;
    98     98     SELECT count(*) FROM t1 WHERE c BETWEEN 800000 AND 900000;
    99     99   } {50 376 32}
   100    100   do_test 3.1 {
   101    101     eqp {SELECT * FROM t1 WHERE b BETWEEN 30 AND 34 AND c BETWEEN 0 AND 100000}
   102         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
          102  +} {/*SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)*/}
   103    103   do_test 3.2 {
   104    104     eqp {SELECT * FROM t1
   105    105          WHERE b BETWEEN 30 AND 34 AND c BETWEEN 800000 AND 900000}
   106         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
          106  +} {/*SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)*/}
   107    107   do_test 3.3 {
   108    108     eqp {SELECT * FROM t1 WHERE a=100 AND c BETWEEN 0 AND 100000}
   109         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?)}}
          109  +} {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
   110    110   do_test 3.4 {
   111    111     eqp {SELECT * FROM t1
   112    112          WHERE a=100 AND c BETWEEN 800000 AND 900000}
   113         -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
          113  +} {/*SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)*/}
   114    114   
   115    115   finish_test

Changes to test/analyze9.test.

   983    983   } {/*USING INTEGER PRIMARY KEY*/}
   984    984   
   985    985   #-------------------------------------------------------------------------
   986    986   #
   987    987   reset_db
   988    988   do_execsql_test 22.0 {
   989    989     CREATE TABLE t3(a, b, c, d, PRIMARY KEY(a, b)) WITHOUT ROWID;
   990         -}
          990  +  SELECT * FROM t3;
          991  +} {}
   991    992   do_execsql_test 22.1 {
   992    993     WITH r(x) AS (
   993    994       SELECT 1
   994    995       UNION ALL
   995    996       SELECT x+1 FROM r WHERE x<=100
   996    997     )
   997    998   
................................................................................
  1051   1052   
  1052   1053   do_eqp_test 23.1 {
  1053   1054     SELECT * FROM t4 WHERE 
  1054   1055       (e=1 AND b='xyz' AND c='zyx' AND a<'AEA') AND f<300
  1055   1056     -- Formerly used index i41.  But i41 is not a covering index whereas
  1056   1057     -- the PRIMARY KEY is a covering index, and so as of 2017-10-15, the
  1057   1058     -- PRIMARY KEY is preferred.
  1058         -} {
  1059         -  0 0 0 {SEARCH TABLE t4 USING PRIMARY KEY (c=? AND b=? AND a<?)}
  1060         -}
         1059  +} {SEARCH TABLE t4 USING PRIMARY KEY (c=? AND b=? AND a<?)}
  1061   1060   do_eqp_test 23.2 {
  1062   1061     SELECT * FROM t4 WHERE 
  1063   1062       (e=1 AND b='xyz' AND c='zyx' AND a<'JJJ') AND f<300
  1064         -} {
  1065         -  0 0 0 {SEARCH TABLE t4 USING INDEX i42 (f<?)}
  1066         -}
         1063  +} {SEARCH TABLE t4 USING INDEX i42 (f<?)}
  1067   1064   
  1068   1065   do_execsql_test 24.0 {
  1069   1066     CREATE TABLE t5(c, d, b, e, a, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
  1070   1067     WITH data(a, b, c, d, e) AS (
  1071   1068       SELECT 'z', 'y', 0, 0, 0
  1072   1069       UNION ALL
  1073   1070       SELECT 
................................................................................
  1104   1101       CREATE INDEX aa ON t6(a);
  1105   1102       CREATE INDEX bb ON t6(b);
  1106   1103       ANALYZE;
  1107   1104     }
  1108   1105   
  1109   1106     # Term (b<?) is estimated at 25%. Better than (a<30) but not as
  1110   1107     # good as (a<20).
  1111         -  do_eqp_test 25.2.1 { SELECT * FROM t6 WHERE a<30 AND b<? } {
  1112         -    0 0 0 {SEARCH TABLE t6 USING INDEX bb (b<?)}
  1113         -  }
  1114         -  do_eqp_test 25.2.2 { SELECT * FROM t6 WHERE a<20 AND b<? } {
  1115         -    0 0 0 {SEARCH TABLE t6 USING INDEX aa (a<?)}
  1116         -  }
         1108  +  do_eqp_test 25.2.1 { SELECT * FROM t6 WHERE a<30 AND b<? } \
         1109  +    {SEARCH TABLE t6 USING INDEX bb (b<?)}
         1110  +  do_eqp_test 25.2.2 { SELECT * FROM t6 WHERE a<20 AND b<? } \
         1111  +    {SEARCH TABLE t6 USING INDEX aa (a<?)}
  1117   1112   
  1118   1113     # Term (b BETWEEN ? AND ?) is estimated at 1/64.
  1119   1114     do_eqp_test 25.3.1 { 
  1120   1115       SELECT * FROM t6 WHERE a BETWEEN 5 AND 10 AND b BETWEEN ? AND ? 
  1121         -  } {
  1122         -    0 0 0 {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
  1123         -  }
         1116  +  } {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
  1124   1117     
  1125   1118     # Term (b BETWEEN ? AND 60) is estimated to return roughly 15 rows -
  1126   1119     # 60 from (b<=60) multiplied by 0.25 for the b>=? term. Better than
  1127   1120     # (a<20) but not as good as (a<10).
  1128   1121     do_eqp_test 25.4.1 { 
  1129   1122       SELECT * FROM t6 WHERE a < 10 AND (b BETWEEN ? AND 60)
  1130         -  } {
  1131         -    0 0 0 {SEARCH TABLE t6 USING INDEX aa (a<?)}
  1132         -  }
         1123  +  } {SEARCH TABLE t6 USING INDEX aa (a<?)}
         1124  +
  1133   1125     do_eqp_test 25.4.2 { 
  1134   1126       SELECT * FROM t6 WHERE a < 20 AND (b BETWEEN ? AND 60)
  1135         -  } {
  1136         -    0 0 0 {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
  1137         -  }
         1127  +  } {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)}
  1138   1128   }
  1139   1129   
  1140   1130   #-------------------------------------------------------------------------
  1141   1131   # Check that a problem in they way stat4 data is used has been 
  1142   1132   # resolved (see below).
  1143   1133   #
  1144   1134   reset_db
................................................................................
  1186   1176   # no more than that. Guessing less than 20 is therefore unreasonable.
  1187   1177   #
  1188   1178   # At one point though, due to a problem in whereKeyStats(), the planner was
  1189   1179   # estimating that (x=10000 AND y<50) would match only 2 rows.
  1190   1180   #
  1191   1181   do_eqp_test 26.1.4 {
  1192   1182     SELECT * FROM t1 WHERE x = 10000 AND y < 50 AND z = 444;
  1193         -} {
  1194         -  0 0 0 {SEARCH TABLE t1 USING INDEX t1z (z=?)}
  1195         -}
         1183  +} {SEARCH TABLE t1 USING INDEX t1z (z=?)}
  1196   1184   
  1197   1185   
  1198   1186   # This test - 26.2.* - tests that another manifestation of the same problem
  1199   1187   # is no longer present in the library. Assuming:
  1200   1188   # 
  1201   1189   #   CREATE INDEX t1xy ON t1(x, y)
  1202   1190   #
................................................................................
  1237   1225       UPDATE t1 SET z = (rowid / 95);
  1238   1226       ANALYZE;
  1239   1227     COMMIT;
  1240   1228   }
  1241   1229   
  1242   1230   do_eqp_test 26.2.2 {
  1243   1231     SELECT * FROM t1 WHERE x='B' AND y>25 AND z=?;
  1244         -} {
  1245         -  0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)}
  1246         -}
         1232  +} {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)}
  1247   1233   
  1248   1234   
  1249   1235   finish_test

Changes to test/analyzeA.test.

   132    132     do_execsql_test 1.$tn.2.1 { SELECT count(*) FROM t1 WHERE b=31 } 1
   133    133     do_execsql_test 1.$tn.2.2 { SELECT count(*) FROM t1 WHERE c=0  } 49
   134    134     do_execsql_test 1.$tn.2.3 { SELECT count(*) FROM t1 WHERE b=125  } 49
   135    135     do_execsql_test 1.$tn.2.4 { SELECT count(*) FROM t1 WHERE c=16  } 1
   136    136   
   137    137     do_eqp_test 1.$tn.2.5 {
   138    138       SELECT * FROM t1 WHERE b = 31 AND c = 0;
   139         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}}
          139  +  } {SEARCH TABLE t1 USING INDEX t1b (b=?)}
   140    140     do_eqp_test 1.$tn.2.6 {
   141    141       SELECT * FROM t1 WHERE b = 125 AND c = 16;
   142         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?)}}
          142  +  } {SEARCH TABLE t1 USING INDEX t1c (c=?)}
   143    143   
   144    144     do_execsql_test 1.$tn.3.1 { 
   145    145       SELECT count(*) FROM t1 WHERE b BETWEEN 0 AND 50
   146    146     } {6}
   147    147     do_execsql_test 1.$tn.3.2 { 
   148    148       SELECT count(*) FROM t1 WHERE c BETWEEN 0 AND 50
   149    149     } {90}
................................................................................
   152    152     } {90}
   153    153     do_execsql_test 1.$tn.3.4 { 
   154    154       SELECT count(*) FROM t1 WHERE c BETWEEN 75 AND 125
   155    155     } {6}
   156    156   
   157    157     do_eqp_test 1.$tn.3.5 {
   158    158       SELECT * FROM t1 WHERE b BETWEEN 0 AND 50 AND c BETWEEN 0 AND 50
   159         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
          159  +  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
   160    160   
   161    161     do_eqp_test 1.$tn.3.6 {
   162    162       SELECT * FROM t1 WHERE b BETWEEN 75 AND 125 AND c BETWEEN 75 AND 125
   163         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
          163  +  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
   164    164   
   165    165     do_eqp_test 1.$tn.3.7 {
   166    166       SELECT * FROM t1 WHERE b BETWEEN +0 AND +50 AND c BETWEEN +0 AND +50
   167         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
          167  +  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
   168    168   
   169    169     do_eqp_test 1.$tn.3.8 {
   170    170       SELECT * FROM t1
   171    171        WHERE b BETWEEN cast('0' AS int) AND cast('50.0' AS real)
   172    172          AND c BETWEEN cast('0' AS numeric) AND cast('50.0' AS real)
   173         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}}
          173  +  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
   174    174   
   175    175     do_eqp_test 1.$tn.3.9 {
   176    176       SELECT * FROM t1 WHERE b BETWEEN +75 AND +125 AND c BETWEEN +75 AND +125
   177         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
          177  +  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
   178    178   
   179    179     do_eqp_test 1.$tn.3.10 {
   180    180       SELECT * FROM t1
   181    181        WHERE b BETWEEN cast('75' AS int) AND cast('125.0' AS real)
   182    182          AND c BETWEEN cast('75' AS numeric) AND cast('125.0' AS real)
   183         -  } {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}}
          183  +  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
   184    184   }
   185    185   
   186    186   finish_test

Changes to test/analyzeD.test.

    59     59   } {}
    60     60   
    61     61   # With full ANALYZE data, SQLite sees that c=150 (5 rows) is better than
    62     62   # a=3001 (7 rows).
    63     63   #
    64     64   do_eqp_test 1.2 {
    65     65     SELECT * FROM t1 WHERE a=3001 AND c=150;
    66         -} {
    67         -  0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
    68         -}
           66  +} {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
    69     67   
    70     68   do_test 1.3 {
    71     69     execsql { DELETE FROM sqlite_stat1 }
    72     70     db close
    73     71     sqlite3 db test.db
    74     72   } {}
    75     73   
................................................................................
    76     74   # Without stat1, because 3001 is larger than all samples in the stat4
    77     75   # table, SQLite thinks that a=3001 matches just 1 row. So it (incorrectly)
    78     76   # chooses it over the c=150 index (5 rows). Even with stat1 data, things
    79     77   # worked this way before commit [e6f7f97dbc].
    80     78   #
    81     79   do_eqp_test 1.4 {
    82     80     SELECT * FROM t1 WHERE a=3001 AND c=150;
    83         -} {
    84         -  0 0 0 {SEARCH TABLE t1 USING INDEX t1_ab (a=?)}
    85         -}
           81  +} {SEARCH TABLE t1 USING INDEX t1_ab (a=?)}
    86     82   
    87     83   do_test 1.5 {
    88     84     execsql { 
    89     85       UPDATE t1 SET a=13 WHERE a = 3001;
    90     86       ANALYZE;
    91     87     }
    92     88   } {}
    93     89   
    94     90   do_eqp_test 1.6 {
    95     91     SELECT * FROM t1 WHERE a=13 AND c=150;
    96         -} {
    97         -  0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
    98         -}
           92  +} {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
    99     93   
   100     94   do_test 1.7 {
   101     95     execsql { DELETE FROM sqlite_stat1 }
   102     96     db close
   103     97     sqlite3 db test.db
   104     98   } {}
   105     99   
   106    100   # Same test as 1.4, except this time the 7 rows that match the a=? condition 
   107    101   # do not feature larger values than all rows in the stat4 table. So SQLite
   108    102   # gets this right, even without stat1 data.
   109    103   do_eqp_test 1.8 {
   110    104     SELECT * FROM t1 WHERE a=13 AND c=150;
   111         -} {
   112         -  0 0 0 {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
   113         -}
          105  +} {SEARCH TABLE t1 USING INDEX t1_c (c=?)}
   114    106   
   115    107   finish_test

Changes to test/analyzeF.test.

    58     58   
    59     59     9  "x = str('19') AND y = str('4')" {t1y (y=?)}
    60     60     10 "x = str('4') AND y = str('19')" {t1y (y=?)}
    61     61   
    62     62     11 "x = nullif('19', 0) AND y = nullif('4', 0)" {t1y (y=?)}
    63     63     12 "x = nullif('4', 0) AND y = nullif('19', 0)" {t1y (y=?)}
    64     64   } {
    65         -  set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}"
           65  +  set res "SEARCH TABLE t1 USING INDEX $idx"
    66     66     do_eqp_test 1.$tn "SELECT * FROM t1 WHERE $where" $res
    67     67   }
    68     68   
    69     69   # Test that functions that do not exist - "func()" - do not cause an error.
    70     70   #
    71     71   do_catchsql_test 2.1 {
    72     72     SELECT * FROM t1 WHERE x = substr('145', 2, 1) AND y = func(1, 2, 3)
................................................................................
    88     88   foreach {tn where idx} {
    89     89     1 "x = det4() AND y = det19()"     {t1x (x=?)}
    90     90     2 "x = det19() AND y = det4()"     {t1y (y=?)}
    91     91   
    92     92     3 "x = nondet4() AND y = nondet19()"     {t1y (y=?)}
    93     93     4 "x = nondet19() AND y = nondet4()"     {t1y (y=?)}
    94     94   } {
    95         -  set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}"
           95  +  set res "SEARCH TABLE t1 USING INDEX $idx"
    96     96     do_eqp_test 3.$tn "SELECT * FROM t1 WHERE $where" $res
    97     97   }
    98     98   
    99     99   
   100    100   execsql { DELETE FROM t1 }
   101    101   
   102    102   proc throw_error {err} { error $err }

Changes to test/autoindex1.test.

   173    173   #
   174    174   do_execsql_test autoindex1-500 {
   175    175     CREATE TABLE t501(a INTEGER PRIMARY KEY, b);
   176    176     CREATE TABLE t502(x INTEGER PRIMARY KEY, y);
   177    177     INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t501',null,'1000000');
   178    178     INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t502',null,'1000');
   179    179     ANALYZE sqlite_master;
   180         -  EXPLAIN QUERY PLAN
          180  +}
          181  +do_eqp_test autoindex1-500.1 {
   181    182     SELECT b FROM t501
   182    183      WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
   183    184   } {
   184         -  0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)} 
   185         -  0 0 0 {EXECUTE LIST SUBQUERY 1} 
   186         -  1 0 0 {SCAN TABLE t502}
          185  +  QUERY PLAN
          186  +  |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
          187  +  `--LIST SUBQUERY
          188  +     `--SCAN TABLE t502
   187    189   }
   188         -do_execsql_test autoindex1-501 {
   189         -  EXPLAIN QUERY PLAN
          190  +do_eqp_test autoindex1-501 {
   190    191     SELECT b FROM t501
   191    192      WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
   192    193   } {
   193         -  0 0 0 {SCAN TABLE t501} 
   194         -  0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 
   195         -  1 0 0 {SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)}
          194  +  QUERY PLAN
          195  +  |--SCAN TABLE t501
          196  +  `--CORRELATED LIST SUBQUERY
          197  +     `--SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)
   196    198   }
   197         -do_execsql_test autoindex1-502 {
   198         -  EXPLAIN QUERY PLAN
          199  +do_eqp_test autoindex1-502 {
   199    200     SELECT b FROM t501
   200    201      WHERE t501.a=123
   201    202        AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
   202    203   } {
   203         -  0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)} 
   204         -  0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 
   205         -  1 0 0 {SCAN TABLE t502}
          204  +  QUERY PLAN
          205  +  |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
          206  +  `--CORRELATED LIST SUBQUERY
          207  +     `--SCAN TABLE t502
   206    208   }
   207         -
   208    209   
   209    210   # The following code checks a performance regression reported on the
   210    211   # mailing list on 2010-10-19.  The problem is that the nRowEst field
   211    212   # of ephermeral tables was not being initialized correctly and so no
   212    213   # automatic index was being created for the emphemeral table when it was
   213    214   # used as part of a join.
   214    215   #
................................................................................
   253    254                 ON flock_owner (owner_change_date);
   254    255     CREATE INDEX fo_owner_person_id_index  
   255    256                 ON flock_owner (owner_person_id);
   256    257     CREATE INDEX sheep_org_flock_index  
   257    258              ON sheep (originating_flock);
   258    259     CREATE INDEX sheep_reg_flock_index  
   259    260              ON sheep (registering_flock);
   260         -  EXPLAIN QUERY PLAN
          261  +}
          262  +do_eqp_test autoindex1-600a {
   261    263     SELECT x.sheep_no, x.registering_flock, x.date_of_registration
   262    264      FROM sheep x LEFT JOIN
   263    265          (SELECT s.sheep_no, prev.flock_no, prev.owner_person_id,
   264    266          s.date_of_registration, prev.owner_change_date
   265    267          FROM sheep s JOIN flock_owner prev ON s.registering_flock =
   266    268      prev.flock_no
   267    269          AND (prev.owner_change_date <= s.date_of_registration || ' 00:00:00')
................................................................................
   270    272              WHERE prev.flock_no = later.flock_no
   271    273              AND later.owner_change_date > prev.owner_change_date
   272    274              AND later.owner_change_date <= s.date_of_registration||' 00:00:00')
   273    275          ) y ON x.sheep_no = y.sheep_no
   274    276      WHERE y.sheep_no IS NULL
   275    277      ORDER BY x.registering_flock;
   276    278   } {
   277         -  1 0 0 {SCAN TABLE sheep AS s} 
   278         -  1 1 1 {SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date<?)} 
   279         -  1 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2} 
   280         -  2 0 0 {SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date<?)} 
   281         -  0 0 0 {SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index} 
   282         -  0 1 1 {SEARCH SUBQUERY 1 AS y USING AUTOMATIC COVERING INDEX (sheep_no=?)}
          279  +  QUERY PLAN
          280  +  |--MATERIALIZE xxxxxx
          281  +  |  |--SCAN TABLE sheep AS s
          282  +  |  |--SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date<?)
          283  +  |  `--CORRELATED SCALAR SUBQUERY
          284  +  |     `--SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date<?)
          285  +  |--SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index
          286  +  `--SEARCH SUBQUERY xxxxxx AS y USING AUTOMATIC COVERING INDEX (sheep_no=?)
   283    287   }
   284    288   
   285    289   
   286    290   do_execsql_test autoindex1-700 {
   287    291     CREATE TABLE t5(a, b, c);
   288         -  EXPLAIN QUERY PLAN SELECT a FROM t5 WHERE b=10 ORDER BY c;
          292  +}
          293  +do_eqp_test autoindex1-700a {
          294  +  SELECT a FROM t5 WHERE b=10 ORDER BY c;
   289    295   } {
   290         -  0 0 0 {SCAN TABLE t5} 
   291         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          296  +  QUERY PLAN
          297  +  |--SCAN TABLE t5
          298  +  `--USE TEMP B-TREE FOR ORDER BY
   292    299   }
   293    300   
   294    301   # The following checks a performance issue reported on the sqlite-dev
   295    302   # mailing list on 2013-01-10
   296    303   #
   297    304   do_execsql_test autoindex1-800 {
   298    305     CREATE TABLE accounts(

Changes to test/autoindex3.test.

    80     80   # on the basis that the real index "uab" must be better than the automatic
    81     81   # index. This is not right - a skip-scan is not necessarily better than an
    82     82   # automatic index scan.
    83     83   #
    84     84   do_eqp_test 220 {
    85     85     select count(*) from u, v where u.b = v.b and v.e > 34;
    86     86   } {
    87         -  0 0 1 {SEARCH TABLE v USING INDEX ve (e>?)} 
    88         -  0 1 0 {SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)}
           87  +  QUERY PLAN
           88  +  |--SEARCH TABLE v USING INDEX ve (e>?)
           89  +  `--SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)
    89     90   }
    90     91   
    91     92   
    92     93   finish_test

Changes to test/autoindex5.test.

    80     80                 AND debian_bugs.note = package_notes.id
    81     81                 ORDER BY debian_bugs.bug;
    82     82   } {}
    83     83   
    84     84   # The following query should use an automatic index for the view
    85     85   # in FROM clause of the subquery of the second result column.
    86     86   #
    87         -do_execsql_test autoindex5-1.1 {
    88         -  EXPLAIN QUERY PLAN
           87  +do_eqp_test autoindex5-1.1 {
    89     88     SELECT
    90     89       st.bug_name,
    91     90       (SELECT ALL debian_cve.bug FROM debian_cve
    92     91         WHERE debian_cve.bug_name = st.bug_name
    93     92         ORDER BY debian_cve.bug),
    94     93       sp.release
    95     94     FROM
................................................................................
    99     98     WHERE
   100     99        sp.rowid = st.package
   101    100        AND st.bug_name = bugs.name
   102    101        AND ( st.bug_name LIKE 'CVE-%' OR st.bug_name LIKE 'TEMP-%' )
   103    102        AND ( sp.release = 'sid' OR sp.release = 'stretch' OR sp.release = 'jessie'
   104    103               OR sp.release = 'wheezy' OR sp.release = 'squeeze' )
   105    104     ORDER BY sp.name, st.bug_name, sp.release, sp.subrelease;
   106         -} {/SEARCH SUBQUERY 2 USING AUTOMATIC COVERING INDEX .bug_name=/}
          105  +} {SEARCH SUBQUERY * USING AUTOMATIC COVERING INDEX (bug_name=?)}
   107    106   
   108    107   #-------------------------------------------------------------------------
   109    108   # Test that ticket [8a2adec1] has been fixed.
   110    109   #
   111    110   do_execsql_test 2.1 {
   112    111     CREATE TABLE one(o);
   113    112     INSERT INTO one DEFAULT VALUES;

Changes to test/bestindex1.test.

    47     47   
    48     48   do_execsql_test 1.0 {
    49     49     CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
    50     50   } {}
    51     51   
    52     52   do_eqp_test 1.1 {
    53     53     SELECT * FROM x1 WHERE a = 'abc'
    54         -} {
    55         -  0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
    56         -}
           54  +} {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
    57     55   
    58     56   do_eqp_test 1.2 {
    59     57     SELECT * FROM x1 WHERE a IN ('abc', 'def');
    60         -} {
    61         -  0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
    62         -}
           58  +} {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
    63     59   
    64     60   #-------------------------------------------------------------------------
    65     61   #
    66     62   reset_db
    67     63   register_tcl_module db
    68     64   
    69     65   # Parameter $mode may be one of:
................................................................................
   140    136     do_execsql_test 2.2.$mode.4 {SELECT rowid FROM t1 WHERE a='two'} {2} 
   141    137   
   142    138     do_execsql_test 2.2.$mode.5 {
   143    139       SELECT rowid FROM t1 WHERE a IN ('one', 'four') ORDER BY +rowid
   144    140     } {1 4} 
   145    141   
   146    142     set plan(use) {
   147         -    0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'}
   148         -    0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          143  +    QUERY PLAN
          144  +    |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'
          145  +    `--USE TEMP B-TREE FOR ORDER BY
   149    146     }
   150    147     set plan(omit) {
   151         -    0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'}
   152         -    0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          148  +    QUERY PLAN
          149  +    |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'
          150  +    `--USE TEMP B-TREE FOR ORDER BY
   153    151     }
   154    152     set plan(use2) {
   155         -    0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x}
   156         -    0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          153  +    QUERY PLAN
          154  +    |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x
          155  +    `--USE TEMP B-TREE FOR ORDER BY
   157    156     }
   158    157   
   159    158     do_eqp_test 2.2.$mode.6 { 
   160    159       SELECT rowid FROM t1 WHERE a IN ('one', 'four') ORDER BY +rowid
   161         -  } $plan($mode)
          160  +  } [string map {"\n  " "\n"} $plan($mode)]
   162    161   }
   163    162   
   164    163   # 2016-04-09.
   165    164   # Demonstrate a register overwrite problem when using two virtual
   166    165   # tables where the outer loop uses the IN operator.
   167    166   #
   168    167   set G(collist) [list PrimaryKey flagA columnA]

Changes to test/bestindex2.test.

    85     85     CREATE VIRTUAL TABLE t1 USING tcl("vtab_cmd t1 {a b}");
    86     86     CREATE VIRTUAL TABLE t2 USING tcl("vtab_cmd t2 {c d}");
    87     87     CREATE VIRTUAL TABLE t3 USING tcl("vtab_cmd t3 {e f}");
    88     88   }
    89     89   
    90     90   do_eqp_test 1.1 {
    91     91     SELECT * FROM t1 WHERE a='abc'
    92         -} {
    93         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
    94         -}
           92  +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
           93  +
    95     94   do_eqp_test 1.2 {
    96     95     SELECT * FROM t1 WHERE a='abc' AND b='def'
    97         -} {
    98         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=? AND b=?)}
    99         -}
           96  +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=? AND b=?)}
           97  +
   100     98   do_eqp_test 1.3 {
   101     99     SELECT * FROM t1 WHERE a='abc' AND a='def'
   102         -} {
   103         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
   104         -}
          100  +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:indexed(a=?)}
          101  +
   105    102   do_eqp_test 1.4 {
   106    103     SELECT * FROM t1,t2 WHERE c=a
   107    104   } {
   108         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:} 
   109         -  0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)}
          105  +  QUERY PLAN
          106  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
          107  +  `--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
   110    108   }
   111    109   
   112    110   do_eqp_test 1.5 {
   113    111     SELECT * FROM t1, t2 CROSS JOIN t3 WHERE t2.c = +t1.b AND t3.e=t2.d
   114    112   } {
   115         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:} 
   116         -  0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)} 
   117         -  0 2 2 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)}
          113  +  QUERY PLAN
          114  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
          115  +  |--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
          116  +  `--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)
   118    117   }
   119    118   
   120    119   do_eqp_test 1.6 {
   121    120     SELECT * FROM t1, t2, t3 WHERE t2.c = +t1.b AND t3.e = t2.d
   122    121   } {
   123         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:} 
   124         -  0 1 1 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)} 
   125         -  0 2 2 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)}
          122  +  QUERY PLAN
          123  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
          124  +  |--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
          125  +  `--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)
   126    126   }
   127    127   
   128    128   do_execsql_test 1.7.1 {
   129    129     CREATE TABLE x1(a, b);
   130    130   }
   131    131   do_eqp_test 1.7.2 {
   132    132     SELECT * FROM x1 CROSS JOIN t1, t2, t3 
   133    133       WHERE t1.a = t2.c AND t1.b = t3.e
   134    134   } {
   135         -  0 0 0 {SCAN TABLE x1} 
   136         -  0 1 1 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:}
   137         -  0 2 2 {SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)} 
   138         -  0 3 3 {SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)}
          135  +  QUERY PLAN
          136  +  |--SCAN TABLE x1
          137  +  |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:
          138  +  |--SCAN TABLE t2 VIRTUAL TABLE INDEX 0:indexed(c=?)
          139  +  `--SCAN TABLE t3 VIRTUAL TABLE INDEX 0:indexed(e=?)
   139    140   }
   140    141   
   141    142   finish_test

Changes to test/bestindex3.test.

    75     75   
    76     76   do_execsql_test 1.0 {
    77     77     CREATE VIRTUAL TABLE t1 USING tcl("vtab_cmd 0");
    78     78   }
    79     79   
    80     80   do_eqp_test 1.1 {
    81     81     SELECT * FROM t1 WHERE a LIKE 'abc';
    82         -} {
    83         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?}
    84         -}
           82  +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?}
    85     83   
    86     84   do_eqp_test 1.2 {
    87     85     SELECT * FROM t1 WHERE a = 'abc';
    88         -} {
    89         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}
    90         -}
           86  +} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}
    91     87   
    92     88   do_eqp_test 1.3 {
    93     89     SELECT * FROM t1 WHERE a = 'abc' OR b = 'def';
    94     90   } {
    95         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}
    96         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?}
           91  +  QUERY PLAN
           92  +  `--MULTI-INDEX OR
           93  +     |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?
           94  +     `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
    97     95   }
    98     96   
    99     97   do_eqp_test 1.4 {
   100     98     SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def';
   101     99   } {
   102         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?}
   103         -  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?}
          100  +  QUERY PLAN
          101  +  `--MULTI-INDEX OR
          102  +     |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?
          103  +     `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
   104    104   }
   105    105   
   106    106   do_execsql_test 1.5 {
   107    107     CREATE TABLE ttt(a, b, c);
   108    108   
   109    109     INSERT INTO ttt VALUES(1, 'two',   'three');
   110    110     INSERT INTO ttt VALUES(2, 'one',   'two');
................................................................................
   143    143       CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT);
   144    144       CREATE INDEX t2x ON t2(x COLLATE nocase);
   145    145       CREATE INDEX t2y ON t2(y);
   146    146     }
   147    147   
   148    148     do_eqp_test 2.2 {
   149    149       SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def'
   150         -  } {
   151         -    0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)}
   152         -    0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)}
   153         -  }
          150  +  } [string map {"\n  " \n} {
          151  +    QUERY PLAN
          152  +    `--MULTI-INDEX OR
          153  +       |--SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)
          154  +       `--SEARCH TABLE t2 USING INDEX t2y (y=?)
          155  +  }]
   154    156   }
   155    157   
   156    158   #-------------------------------------------------------------------------
   157    159   # Test that any PRIMARY KEY within a sqlite3_decl_vtab() CREATE TABLE 
   158    160   # statement is currently ignored.
   159    161   #
   160    162   proc vvv_command {method args} {

Changes to test/bigmmap.test.

    88     88         ORDER BY b, c;
    89     89       " {}
    90     90       
    91     91       do_eqp_test 2.$i.$t.3 "
    92     92         SELECT * FROM t$t AS o WHERE 
    93     93           NOT EXISTS( SELECT * FROM t$t AS i WHERE a=o.a AND +b=o.b AND +c=o.c )
    94     94         ORDER BY b, c;
    95         -    " "
    96         -      0 0 0 {SCAN TABLE t$t AS o USING COVERING INDEX sqlite_autoindex_t${t}_1}
    97         -      0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 1}
    98         -      1 0 0 {SEARCH TABLE t$t AS i USING INTEGER PRIMARY KEY (rowid=?)}
    99         -    "
           95  +    " [string map {"\n    " "\n"} "
           96  +      QUERY PLAN
           97  +      |--SCAN TABLE t$t AS o USING COVERING INDEX sqlite_autoindex_t${t}_1
           98  +      `--CORRELATED SCALAR SUBQUERY
           99  +         `--SEARCH TABLE t$t AS i USING INTEGER PRIMARY KEY (rowid=?)
          100  +    "]
   100    101     }
   101    102   }
   102    103   
   103    104   finish_test
   104         -

Changes to test/closure01.test.

   268    268      WHERE root=1
   269    269        AND depth=3
   270    270        AND tablename='t1'
   271    271        AND idcolumn='x'
   272    272        AND parentcolumn='y'
   273    273     ORDER BY id;
   274    274   } {8 9 10 11 12 13 14 15}
          275  +
          276  +#-------------------------------------------------------------------------
          277  +# At one point the following join query was causing a malfunction in
          278  +# xBestIndex.
          279  +#
          280  +do_execsql_test 6.0 {
          281  +  CREATE TABLE t4 (
          282  +    id INTEGER PRIMARY KEY, 
          283  +    name TEXT NOT NULL,
          284  +    parent_id INTEGER
          285  +  );
          286  +  CREATE VIRTUAL TABLE vt4 USING transitive_closure (
          287  +    idcolumn=id, parentcolumn=parent_id, tablename=t4
          288  +  );
          289  +}
          290  +
          291  +do_execsql_test 6.1 {
          292  +  SELECT * FROM t4, vt4 WHERE t4.id = vt4.root AND vt4.id=4 AND vt4.depth=2;
          293  +}
   275    294   
   276    295   finish_test

Changes to test/cost.test.

    20     20     CREATE TABLE t4(c, d, e);
    21     21     CREATE UNIQUE INDEX i3 ON t3(b);
    22     22     CREATE UNIQUE INDEX i4 ON t4(c, d);
    23     23   }
    24     24   do_eqp_test 1.2 {
    25     25     SELECT e FROM t3, t4 WHERE b=c ORDER BY b, d;
    26     26   } {
    27         -  0 0 0 {SCAN TABLE t3 USING COVERING INDEX i3} 
    28         -  0 1 1 {SEARCH TABLE t4 USING INDEX i4 (c=?)}
           27  +  QUERY PLAN
           28  +  |--SCAN TABLE t3 USING COVERING INDEX i3
           29  +  `--SEARCH TABLE t4 USING INDEX i4 (c=?)
    29     30   }
    30     31   
    31     32   
    32     33   do_execsql_test 2.1 {
    33     34     CREATE TABLE t1(a, b);
    34     35     CREATE INDEX i1 ON t1(a);
    35     36   }
    36     37   
    37     38   # It is better to use an index for ORDER BY than sort externally, even 
    38     39   # if the index is a non-covering index.
    39     40   do_eqp_test 2.2 {
    40     41     SELECT * FROM t1 ORDER BY a;
    41         -} {
    42         -  0 0 0 {SCAN TABLE t1 USING INDEX i1}
    43         -}
           42  +} {SCAN TABLE t1 USING INDEX i1}
    44     43   
    45     44   do_execsql_test 3.1 {
    46     45     CREATE TABLE t5(a INTEGER PRIMARY KEY,b,c,d,e,f,g);
    47     46     CREATE INDEX t5b ON t5(b);
    48     47     CREATE INDEX t5c ON t5(c);
    49     48     CREATE INDEX t5d ON t5(d);
    50     49     CREATE INDEX t5e ON t5(e);
................................................................................
    53     52   }
    54     53   
    55     54   do_eqp_test 3.2 {
    56     55     SELECT a FROM t5 
    57     56     WHERE b IS NULL OR c IS NULL OR d IS NULL 
    58     57     ORDER BY a;
    59     58   } {
    60         -  0 0 0 {SEARCH TABLE t5 USING INDEX t5b (b=?)} 
    61         -  0 0 0 {SEARCH TABLE t5 USING INDEX t5c (c=?)} 
    62         -  0 0 0 {SEARCH TABLE t5 USING INDEX t5d (d=?)} 
    63         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
           59  +  QUERY PLAN
           60  +  |--MULTI-INDEX OR
           61  +  |  |--SEARCH TABLE t5 USING INDEX t5b (b=?)
           62  +  |  |--SEARCH TABLE t5 USING INDEX t5c (c=?)
           63  +  |  `--SEARCH TABLE t5 USING INDEX t5d (d=?)
           64  +  `--USE TEMP B-TREE FOR ORDER BY
    64     65   }
    65     66   
    66     67   #-------------------------------------------------------------------------
    67     68   # If there is no likelihood() or stat3 data, SQLite assumes that a closed
    68     69   # range scan (e.g. one constrained by "col BETWEEN ? AND ?" constraint)
    69     70   # visits 1/64 of the rows in a table.
    70     71   #
................................................................................
    75     76   do_execsql_test 4.1 {
    76     77     CREATE TABLE t1(a, b);
    77     78     CREATE INDEX i1 ON t1(a);
    78     79     CREATE INDEX i2 ON t1(b);
    79     80   }
    80     81   do_eqp_test 4.2 {
    81     82     SELECT * FROM t1 WHERE likelihood(a=?, 0.014) AND b BETWEEN ? AND ?;
    82         -} {
    83         -  0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
    84         -}
           83  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
           84  +
    85     85   do_eqp_test 4.3 {
    86     86     SELECT * FROM t1 WHERE likelihood(a=?, 0.016) AND b BETWEEN ? AND ?;
    87         -} {
    88         -  0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b>? AND b<?)}
    89         -}
           87  +} {SEARCH TABLE t1 USING INDEX i2 (b>? AND b<?)}
    90     88   
    91     89   
    92     90   #-------------------------------------------------------------------------
    93     91   #
    94     92   reset_db
    95     93   do_execsql_test 5.1 {
    96     94     CREATE TABLE t2(x, y);
    97     95     CREATE INDEX t2i1 ON t2(x);
    98     96   }
    99     97   
   100     98   do_eqp_test 5.2 {
   101     99     SELECT * FROM t2 ORDER BY x, y;
   102    100   } {
   103         -  0 0 0 {SCAN TABLE t2 USING INDEX t2i1} 
   104         -  0 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
          101  +  QUERY PLAN
          102  +  |--SCAN TABLE t2 USING INDEX t2i1
          103  +  `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
   105    104   }
   106    105   
   107    106   do_eqp_test 5.3 {
   108    107     SELECT * FROM t2 WHERE x BETWEEN ? AND ? ORDER BY rowid;
   109    108   } {
   110         -  0 0 0 {SEARCH TABLE t2 USING INDEX t2i1 (x>? AND x<?)} 
   111         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          109  +  QUERY PLAN
          110  +  |--SEARCH TABLE t2 USING INDEX t2i1 (x>? AND x<?)
          111  +  `--USE TEMP B-TREE FOR ORDER BY
   112    112   }
   113    113   
   114    114   # where7.test, where8.test:
   115    115   #
   116    116   do_execsql_test 6.1 {
   117    117     CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c);
   118    118     CREATE INDEX t3i1 ON t3(b);
   119    119     CREATE INDEX t3i2 ON t3(c);
   120    120   }
   121    121   
   122    122   do_eqp_test 6.2 {
   123    123     SELECT a FROM t3 WHERE (b BETWEEN 2 AND 4) OR c=100 ORDER BY a
   124    124   } {
   125         -  0 0 0 {SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)} 
   126         -  0 0 0 {SEARCH TABLE t3 USING INDEX t3i2 (c=?)}
   127         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          125  +  QUERY PLAN
          126  +  |--MULTI-INDEX OR
          127  +  |  |--SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)
          128  +  |  `--SEARCH TABLE t3 USING INDEX t3i2 (c=?)
          129  +  `--USE TEMP B-TREE FOR ORDER BY
   128    130   }
   129    131   
   130    132   #-------------------------------------------------------------------------
   131    133   #
   132    134   reset_db
   133    135   do_execsql_test 7.1 {
   134    136     CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d,e,f,g);
................................................................................
   141    143   }
   142    144   
   143    145   do_eqp_test 7.2 {
   144    146     SELECT a FROM t1
   145    147        WHERE (b>=950 AND b<=1010) OR (b IS NULL AND c NOT NULL)
   146    148     ORDER BY a
   147    149   } {
   148         -  0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)} 
   149         -  0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)} 
   150         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          150  +  QUERY PLAN
          151  +  |--MULTI-INDEX OR
          152  +  |  |--SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)
          153  +  |  `--SEARCH TABLE t1 USING INDEX t1b (b=?)
          154  +  `--USE TEMP B-TREE FOR ORDER BY
   151    155   }
   152    156   
   153    157   do_eqp_test 7.3 {
   154    158     SELECT rowid FROM t1
   155    159     WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
   156    160           OR (b NOT NULL AND c IS NULL AND d NOT NULL)
   157    161           OR (b NOT NULL AND c NOT NULL AND d IS NULL)
   158         -} {
   159         -  0 0 0 {SCAN TABLE t1}
   160         -}
          162  +} {SCAN TABLE t1}
   161    163   
   162    164   do_eqp_test 7.4 {
   163    165     SELECT rowid FROM t1 WHERE (+b IS NULL AND c NOT NULL) OR c IS NULL
   164         -} {
   165         -  0 0 0 {SCAN TABLE t1}
   166         -}
          166  +} {SCAN TABLE t1}
   167    167   
   168    168   #-------------------------------------------------------------------------
   169    169   #
   170    170   reset_db
   171    171   do_execsql_test 8.1 {
   172    172     CREATE TABLE composer(
   173    173       cid INTEGER PRIMARY KEY,
................................................................................
   190    190   do_eqp_test 8.2 {
   191    191     SELECT DISTINCT aname
   192    192       FROM album, composer, track
   193    193      WHERE cname LIKE '%bach%'
   194    194        AND unlikely(composer.cid=track.cid)
   195    195        AND unlikely(album.aid=track.aid);
   196    196   } {
   197         -  0 0 2 {SCAN TABLE track} 
   198         -  0 1 0 {SEARCH TABLE album USING INTEGER PRIMARY KEY (rowid=?)}
   199         -  0 2 1 {SEARCH TABLE composer USING INTEGER PRIMARY KEY (rowid=?)}
   200         -  0 0 0 {USE TEMP B-TREE FOR DISTINCT}
          197  +  QUERY PLAN
          198  +  |--SCAN TABLE track
          199  +  |--SEARCH TABLE album USING INTEGER PRIMARY KEY (rowid=?)
          200  +  |--SEARCH TABLE composer USING INTEGER PRIMARY KEY (rowid=?)
          201  +  `--USE TEMP B-TREE FOR DISTINCT
   201    202   }
   202    203   
   203    204   #-------------------------------------------------------------------------
   204    205   #
   205    206   do_execsql_test 9.1 {
   206    207     CREATE TABLE t1(
   207    208       a,b,c,d,e, f,g,h,i,j,
................................................................................
   259    260         execsql { INSERT INTO t6 VALUES($i%4, 'xyz', $i%8) }
   260    261       }
   261    262       execsql ANALYZE
   262    263     } {}
   263    264   
   264    265     do_eqp_test 10.3 {
   265    266       SELECT rowid FROM t6 WHERE a=0 AND c=0
   266         -  } {
   267         -    0 0 0 {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
   268         -  }
          267  +  } {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
   269    268   
   270    269     do_eqp_test 10.4 {
   271    270       SELECT rowid FROM t6 WHERE a=0 AND b='xyz' AND c=0
   272         -  } {
   273         -    0 0 0 {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
   274         -  }
          271  +  } {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
   275    272   
   276    273     do_eqp_test 10.5 {
   277    274       SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND c=0
   278         -  } {
   279         -    0 0 0 {SEARCH TABLE t6 USING INDEX t6i1 (a=?)}
   280         -  }
          275  +  } {SEARCH TABLE t6 USING INDEX t6i1 (a=?)}
   281    276   
   282    277     do_eqp_test 10.6 {
   283    278       SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND b='xyz' AND c=0
   284         -  } {
   285         -    0 0 0 {SEARCH TABLE t6 USING INDEX t6i1 (a=? AND b=?)}
   286         -  }
          279  +  } {SEARCH TABLE t6 USING INDEX t6i1 (a=? AND b=?)}
   287    280   }
   288    281   
   289    282   finish_test

Changes to test/coveridxscan.test.

   105    105   
   106    106     CREATE TABLE t2(i INTEGER PRIMARY KEY, $cols);
   107    107     CREATE INDEX i2 ON t2($cols);
   108    108   "
   109    109   
   110    110   do_eqp_test 5.1.1 {
   111    111     SELECT * FROM t1 ORDER BY c1, c2;
   112         -} {
   113         -  0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
   114         -}
          112  +} {SCAN TABLE t1 USING COVERING INDEX i1}
   115    113   
   116    114   do_eqp_test 5.1.2 {
   117    115     SELECT * FROM t2 ORDER BY c1, c2;
   118         -} {
   119         -  0 0 0 {SCAN TABLE t2 USING COVERING INDEX i2}
   120         -}
   121         -
          116  +} {SCAN TABLE t2 USING COVERING INDEX i2}
   122    117   
   123    118   
   124    119   finish_test

Changes to test/e_createtable.test.

   652    652     1    "CREATE TABLE x1 AS SELECT * FROM t1"                     {a b c}
   653    653     2    "CREATE TABLE x1 AS SELECT c, b, a FROM t1"               {c b a}
   654    654     3    "CREATE TABLE x1 AS SELECT * FROM t1, t2"                 {a b c d e f}
   655    655     4    "CREATE TABLE x1 AS SELECT count(*) FROM t1"              {count(*)}
   656    656     5    "CREATE TABLE x1 AS SELECT count(a) AS a, max(b) FROM t1" {a max(b)}
   657    657   }
   658    658   
   659         -# EVIDENCE-OF: R-37111-22855 The declared type of each column is
          659  +# EVIDENCE-OF: R-55407-45319 The declared type of each column is
   660    660   # determined by the expression affinity of the corresponding expression
   661    661   # in the result set of the SELECT statement, as follows: Expression
   662    662   # Affinity Column Declared Type TEXT "TEXT" NUMERIC "NUM" INTEGER "INT"
   663         -# REAL "REAL" NONE "" (empty string)
          663  +# REAL "REAL" BLOB (a.k.a "NONE") "" (empty string)
   664    664   #
   665    665   do_createtable_tests 2.2 -tclquery {
   666    666     table_column_decltypes x1
   667    667   } -repair {
   668    668     catchsql { DROP TABLE x1 }
   669    669   } {
   670    670     1    "CREATE TABLE x1 AS SELECT a FROM t1"     {""}
................................................................................
  1381   1381   #
  1382   1382   do_execsql_test 4.10.0 {
  1383   1383     CREATE TABLE t1(a, b PRIMARY KEY);
  1384   1384     CREATE TABLE t2(a, b, c, UNIQUE(b, c));
  1385   1385   }
  1386   1386   do_createtable_tests 4.10 {
  1387   1387     1    "EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 5" 
  1388         -       {0 0 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (b=?)}}
         1388  +       {/*SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (b=?)*/}
  1389   1389   
  1390   1390     2    "EXPLAIN QUERY PLAN SELECT * FROM t2 ORDER BY b, c"
  1391         -       {0 0 0 {SCAN TABLE t2 USING INDEX sqlite_autoindex_t2_1}}
         1391  +       {/*SCAN TABLE t2 USING INDEX sqlite_autoindex_t2_1*/}
  1392   1392   
  1393   1393     3    "EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE b=10 AND c>10"
  1394         -       {0 0 0 {SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (b=? AND c>?)}}
         1394  +       {/*SEARCH TABLE t2 USING INDEX sqlite_autoindex_t2_1 (b=? AND c>?)*/}
  1395   1395   }
  1396   1396   
  1397   1397   # EVIDENCE-OF: R-45493-35653 A CHECK constraint may be attached to a
  1398   1398   # column definition or specified as a table constraint. In practice it
  1399   1399   # makes no difference.
  1400   1400   #
  1401   1401   #   All the tests that deal with CHECK constraints below (4.11.* and 

Changes to test/eqp.test.

    39     39     CREATE TABLE t2(a INT, b INT, ex TEXT);
    40     40     CREATE TABLE t3(a INT, b INT, ex TEXT);
    41     41   }
    42     42   
    43     43   do_eqp_test 1.2 {
    44     44     SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2;
    45     45   } {
    46         -  0 0 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)} 
    47         -  0 0 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)} 
    48         -  0 1 0 {SCAN TABLE t2}
           46  +  QUERY PLAN
           47  +  |--MULTI-INDEX OR
           48  +  |  |--SEARCH TABLE t1 USING INDEX i1 (a=?)
           49  +  |  `--SEARCH TABLE t1 USING INDEX i2 (b=?)
           50  +  `--SCAN TABLE t2
    49     51   }
    50     52   do_eqp_test 1.3 {
    51     53     SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2;
    52     54   } {
    53         -  0 0 0 {SCAN TABLE t2}
    54         -  0 1 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)} 
    55         -  0 1 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)} 
           55  +  QUERY PLAN
           56  +  |--SCAN TABLE t2
           57  +  `--MULTI-INDEX OR
           58  +     |--SEARCH TABLE t1 USING INDEX i1 (a=?)
           59  +     `--SEARCH TABLE t1 USING INDEX i2 (b=?)
    56     60   }
    57     61   do_eqp_test 1.3 {
    58     62     SELECT a FROM t1 ORDER BY a
    59     63   } {
    60         -  0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
           64  +  QUERY PLAN
           65  +  `--SCAN TABLE t1 USING COVERING INDEX i1
    61     66   }
    62     67   do_eqp_test 1.4 {
    63     68     SELECT a FROM t1 ORDER BY +a
    64     69   } {
    65         -  0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
    66         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
           70  +  QUERY PLAN
           71  +  |--SCAN TABLE t1 USING COVERING INDEX i1
           72  +  `--USE TEMP B-TREE FOR ORDER BY
    67     73   }
    68     74   do_eqp_test 1.5 {
    69     75     SELECT a FROM t1 WHERE a=4
    70     76   } {
    71         -  0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
           77  +  QUERY PLAN
           78  +  `--SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)
    72     79   }
    73     80   do_eqp_test 1.6 {
    74     81     SELECT DISTINCT count(*) FROM t3 GROUP BY a;
    75     82   } {
    76         -  0 0 0 {SCAN TABLE t3}
    77         -  0 0 0 {USE TEMP B-TREE FOR GROUP BY}
    78         -  0 0 0 {USE TEMP B-TREE FOR DISTINCT}
           83  +  QUERY PLAN
           84  +  |--SCAN TABLE t3
           85  +  |--USE TEMP B-TREE FOR GROUP BY
           86  +  `--USE TEMP B-TREE FOR DISTINCT
    79     87   }
    80     88   
    81     89   do_eqp_test 1.7 {
    82     90     SELECT * FROM t3 JOIN (SELECT 1)
    83     91   } {
    84         -  0 0 1 {SCAN SUBQUERY 1}
    85         -  0 1 0 {SCAN TABLE t3}
           92  +  QUERY PLAN
           93  +  |--MATERIALIZE xxxxxx
           94  +  |  `--SCAN CONSTANT ROW
           95  +  |--SCAN SUBQUERY xxxxxx
           96  +  `--SCAN TABLE t3
    86     97   }
    87     98   do_eqp_test 1.8 {
    88     99     SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2)
    89    100   } {
    90         -  1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
    91         -  0 0 1 {SCAN SUBQUERY 1}
    92         -  0 1 0 {SCAN TABLE t3}
          101  +  QUERY PLAN
          102  +  |--MATERIALIZE xxxxxx
          103  +  |  `--COMPOUND QUERY
          104  +  |     |--LEFT-MOST SUBQUERY
          105  +  |     |  `--SCAN CONSTANT ROW
          106  +  |     `--UNION USING TEMP B-TREE
          107  +  |        `--SCAN CONSTANT ROW
          108  +  |--SCAN SUBQUERY xxxxxx
          109  +  `--SCAN TABLE t3
    93    110   }
    94    111   do_eqp_test 1.9 {
    95    112     SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17)
    96    113   } {
    97         -  3 0 0 {SCAN TABLE t3}
    98         -  1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)}
    99         -  0 0 1 {SCAN SUBQUERY 1}
   100         -  0 1 0 {SCAN TABLE t3}
          114  +  QUERY PLAN
          115  +  |--MATERIALIZE xxxxxx
          116  +  |  `--COMPOUND QUERY
          117  +  |     |--LEFT-MOST SUBQUERY
          118  +  |     |  `--SCAN CONSTANT ROW
          119  +  |     `--EXCEPT USING TEMP B-TREE
          120  +  |        `--SCAN TABLE t3
          121  +  |--SCAN SUBQUERY xxxxxx
          122  +  `--SCAN TABLE t3
   101    123   }
   102    124   do_eqp_test 1.10 {
   103    125     SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17)
   104    126   } {
   105         -  3 0 0 {SCAN TABLE t3}
   106         -  1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (INTERSECT)}
   107         -  0 0 1 {SCAN SUBQUERY 1}
   108         -  0 1 0 {SCAN TABLE t3}
          127  +  QUERY PLAN
          128  +  |--MATERIALIZE xxxxxx
          129  +  |  `--COMPOUND QUERY
          130  +  |     |--LEFT-MOST SUBQUERY
          131  +  |     |  `--SCAN CONSTANT ROW
          132  +  |     `--INTERSECT USING TEMP B-TREE
          133  +  |        `--SCAN TABLE t3
          134  +  |--SCAN SUBQUERY xxxxxx
          135  +  `--SCAN TABLE t3
   109    136   }
   110    137   
   111    138   do_eqp_test 1.11 {
   112    139     SELECT * FROM t3 JOIN (SELECT 1 UNION ALL SELECT a FROM t3 LIMIT 17)
   113    140   } {
   114         -  3 0 0 {SCAN TABLE t3}
   115         -  1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)}
   116         -  0 0 1 {SCAN SUBQUERY 1}
   117         -  0 1 0 {SCAN TABLE t3}
          141  +  QUERY PLAN
          142  +  |--MATERIALIZE xxxxxx
          143  +  |  `--COMPOUND QUERY
          144  +  |     |--LEFT-MOST SUBQUERY
          145  +  |     |  `--SCAN CONSTANT ROW
          146  +  |     `--UNION ALL
          147  +  |        `--SCAN TABLE t3
          148  +  |--SCAN SUBQUERY xxxxxx
          149  +  `--SCAN TABLE t3
   118    150   }
   119    151   
   120    152   #-------------------------------------------------------------------------
   121    153   # Test cases eqp-2.* - tests for single select statements.
   122    154   #
   123    155   drop_all_tables
   124    156   do_execsql_test 2.1 {
................................................................................
   125    157     CREATE TABLE t1(x INT, y INT, ex TEXT);
   126    158   
   127    159     CREATE TABLE t2(x INT, y INT, ex TEXT);
   128    160     CREATE INDEX t2i1 ON t2(x);
   129    161   }
   130    162   
   131    163   det 2.2.1 "SELECT DISTINCT min(x), max(x) FROM t1 GROUP BY x ORDER BY 1" {
   132         -  0 0 0 {SCAN TABLE t1}
   133         -  0 0 0 {USE TEMP B-TREE FOR GROUP BY}
   134         -  0 0 0 {USE TEMP B-TREE FOR DISTINCT}
   135         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          164  +  QUERY PLAN
          165  +  |--SCAN TABLE t1
          166  +  |--USE TEMP B-TREE FOR GROUP BY
          167  +  |--USE TEMP B-TREE FOR DISTINCT
          168  +  `--USE TEMP B-TREE FOR ORDER BY
   136    169   }
   137    170   det 2.2.2 "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORDER BY 1" {
   138         -  0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
   139         -  0 0 0 {USE TEMP B-TREE FOR DISTINCT}
   140         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          171  +  QUERY PLAN
          172  +  |--SCAN TABLE t2 USING COVERING INDEX t2i1
          173  +  |--USE TEMP B-TREE FOR DISTINCT
          174  +  `--USE TEMP B-TREE FOR ORDER BY
   141    175   }
   142    176   det 2.2.3 "SELECT DISTINCT * FROM t1" {
   143         -  0 0 0 {SCAN TABLE t1}
   144         -  0 0 0 {USE TEMP B-TREE FOR DISTINCT}
          177  +  QUERY PLAN
          178  +  |--SCAN TABLE t1
          179  +  `--USE TEMP B-TREE FOR DISTINCT
   145    180   }
   146    181   det 2.2.4 "SELECT DISTINCT * FROM t1, t2" {
   147         -  0 0 0 {SCAN TABLE t1}
   148         -  0 1 1 {SCAN TABLE t2}
   149         -  0 0 0 {USE TEMP B-TREE FOR DISTINCT}
          182  +  QUERY PLAN
          183  +  |--SCAN TABLE t1
          184  +  |--SCAN TABLE t2
          185  +  `--USE TEMP B-TREE FOR DISTINCT
   150    186   }
   151    187   det 2.2.5 "SELECT DISTINCT * FROM t1, t2 ORDER BY t1.x" {
   152         -  0 0 0 {SCAN TABLE t1}
   153         -  0 1 1 {SCAN TABLE t2}
   154         -  0 0 0 {USE TEMP B-TREE FOR DISTINCT}
   155         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          188  +  QUERY PLAN
          189  +  |--SCAN TABLE t1
          190  +  |--SCAN TABLE t2
          191  +  |--USE TEMP B-TREE FOR DISTINCT
          192  +  `--USE TEMP B-TREE FOR ORDER BY
   156    193   }
   157    194   det 2.2.6 "SELECT DISTINCT t2.x FROM t1, t2 ORDER BY t2.x" {
   158         -  0 0 1 {SCAN TABLE t2 USING COVERING INDEX t2i1}
   159         -  0 1 0 {SCAN TABLE t1}
          195  +  QUERY PLAN
          196  +  |--SCAN TABLE t2 USING COVERING INDEX t2i1
          197  +  `--SCAN TABLE t1
   160    198   }
   161    199   
   162    200   det 2.3.1 "SELECT max(x) FROM t2" {
   163         -  0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1}
          201  +  QUERY PLAN
          202  +  `--SEARCH TABLE t2 USING COVERING INDEX t2i1
   164    203   }
   165    204   det 2.3.2 "SELECT min(x) FROM t2" {
   166         -  0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1}
          205  +  QUERY PLAN
          206  +  `--SEARCH TABLE t2 USING COVERING INDEX t2i1
   167    207   }
   168    208   det 2.3.3 "SELECT min(x), max(x) FROM t2" {
   169         -  0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
          209  +  QUERY PLAN
          210  +  `--SCAN TABLE t2 USING COVERING INDEX t2i1
   170    211   }
   171    212   
   172    213   det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" {
   173         -  0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)}
          214  +  QUERY PLAN
          215  +  `--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
   174    216   }
   175    217   
   176    218   
   177    219   
   178    220   #-------------------------------------------------------------------------
   179    221   # Test cases eqp-3.* - tests for select statements that use sub-selects.
   180    222   #
   181    223   do_eqp_test 3.1.1 {
   182    224     SELECT (SELECT x FROM t1 AS sub) FROM t1;
   183    225   } {
   184         -  0 0 0 {SCAN TABLE t1}
   185         -  0 0 0 {EXECUTE SCALAR SUBQUERY 1}
   186         -  1 0 0 {SCAN TABLE t1 AS sub}
          226  +  QUERY PLAN
          227  +  |--SCAN TABLE t1
          228  +  `--SCALAR SUBQUERY
          229  +     `--SCAN TABLE t1 AS sub
   187    230   }
   188    231   do_eqp_test 3.1.2 {
   189    232     SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub);
   190    233   } {
   191         -  0 0 0 {SCAN TABLE t1}
   192         -  0 0 0 {EXECUTE SCALAR SUBQUERY 1}
   193         -  1 0 0 {SCAN TABLE t1 AS sub}
          234  +  QUERY PLAN
          235  +  |--SCAN TABLE t1
          236  +  `--SCALAR SUBQUERY
          237  +     `--SCAN TABLE t1 AS sub
   194    238   }
   195    239   do_eqp_test 3.1.3 {
   196    240     SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y);
   197    241   } {
   198         -  0 0 0 {SCAN TABLE t1}
   199         -  0 0 0 {EXECUTE SCALAR SUBQUERY 1}
   200         -  1 0 0 {SCAN TABLE t1 AS sub}
   201         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
          242  +  QUERY PLAN
          243  +  |--SCAN TABLE t1
          244  +  `--SCALAR SUBQUERY
          245  +     |--SCAN TABLE t1 AS sub
          246  +     `--USE TEMP B-TREE FOR ORDER BY
   202    247   }
   203    248   do_eqp_test 3.1.4 {
   204    249     SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x);
   205    250   } {
   206         -  0 0 0 {SCAN TABLE t1}
   207         -  0 0 0 {EXECUTE SCALAR SUBQUERY 1}
   208         -  1 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
          251  +  QUERY PLAN
          252  +  |--SCAN TABLE t1
          253  +  `--SCALAR SUBQUERY
          254  +     `--SCAN TABLE t2 USING COVERING INDEX t2i1
   209    255   }
   210    256   
   211    257   det 3.2.1 {
   212    258     SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5
   213    259   } {
   214         -  1 0 0 {SCAN TABLE t1} 
   215         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY} 
   216         -  0 0 0 {SCAN SUBQUERY 1} 
   217         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          260  +  QUERY PLAN
          261  +  |--CO-ROUTINE xxxxxx
          262  +  |  |--SCAN TABLE t1
          263  +  |  `--USE TEMP B-TREE FOR ORDER BY
          264  +  |--SCAN SUBQUERY xxxxxx
          265  +  `--USE TEMP B-TREE FOR ORDER BY
   218    266   }
   219    267   det 3.2.2 {
   220    268     SELECT * FROM 
   221    269       (SELECT * FROM t1 ORDER BY x LIMIT 10) AS x1,
   222    270       (SELECT * FROM t2 ORDER BY x LIMIT 10) AS x2
   223    271     ORDER BY x2.y LIMIT 5
   224    272   } {
   225         -  1 0 0 {SCAN TABLE t1} 
   226         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY} 
   227         -  2 0 0 {SCAN TABLE t2 USING INDEX t2i1} 
   228         -  0 0 0 {SCAN SUBQUERY 1 AS x1} 
   229         -  0 1 1 {SCAN SUBQUERY 2 AS x2} 
   230         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          273  +  QUERY PLAN
          274  +  |--MATERIALIZE xxxxxx
          275  +  |  |--SCAN TABLE t1
          276  +  |  `--USE TEMP B-TREE FOR ORDER BY
          277  +  |--MATERIALIZE xxxxxx
          278  +  |  `--SCAN TABLE t2 USING INDEX t2i1
          279  +  |--SCAN SUBQUERY xxxxxx AS x1
          280  +  |--SCAN SUBQUERY xxxxxx AS x2
          281  +  `--USE TEMP B-TREE FOR ORDER BY
   231    282   }
   232    283   
   233    284   det 3.3.1 {
   234    285     SELECT * FROM t1 WHERE y IN (SELECT y FROM t2)
   235    286   } {
   236         -  0 0 0 {SCAN TABLE t1} 
   237         -  0 0 0 {EXECUTE LIST SUBQUERY 1} 
   238         -  1 0 0 {SCAN TABLE t2}
          287  +  QUERY PLAN
          288  +  |--SCAN TABLE t1
          289  +  `--LIST SUBQUERY
          290  +     `--SCAN TABLE t2
   239    291   }
   240    292   det 3.3.2 {
   241    293     SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x)
   242    294   } {
   243         -  0 0 0 {SCAN TABLE t1} 
   244         -  0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 
   245         -  1 0 0 {SCAN TABLE t2}
          295  +  QUERY PLAN
          296  +  |--SCAN TABLE t1
          297  +  `--CORRELATED LIST SUBQUERY
          298  +     `--SCAN TABLE t2
   246    299   }
   247    300   det 3.3.3 {
   248    301     SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x)
   249    302   } {
   250         -  0 0 0 {SCAN TABLE t1} 
   251         -  0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 1} 
   252         -  1 0 0 {SCAN TABLE t2}
          303  +  QUERY PLAN
          304  +  |--SCAN TABLE t1
          305  +  `--CORRELATED SCALAR SUBQUERY
          306  +     `--SCAN TABLE t2
   253    307   }
   254    308   
   255    309   #-------------------------------------------------------------------------
   256    310   # Test cases eqp-4.* - tests for composite select statements.
   257    311   #
   258    312   do_eqp_test 4.1.1 {
   259    313     SELECT * FROM t1 UNION ALL SELECT * FROM t2
   260    314   } {
   261         -  1 0 0 {SCAN TABLE t1} 
   262         -  2 0 0 {SCAN TABLE t2} 
   263         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} 
          315  +  QUERY PLAN
          316  +  `--COMPOUND QUERY
          317  +     |--LEFT-MOST SUBQUERY
          318  +     |  `--SCAN TABLE t1
          319  +     `--UNION ALL
          320  +        `--SCAN TABLE t2
   264    321   }
   265    322   do_eqp_test 4.1.2 {
   266    323     SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 2
   267    324   } {
   268         -  1 0 0 {SCAN TABLE t1} 
   269         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   270         -  2 0 0 {SCAN TABLE t2} 
   271         -  2 0 0 {USE TEMP B-TREE FOR ORDER BY}
   272         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} 
          325  +  QUERY PLAN
          326  +  `--MERGE (UNION ALL)
          327  +     |--LEFT
          328  +     |  |--SCAN TABLE t1
          329  +     |  `--USE TEMP B-TREE FOR ORDER BY
          330  +     `--RIGHT
          331  +        |--SCAN TABLE t2
          332  +        `--USE TEMP B-TREE FOR ORDER BY
   273    333   }
   274    334   do_eqp_test 4.1.3 {
   275    335     SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 2
   276    336   } {
   277         -  1 0 0 {SCAN TABLE t1} 
   278         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   279         -  2 0 0 {SCAN TABLE t2} 
   280         -  2 0 0 {USE TEMP B-TREE FOR ORDER BY}
   281         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)} 
          337  +  QUERY PLAN
          338  +  `--MERGE (UNION)
          339  +     |--LEFT
          340  +     |  |--SCAN TABLE t1
          341  +     |  `--USE TEMP B-TREE FOR ORDER BY
          342  +     `--RIGHT
          343  +        |--SCAN TABLE t2
          344  +        `--USE TEMP B-TREE FOR ORDER BY
   282    345   }
   283    346   do_eqp_test 4.1.4 {
   284    347     SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 2
   285    348   } {
   286         -  1 0 0 {SCAN TABLE t1} 
   287         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   288         -  2 0 0 {SCAN TABLE t2} 
   289         -  2 0 0 {USE TEMP B-TREE FOR ORDER BY}
   290         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)} 
          349  +  QUERY PLAN
          350  +  `--MERGE (INTERSECT)
          351  +     |--LEFT
          352  +     |  |--SCAN TABLE t1
          353  +     |  `--USE TEMP B-TREE FOR ORDER BY
          354  +     `--RIGHT
          355  +        |--SCAN TABLE t2
          356  +        `--USE TEMP B-TREE FOR ORDER BY
   291    357   }
   292    358   do_eqp_test 4.1.5 {
   293    359     SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 2
   294    360   } {
   295         -  1 0 0 {SCAN TABLE t1} 
   296         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   297         -  2 0 0 {SCAN TABLE t2} 
   298         -  2 0 0 {USE TEMP B-TREE FOR ORDER BY}
   299         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} 
          361  +  QUERY PLAN
          362  +  `--MERGE (EXCEPT)
          363  +     |--LEFT
          364  +     |  |--SCAN TABLE t1
          365  +     |  `--USE TEMP B-TREE FOR ORDER BY
          366  +     `--RIGHT
          367  +        |--SCAN TABLE t2
          368  +        `--USE TEMP B-TREE FOR ORDER BY
   300    369   }
   301    370   
   302    371   do_eqp_test 4.2.2 {
   303    372     SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 1
   304    373   } {
   305         -  1 0 0 {SCAN TABLE t1} 
   306         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   307         -  2 0 0 {SCAN TABLE t2 USING INDEX t2i1} 
   308         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} 
          374  +  QUERY PLAN
          375  +  `--MERGE (UNION ALL)
          376  +     |--LEFT
          377  +     |  |--SCAN TABLE t1
          378  +     |  `--USE TEMP B-TREE FOR ORDER BY
          379  +     `--RIGHT
          380  +        `--SCAN TABLE t2 USING INDEX t2i1
   309    381   }
   310    382   do_eqp_test 4.2.3 {
   311    383     SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 1
   312    384   } {
   313         -  1 0 0 {SCAN TABLE t1} 
   314         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   315         -  2 0 0 {SCAN TABLE t2 USING INDEX t2i1} 
   316         -  2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
   317         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)} 
          385  +  QUERY PLAN
          386  +  `--MERGE (UNION)
          387  +     |--LEFT
          388  +     |  |--SCAN TABLE t1
          389  +     |  `--USE TEMP B-TREE FOR ORDER BY
          390  +     `--RIGHT
          391  +        |--SCAN TABLE t2 USING INDEX t2i1
          392  +        `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
   318    393   }
   319    394   do_eqp_test 4.2.4 {
   320    395     SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 1
   321    396   } {
   322         -  1 0 0 {SCAN TABLE t1} 
   323         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   324         -  2 0 0 {SCAN TABLE t2 USING INDEX t2i1} 
   325         -  2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
   326         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)} 
          397  +  QUERY PLAN
          398  +  `--MERGE (INTERSECT)
          399  +     |--LEFT
          400  +     |  |--SCAN TABLE t1
          401  +     |  `--USE TEMP B-TREE FOR ORDER BY
          402  +     `--RIGHT
          403  +        |--SCAN TABLE t2 USING INDEX t2i1
          404  +        `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
   327    405   }
   328    406   do_eqp_test 4.2.5 {
   329    407     SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 1
   330    408   } {
   331         -  1 0 0 {SCAN TABLE t1} 
   332         -  1 0 0 {USE TEMP B-TREE FOR ORDER BY}
   333         -  2 0 0 {SCAN TABLE t2 USING INDEX t2i1} 
   334         -  2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
   335         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} 
          409  +  QUERY PLAN
          410  +  `--MERGE (EXCEPT)
          411  +     |--LEFT
          412  +     |  |--SCAN TABLE t1
          413  +     |  `--USE TEMP B-TREE FOR ORDER BY
          414  +     `--RIGHT
          415  +        |--SCAN TABLE t2 USING INDEX t2i1
          416  +        `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
   336    417   }
   337    418   
   338    419   do_eqp_test 4.3.1 {
   339    420     SELECT x FROM t1 UNION SELECT x FROM t2
   340    421   } {
   341         -  1 0 0 {SCAN TABLE t1} 
   342         -  2 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} 
   343         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} 
          422  +  QUERY PLAN
          423  +  `--COMPOUND QUERY
          424  +     |--LEFT-MOST SUBQUERY
          425  +     |  `--SCAN TABLE t1
          426  +     `--UNION USING TEMP B-TREE
          427  +        `--SCAN TABLE t2 USING COVERING INDEX t2i1
   344    428   }
   345    429   
   346    430   do_eqp_test 4.3.2 {
   347    431     SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1
   348    432   } {
   349         -  2 0 0 {SCAN TABLE t1} 
   350         -  3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} 
   351         -  1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
   352         -  4 0 0 {SCAN TABLE t1} 
   353         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)}
          433  +  QUERY PLAN
          434  +  `--COMPOUND QUERY
          435  +     |--LEFT-MOST SUBQUERY
          436  +     |  `--SCAN TABLE t1
          437  +     |--UNION USING TEMP B-TREE
          438  +     |  `--SCAN TABLE t2 USING COVERING INDEX t2i1
          439  +     `--UNION USING TEMP B-TREE
          440  +        `--SCAN TABLE t1
   354    441   }
   355    442   do_eqp_test 4.3.3 {
   356    443     SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ORDER BY 1
   357    444   } {
   358         -  2 0 0 {SCAN TABLE t1} 
   359         -  2 0 0 {USE TEMP B-TREE FOR ORDER BY} 
   360         -  3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1} 
   361         -  1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION)} 
   362         -  4 0 0 {SCAN TABLE t1} 
   363         -  4 0 0 {USE TEMP B-TREE FOR ORDER BY} 
   364         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 4 (UNION)}
          445  +  QUERY PLAN
          446  +  `--MERGE (UNION)
          447  +     |--LEFT
          448  +     |  `--MERGE (UNION)
          449  +     |     |--LEFT
          450  +     |     |  |--SCAN TABLE t1
          451  +     |     |  `--USE TEMP B-TREE FOR ORDER BY
          452  +     |     `--RIGHT
          453  +     |        `--SCAN TABLE t2 USING COVERING INDEX t2i1
          454  +     `--RIGHT
          455  +        |--SCAN TABLE t1
          456  +        `--USE TEMP B-TREE FOR ORDER BY
   365    457   }
   366    458   
          459  +if 0 {
   367    460   #-------------------------------------------------------------------------
   368    461   # This next block of tests verifies that the examples on the 
   369    462   # lang_explain.html page are correct.
   370    463   #
   371    464   drop_all_tables
   372    465   
   373         -# EVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b
          466  +# XVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b
   374    467   # FROM t1 WHERE a=1;
   375    468   # 0|0|0|SCAN TABLE t1
   376    469   #
   377    470   do_execsql_test 5.1.0 { CREATE TABLE t1(a INT, b INT, ex TEXT) }
   378    471   det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" {
   379    472     0 0 0 {SCAN TABLE t1}
   380    473   }
   381    474   
   382         -# EVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a);
          475  +# XVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a);
   383    476   # sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
   384    477   # 0|0|0|SEARCH TABLE t1 USING INDEX i1
   385    478   #
   386    479   do_execsql_test 5.2.0 { CREATE INDEX i1 ON t1(a) }
   387    480   det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" {
   388    481     0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
   389    482   }
   390    483   
   391         -# EVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b);
          484  +# XVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b);
   392    485   # sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
   393    486   # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
   394    487   #
   395    488   do_execsql_test 5.3.0 { CREATE INDEX i2 ON t1(a, b) }
   396    489   det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" {
   397    490     0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
   398    491   }
   399    492   
   400         -# EVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN
          493  +# XVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN
   401    494   # SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2;
   402    495   # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
   403    496   # 0|1|1|SCAN TABLE t2
   404    497   #
   405    498   do_execsql_test 5.4.0 {CREATE TABLE t2(c INT, d INT, ex TEXT)}
   406    499   det 5.4.1 "SELECT t1.a, t2.c FROM t1, t2 WHERE t1.a=1 AND t1.b>2" {
   407    500     0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)}
   408    501     0 1 1 {SCAN TABLE t2}
   409    502   }
   410    503   
   411         -# EVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN
          504  +# XVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN
   412    505   # SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2;
   413    506   # 0|0|1|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
   414    507   # 0|1|0|SCAN TABLE t2
   415    508   #
   416    509   det 5.5 "SELECT t1.a, t2.c FROM t2, t1 WHERE t1.a=1 AND t1.b>2" {
   417    510     0 0 1 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)}
   418    511     0 1 0 {SCAN TABLE t2}
   419    512   }
   420    513   
   421         -# EVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b);
          514  +# XVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b);
   422    515   # sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2;
   423    516   # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
   424    517   # 0|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
   425    518   #
   426    519   do_execsql_test 5.5.0 {CREATE INDEX i3 ON t1(b)}
   427    520   det 5.6.1 "SELECT a, b FROM t1 WHERE a=1 OR b=2" {
   428    521     0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
   429    522     0 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
   430    523   }
   431    524   
   432         -# EVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN
          525  +# XVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN
   433    526   # SELECT c, d FROM t2 ORDER BY c;
   434    527   # 0|0|0|SCAN TABLE t2
   435    528   # 0|0|0|USE TEMP B-TREE FOR ORDER BY
   436    529   #
   437    530   det 5.7 "SELECT c, d FROM t2 ORDER BY c" {
   438    531     0 0 0 {SCAN TABLE t2}
   439    532     0 0 0 {USE TEMP B-TREE FOR ORDER BY}
   440    533   }
   441    534   
   442         -# EVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c);
          535  +# XVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c);
   443    536   # sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c;
   444    537   # 0|0|0|SCAN TABLE t2 USING INDEX i4
   445    538   #
   446    539   do_execsql_test 5.8.0 {CREATE INDEX i4 ON t2(c)}
   447    540   det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
   448    541     0 0 0 {SCAN TABLE t2 USING INDEX i4}
   449    542   }
   450    543   
   451         -# EVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT
          544  +# XVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT
   452    545   # (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
   453    546   # 0|0|0|SCAN TABLE t2
   454    547   # 0|0|0|EXECUTE SCALAR SUBQUERY 1
   455    548   # 1|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
   456    549   # 0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2
   457    550   # 2|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
   458    551   #
................................................................................
   462    555     0 0 0 {SCAN TABLE t2 USING COVERING INDEX i4}
   463    556     0 0 0 {EXECUTE SCALAR SUBQUERY 1}
   464    557     1 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
   465    558     0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
   466    559     2 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
   467    560   }
   468    561   
   469         -# EVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN
          562  +# XVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN
   470    563   # SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
   471    564   # 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
   472    565   # 0|0|0|SCAN SUBQUERY 1
   473    566   # 0|0|0|USE TEMP B-TREE FOR GROUP BY
   474    567   #
   475    568   det 5.10 {
   476    569     SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x
   477    570   } {
   478    571     1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
   479    572     0 0 0 {SCAN SUBQUERY 1}
   480    573     0 0 0 {USE TEMP B-TREE FOR GROUP BY}
   481    574   }
   482    575   
   483         -# EVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN
          576  +# XVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN
   484    577   # SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1;
   485    578   # 0|0|0|SEARCH TABLE t2 USING INDEX i4 (c=?)
   486    579   # 0|1|1|SCAN TABLE t1
   487    580   #
   488    581   det 5.11 "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1" {
   489    582     0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?)}
   490    583     0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2}
   491    584   }
   492    585   
   493         -# EVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN
          586  +# XVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN
   494    587   # SELECT a FROM t1 UNION SELECT c FROM t2;
   495    588   # 1|0|0|SCAN TABLE t1
   496    589   # 2|0|0|SCAN TABLE t2
   497    590   # 0|0|0|COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)
   498    591   #
   499    592   det 5.12 "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2" {
   500    593     1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
   501    594     2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4}
   502    595     0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
   503    596   }
   504    597   
   505         -# EVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN
          598  +# XVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN
   506    599   # SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1;
   507    600   # 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
   508    601   # 2|0|0|SCAN TABLE t2 2|0|0|USE TEMP B-TREE FOR ORDER BY
   509    602   # 0|0|0|COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
   510    603   #
   511    604   det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" {
   512    605     1 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
   513    606     2 0 0 {SCAN TABLE t2}
   514    607     2 0 0 {USE TEMP B-TREE FOR ORDER BY}
   515    608     0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
   516    609   }
   517         -
   518    610   
   519    611   if {![nonzero_reserved_bytes]} {
   520    612     #-------------------------------------------------------------------------
   521    613     # The following tests - eqp-6.* - test that the example C code on 
   522    614     # documentation page eqp.html works. The C code is duplicated in test1.c
   523    615     # and wrapped in Tcl command [print_explain_query_plan] 
   524    616     #
................................................................................
   553    645     } [string trimleft {
   554    646   1 0 0 SCAN TABLE t1 USING COVERING INDEX i2
   555    647   2 0 0 SCAN TABLE t2
   556    648   2 0 0 USE TEMP B-TREE FOR ORDER BY
   557    649   0 0 0 COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
   558    650   }]
   559    651   }
          652  +}
   560    653   
   561    654   #-------------------------------------------------------------------------
   562    655   # The following tests - eqp-7.* - test that queries that use the OP_Count
   563    656   # optimization return something sensible with EQP.
   564    657   #
   565    658   drop_all_tables
   566    659   
................................................................................
   567    660   do_execsql_test 7.0 {
   568    661     CREATE TABLE t1(a INT, b INT, ex CHAR(100));
   569    662     CREATE TABLE t2(a INT, b INT, ex CHAR(100));
   570    663     CREATE INDEX i1 ON t2(a);
   571    664   }
   572    665   
   573    666   det 7.1 "SELECT count(*) FROM t1" {
   574         -  0 0 0 {SCAN TABLE t1}
          667  +  QUERY PLAN
          668  +  `--SCAN TABLE t1
   575    669   }
   576    670   
   577    671   det 7.2 "SELECT count(*) FROM t2" {
   578         -  0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1}
          672  +  QUERY PLAN
          673  +  `--SCAN TABLE t2 USING COVERING INDEX i1
   579    674   }
   580    675   
   581    676   do_execsql_test 7.3 {
   582    677     INSERT INTO t1(a,b) VALUES(1, 2);
   583    678     INSERT INTO t1(a,b) VALUES(3, 4);
   584    679   
   585    680     INSERT INTO t2(a,b) VALUES(1, 2);
................................................................................
   589    684     ANALYZE;
   590    685   }
   591    686   
   592    687   db close
   593    688   sqlite3 db test.db
   594    689   
   595    690   det 7.4 "SELECT count(*) FROM t1" {
   596         -  0 0 0 {SCAN TABLE t1}
          691  +  QUERY PLAN
          692  +  `--SCAN TABLE t1
   597    693   }
   598    694   
   599    695   det 7.5 "SELECT count(*) FROM t2" {
   600         -  0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1}
          696  +  QUERY PLAN
          697  +  `--SCAN TABLE t2 USING COVERING INDEX i1
   601    698   }
   602    699   
   603    700   #-------------------------------------------------------------------------
   604    701   # The following tests - eqp-8.* - test that queries that use the OP_Count
   605    702   # optimization return something sensible with EQP.
   606    703   #
   607    704   drop_all_tables
................................................................................
   608    705   
   609    706   do_execsql_test 8.0 {
   610    707     CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
   611    708     CREATE TABLE t2(a, b, c);
   612    709   }
   613    710   
   614    711   det 8.1.1 "SELECT * FROM t2" {
   615         -  0 0 0 {SCAN TABLE t2}
          712  +  QUERY PLAN
          713  +  `--SCAN TABLE t2
   616    714   }
   617    715   
   618    716   det 8.1.2 "SELECT * FROM t2 WHERE rowid=?" {
   619         -  0 0 0 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
          717  +  QUERY PLAN
          718  +  `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
   620    719   }
   621    720   
   622    721   det 8.1.3 "SELECT count(*) FROM t2" {
   623         -  0 0 0 {SCAN TABLE t2}
          722  +  QUERY PLAN
          723  +  `--SCAN TABLE t2
   624    724   }
   625    725   
   626    726   det 8.2.1 "SELECT * FROM t1" {
   627         -  0 0 0 {SCAN TABLE t1}
          727  +  QUERY PLAN
          728  +  `--SCAN TABLE t1
   628    729   }
   629    730   
   630    731   det 8.2.2 "SELECT * FROM t1 WHERE b=?" {
   631         -  0 0 0 {SEARCH TABLE t1 USING PRIMARY KEY (b=?)}
          732  +  QUERY PLAN
          733  +  `--SEARCH TABLE t1 USING PRIMARY KEY (b=?)
   632    734   }
   633    735   
   634    736   det 8.2.3 "SELECT * FROM t1 WHERE b=? AND c=?" {
   635         -  0 0 0 {SEARCH TABLE t1 USING PRIMARY KEY (b=? AND c=?)}
          737  +  QUERY PLAN
          738  +  `--SEARCH TABLE t1 USING PRIMARY KEY (b=? AND c=?)
   636    739   }
   637    740   
   638    741   det 8.2.4 "SELECT count(*) FROM t1" {
   639         -  0 0 0 {SCAN TABLE t1}
          742  +  QUERY PLAN
          743  +  `--SCAN TABLE t1
   640    744   }
   641    745   
   642    746   
   643    747   
   644    748   
   645    749   
   646    750   
   647    751   
   648    752   finish_test

Changes to test/fts3aux1.test.

   101    101   db func rec rec
   102    102   
   103    103   # Use EQP to show that the WHERE expression "term='braid'" uses a different
   104    104   # index number (1) than "+term='braid'" (0).
   105    105   #
   106    106   do_execsql_test 2.1.1.1 {
   107    107     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term='braid'
   108         -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:} }
          108  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 1:*/}
   109    109   do_execsql_test 2.1.1.2 {
   110    110     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term='braid'
   111         -} {0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}}
          111  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
   112    112   
   113    113   # Now show that using "term='braid'" means the virtual table returns
   114    114   # only 1 row to SQLite, but "+term='braid'" means all 19 are returned.
   115    115   #
   116    116   do_test 2.1.2.1 {
   117    117     set cnt 0
   118    118     execsql { SELECT * FROM terms_v WHERE rec('cnt', term) AND term='braid' }
................................................................................
   150    150   
   151    151   # Special case: term=NULL
   152    152   #
   153    153   do_execsql_test 2.1.5 { SELECT * FROM terms WHERE term=NULL } {}
   154    154   
   155    155   do_execsql_test 2.2.1.1 {
   156    156     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term>'brain'
   157         -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 2:} }
          157  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 2:*/}
   158    158   do_execsql_test 2.2.1.2 {
   159    159     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term>'brain'
   160         -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} }
          160  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
   161    161   
   162    162   do_execsql_test 2.2.1.3 {
   163    163     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term<'brain'
   164         -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 4:} }
          164  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 4:*/}
   165    165   do_execsql_test 2.2.1.4 {
   166    166     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term<'brain'
   167         -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} }
          167  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
   168    168   
   169    169   do_execsql_test 2.2.1.5 {
   170    170     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE term BETWEEN 'brags' AND 'brain'
   171         -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 6:} }
          171  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 6:*/}
   172    172   do_execsql_test 2.2.1.6 {
   173    173     EXPLAIN QUERY PLAN SELECT * FROM terms WHERE +term BETWEEN 'brags' AND 'brain'
   174         -} { 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} }
          174  +} {/*SCAN TABLE terms VIRTUAL TABLE INDEX 0:*/}
   175    175   
   176    176   do_test 2.2.2.1 {
   177    177     set cnt 0
   178    178     execsql { SELECT * FROM terms WHERE rec('cnt', term) AND term>'brain' }
   179    179     set cnt
   180    180   } {18}
   181    181   do_test 2.2.2.2 {
................................................................................
   331    331     5    1    "ORDER BY documents"
   332    332     6    1    "ORDER BY documents DESC"
   333    333     7    1    "ORDER BY occurrences ASC"
   334    334     8    1    "ORDER BY occurrences"
   335    335     9    1    "ORDER BY occurrences DESC"
   336    336   } {
   337    337   
   338         -  set res [list 0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}]
   339         -  if {$sort} { lappend res 0 0 0 {USE TEMP B-TREE FOR ORDER BY} }
          338  +  set res {SCAN TABLE terms VIRTUAL TABLE INDEX 0:}
          339  +  if {$sort} { append res {*USE TEMP B-TREE FOR ORDER BY} }
          340  +  set res "/*$res*/"
   340    341   
   341    342     set sql "SELECT * FROM terms $orderby"
   342    343     do_execsql_test 2.3.1.$tn "EXPLAIN QUERY PLAN $sql" $res
   343    344   }
   344    345   
   345    346   #-------------------------------------------------------------------------
   346    347   # The next set of tests, fts3aux1-3.*, test error conditions in the 
................................................................................
   399    400     INSERT INTO x1 VALUES('f g h i j');
   400    401     INSERT INTO x1 VALUES('k k l l a');
   401    402   
   402    403     INSERT INTO x2 SELECT term FROM terms WHERE col = '*';
   403    404     INSERT INTO x3 SELECT term FROM terms WHERE col = '*';
   404    405   }
   405    406   
   406         -proc do_plansql_test {tn sql r} {
   407         -  uplevel do_execsql_test $tn [list "EXPLAIN QUERY PLAN $sql ; $sql"] [list $r]
          407  +proc do_plansql_test {tn sql r1 r2} {
          408  +  do_eqp_test $tn.eqp $sql $r1
          409  +  do_execsql_test $tn $sql $r2
   408    410   }
   409    411   
   410    412   do_plansql_test 4.2 {
   411    413     SELECT y FROM x2, terms WHERE y = term AND col = '*'
   412    414   } {
   413         -  0 0 0 {SCAN TABLE x2} 
   414         -  0 1 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:} 
          415  +  QUERY PLAN
          416  +  |--SCAN TABLE x2
          417  +  `--SCAN TABLE terms VIRTUAL TABLE INDEX 1:
          418  +} {
   415    419     a b c d e f g h i j k l
   416    420   }
   417    421   
   418    422   do_plansql_test 4.3 {
   419    423     SELECT y FROM terms, x2 WHERE y = term AND col = '*'
   420    424   } {
   421         -  0 0 1 {SCAN TABLE x2} 
   422         -  0 1 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 1:} 
          425  +  QUERY PLAN
          426  +  |--SCAN TABLE x2
          427  +  `--SCAN TABLE terms VIRTUAL TABLE INDEX 1:
          428  +} {
   423    429     a b c d e f g h i j k l
   424    430   }
   425    431   
   426    432   do_plansql_test 4.4 {
   427    433     SELECT y FROM x3, terms WHERE y = term AND col = '*'
   428    434   } {
   429         -  0 0 1 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} 
   430         -  0 1 0 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)}
          435  +  QUERY PLAN
          436  +  |--SCAN TABLE terms VIRTUAL TABLE INDEX 0:
          437  +  `--SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)
          438  +} {
   431    439     a b c d e f g h i j k l
   432    440   }
   433    441   
   434    442   do_plansql_test 4.5 {
   435    443     SELECT y FROM terms, x3 WHERE y = term AND occurrences>1 AND col = '*'
   436    444   } {
   437         -  0 0 0 {SCAN TABLE terms VIRTUAL TABLE INDEX 0:} 
   438         -  0 1 1 {SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)}
          445  +  QUERY PLAN
          446  +  |--SCAN TABLE terms VIRTUAL TABLE INDEX 0:
          447  +  `--SEARCH TABLE x3 USING COVERING INDEX i1 (y=?)
          448  +} {
   439    449     a k l
   440    450   }
   441    451   
   442    452   #-------------------------------------------------------------------------
   443    453   # The following tests check that fts4aux can handle an fts table with an
   444    454   # odd name (one that requires quoting for use in SQL statements). And that
   445    455   # the argument to the fts4aux constructor is properly dequoted before use.

Changes to test/fts3expr.test.

   405    405   # cases in the test code, which makes test coverage easier to measure.
   406    406   # 
   407    407   do_test fts3expr-5.1 {
   408    408     catchsql { SELECT fts3_exprtest('simple', 'a b') }
   409    409   } {1 {Usage: fts3_exprtest(tokenizer, expr, col1, ...}}
   410    410   do_test fts3expr-5.2 {
   411    411     catchsql { SELECT fts3_exprtest('doesnotexist', 'a b', 'c') }
   412         -} {1 {No such tokenizer module}}
          412  +} {1 {unknown tokenizer: doesnotexist}}
   413    413   do_test fts3expr-5.3 {
   414    414     catchsql { SELECT fts3_exprtest('simple', 'a b OR', 'c') }
   415    415   } {1 {Error parsing expression}}
   416    416   
   417    417   #------------------------------------------------------------------------
   418    418   # The next set of tests verifies that things actually work as they are
   419    419   # supposed to when using the new syntax.

Changes to test/fts3expr4.test.

    25     25   set sqlite_fts3_enable_parentheses 1
    26     26   
    27     27   proc test_fts3expr {tokenizer expr} {
    28     28     db one {SELECT fts3_exprtest($tokenizer, $expr, 'a', 'b', 'c')}
    29     29   }
    30     30   
    31     31   proc do_icu_expr_test {tn expr res} {
    32         -  uplevel [list do_test $tn [list test_fts3expr icu $expr] [list {*}$res]]
           32  +  set res2 [list {*}$res]
           33  +  uplevel [list do_test $tn [list test_fts3expr "icu en_US" $expr] $res2]
    33     34   }
    34     35   
    35     36   proc do_simple_expr_test {tn expr res} {
    36     37     uplevel [list do_test $tn [list test_fts3expr simple $expr] [list {*}$res]]
    37     38   }
    38     39   
    39     40   #-------------------------------------------------------------------------

Changes to test/fts3join.test.

    92     92   
    93     93   do_eqp_test 4.2 {
    94     94     SELECT * FROM t4 LEFT JOIN (
    95     95         SELECT docid, * FROM ft4 WHERE ft4 MATCH ?
    96     96     ) AS rr ON t4.rowid=rr.docid 
    97     97     WHERE t4.y = ?;
    98     98   } {
    99         -  1 0 0 {SCAN TABLE ft4 VIRTUAL TABLE INDEX 3:} 
   100         -  0 0 0 {SCAN TABLE t4}
   101         -  0 1 1 {SEARCH SUBQUERY 1 AS rr USING AUTOMATIC COVERING INDEX (docid=?)}
           99  +  QUERY PLAN
          100  +  |--MATERIALIZE xxxxxx
          101  +  |  `--SCAN TABLE ft4 VIRTUAL TABLE INDEX 3:
          102  +  |--SCAN TABLE t4
          103  +  `--SEARCH SUBQUERY xxxxxx AS rr USING AUTOMATIC COVERING INDEX (docid=?)
   102    104   }
   103    105   
   104    106   finish_test

Changes to test/fts3query.test.

   114    114       CREATE VIRTUAL TABLE ft USING fts3(title);
   115    115       CREATE TABLE bt(title);
   116    116     }
   117    117   } {}
   118    118   do_eqp_test fts3query-4.2 {
   119    119     SELECT t1.number FROM t1, ft WHERE t1.number=ft.rowid ORDER BY t1.date
   120    120   } {
   121         -  0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1} 
   122         -  0 1 1 {SCAN TABLE ft VIRTUAL TABLE INDEX 1:}
          121  +  QUERY PLAN
          122  +  |--SCAN TABLE t1 USING COVERING INDEX i1
          123  +  `--SCAN TABLE ft VIRTUAL TABLE INDEX 1:
   123    124   }
   124    125   do_eqp_test fts3query-4.3 {
   125    126     SELECT t1.number FROM ft, t1 WHERE t1.number=ft.rowid ORDER BY t1.date
   126    127   } {
   127         -  0 0 1 {SCAN TABLE t1 USING COVERING INDEX i1} 
   128         -  0 1 0 {SCAN TABLE ft VIRTUAL TABLE INDEX 1:}
          128  +  QUERY PLAN
          129  +  |--SCAN TABLE t1 USING COVERING INDEX i1
          130  +  `--SCAN TABLE ft VIRTUAL TABLE INDEX 1:
   129    131   }
   130    132   do_eqp_test fts3query-4.4 {
   131    133     SELECT t1.number FROM t1, bt WHERE t1.number=bt.rowid ORDER BY t1.date
   132    134   } {
   133         -  0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1} 
   134         -  0 1 1 {SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)}
          135  +  QUERY PLAN
          136  +  |--SCAN TABLE t1 USING COVERING INDEX i1
          137  +  `--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)
   135    138   }
   136    139   do_eqp_test fts3query-4.5 {
   137    140     SELECT t1.number FROM bt, t1 WHERE t1.number=bt.rowid ORDER BY t1.date
   138    141   } {
   139         -  0 0 1 {SCAN TABLE t1 USING COVERING INDEX i1} 
   140         -  0 1 0 {SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)}
          142  +  QUERY PLAN
          143  +  |--SCAN TABLE t1 USING COVERING INDEX i1
          144  +  `--SEARCH TABLE bt USING INTEGER PRIMARY KEY (rowid=?)
   141    145   }
   142    146   
   143    147   
   144    148   # Test that calling matchinfo() with the wrong number of arguments, or with
   145    149   # an invalid argument returns an error.
   146    150   #
   147    151   do_execsql_test 5.1 {

Changes to test/fuzz_malloc.test.

    53     53     execsql $::prep
    54     54     set jj 0
    55     55     for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} {
    56     56       expr srand($jj)
    57     57       incr jj
    58     58       set ::sql [subst $::fuzzyopts(-template)]
    59     59       # puts fuzyy-sql=\[$::sql\]; flush stdout
    60         -    foreach {rc res} [catchsql "$::sql"] {}
           60  +    foreach {rc ::fmtres} [catchsql "$::sql"] {}
    61     61       if {$rc==0} {
    62     62         set nErr1 [set_test_counter errors]
    63         -      do_malloc_test $testname-$ii -sqlbody $::sql -sqlprep $::prep
           63  +      do_faultsim_test $testname-$ii -faults oom* -body {
           64  +        execsql $::sql
           65  +      } -test {
           66  +        if {$testrc && $testresult!="datatype mismatch"} { 
           67  +          faultsim_test_result {0 {}}
           68  +        }
           69  +      }
    64     70         if {[set_test_counter errors]>$nErr1} {
    65     71           puts "Previous fuzzy-sql=\[$::sql\]"
    66     72           flush stdout
    67     73         }
    68     74       } else {
    69     75         incr ii -1
    70     76       }

Changes to test/fuzzcheck.c.

   716    716   */
   717    717   static void rebuild_database(sqlite3 *db){
   718    718     int rc;
   719    719     rc = sqlite3_exec(db, 
   720    720        "BEGIN;\n"
   721    721        "CREATE TEMP TABLE dbx AS SELECT DISTINCT dbcontent FROM db;\n"
   722    722        "DELETE FROM db;\n"
   723         -     "INSERT INTO db(dbid, dbcontent) SELECT NULL, dbcontent FROM dbx ORDER BY 2;\n"
          723  +     "INSERT INTO db(dbid, dbcontent) "
          724  +        " SELECT NULL, dbcontent FROM dbx ORDER BY 2;\n"
   724    725        "DROP TABLE dbx;\n"
   725    726        "CREATE TEMP TABLE sx AS SELECT DISTINCT sqltext FROM xsql;\n"
   726    727        "DELETE FROM xsql;\n"
   727         -     "INSERT INTO xsql(sqlid,sqltext) SELECT NULL, sqltext FROM sx ORDER BY 2;\n"
          728  +     "INSERT INTO xsql(sqlid,sqltext) "
          729  +        " SELECT NULL, sqltext FROM sx ORDER BY 2;\n"
   728    730        "DROP TABLE sx;\n"
   729    731        "COMMIT;\n"
   730    732        "PRAGMA page_size=1024;\n"
   731    733        "VACUUM;\n", 0, 0, 0);
   732    734     if( rc ) fatalError("cannot rebuild: %s", sqlite3_errmsg(db));
   733    735   }
   734    736   
................................................................................
   803    805   "  --dbid N             Use only the database where dbid=N\n"
   804    806   "  --export-db DIR      Write databases to files(s) in DIR. Works with --dbid\n"
   805    807   "  --export-sql DIR     Write SQL to file(s) in DIR. Also works with --sqlid\n"
   806    808   "  --help               Show this help text\n"
   807    809   "  -q|--quiet           Reduced output\n"
   808    810   "  --limit-mem N        Limit memory used by test SQLite instance to N bytes\n"
   809    811   "  --limit-vdbe         Panic if any test runs for more than 100,000 cycles\n"
   810         -"  --load-sql ARGS...   Load SQL scripts fro files into SOURCE-DB\n"
          812  +"  --load-sql ARGS...   Load SQL scripts fron files into SOURCE-DB\n"
   811    813   "  --load-db ARGS...    Load template databases from files into SOURCE_DB\n"
   812    814   "  -m TEXT              Add a description to the database\n"
   813    815   "  --native-vfs         Use the native VFS for initially empty database files\n"
   814    816   "  --native-malloc      Turn off MEMSYS3/5 and Lookaside\n"
   815    817   "  --oss-fuzz           Enable OSS-FUZZ testing\n"
   816    818   "  --prng-seed N        Seed value for the PRGN inside of SQLite\n"
   817    819   "  --rebuild            Rebuild and vacuum the database file\n"
................................................................................
   823    825   }
   824    826   
   825    827   int main(int argc, char **argv){
   826    828     sqlite3_int64 iBegin;        /* Start time of this program */
   827    829     int quietFlag = 0;           /* True if --quiet or -q */
   828    830     int verboseFlag = 0;         /* True if --verbose or -v */
   829    831     char *zInsSql = 0;           /* SQL statement for --load-db or --load-sql */
   830         -  int iFirstInsArg = 0;        /* First argv[] to use for --load-db or --load-sql */
          832  +  int iFirstInsArg = 0;        /* First argv[] for --load-db or --load-sql */
   831    833     sqlite3 *db = 0;             /* The open database connection */
   832    834     sqlite3_stmt *pStmt;         /* A prepared statement */
   833    835     int rc;                      /* Result code from SQLite interface calls */
   834    836     Blob *pSql;                  /* For looping over SQL scripts */
   835    837     Blob *pDb;                   /* For looping over template databases */
   836    838     int i;                       /* Loop index for the argv[] loop */
   837    839     int onlySqlid = -1;          /* --sqlid */
................................................................................
   843    845     int runFlags = 0;            /* Flags sent to runSql() */
   844    846     char *zMsg = 0;              /* Add this message */
   845    847     int nSrcDb = 0;              /* Number of source databases */
   846    848     char **azSrcDb = 0;          /* Array of source database names */
   847    849     int iSrcDb;                  /* Loop over all source databases */
   848    850     int nTest = 0;               /* Total number of tests performed */
   849    851     char *zDbName = "";          /* Appreviated name of a source database */
   850         -  const char *zFailCode = 0;   /* Value of the TEST_FAILURE environment variable */
          852  +  const char *zFailCode = 0;   /* Value of the TEST_FAILURE env variable */
   851    853     int cellSzCkFlag = 0;        /* --cell-size-check */
   852         -  int sqlFuzz = 0;             /* True for SQL fuzz testing. False for DB fuzz */
          854  +  int sqlFuzz = 0;             /* True for SQL fuzz. False for DB fuzz */
   853    855     int iTimeout = 120;          /* Default 120-second timeout */
   854    856     int nMem = 0;                /* Memory limit */
   855    857     int nMemThisDb = 0;          /* Memory limit set by the CONFIG table */
   856    858     char *zExpDb = 0;            /* Write Databases to files in this directory */
   857    859     char *zExpSql = 0;           /* Write SQL to files in this directory */
   858    860     void *pHeap = 0;             /* Heap for use by SQLite */
   859    861     int ossFuzz = 0;             /* enable OSS-FUZZ testing */
   860    862     int ossFuzzThisDb = 0;       /* ossFuzz value for this particular database */
   861    863     int nativeMalloc = 0;        /* Turn off MEMSYS3/5 and lookaside if true */
   862    864     sqlite3_vfs *pDfltVfs;       /* The default VFS */
          865  +  int openFlags4Data;          /* Flags for sqlite3_open_v2() */
   863    866   
   864    867     iBegin = timeOfDay();
   865    868   #ifdef __unix__
   866    869     signal(SIGALRM, timeoutHandler);
   867    870   #endif
   868    871     g.zArgv0 = argv[0];
          872  +  openFlags4Data = SQLITE_OPEN_READONLY;
   869    873     zFailCode = getenv("TEST_FAILURE");
   870    874     pDfltVfs = sqlite3_vfs_find(0);
   871    875     inmemVfsRegister(1);
   872    876     for(i=1; i<argc; i++){
   873    877       const char *z = argv[i];
   874    878       if( z[0]=='-' ){
   875    879         z++;
................................................................................
   902    906           nMem = integerValue(argv[++i]);
   903    907   #endif
   904    908         }else
   905    909         if( strcmp(z,"limit-vdbe")==0 ){
   906    910           vdbeLimitFlag = 1;
   907    911         }else
   908    912         if( strcmp(z,"load-sql")==0 ){
   909         -        zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))";
          913  +        zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))";
   910    914           iFirstInsArg = i+1;
          915  +        openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
   911    916           break;
   912    917         }else
   913    918         if( strcmp(z,"load-db")==0 ){
   914    919           zInsSql = "INSERT INTO db(dbcontent) VALUES(readfile(?1))";
   915    920           iFirstInsArg = i+1;
          921  +        openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
   916    922           break;
   917    923         }else
   918    924         if( strcmp(z,"m")==0 ){
   919    925           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   920    926           zMsg = argv[++i];
          927  +        openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
   921    928         }else
   922    929         if( strcmp(z,"native-malloc")==0 ){
   923    930           nativeMalloc = 1;
   924    931         }else
   925    932         if( strcmp(z,"native-vfs")==0 ){
   926    933           nativeFlag = 1;
   927    934         }else
................................................................................
   934    941         }else
   935    942         if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
   936    943           quietFlag = 1;
   937    944           verboseFlag = 0;
   938    945         }else
   939    946         if( strcmp(z,"rebuild")==0 ){
   940    947           rebuildFlag = 1;
          948  +        openFlags4Data = SQLITE_OPEN_READWRITE;
   941    949         }else
   942    950         if( strcmp(z,"result-trace")==0 ){
   943    951           runFlags |= SQL_OUTPUT;
   944    952         }else
   945    953         if( strcmp(z,"sqlid")==0 ){
   946    954           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   947    955           onlySqlid = integerValue(argv[++i]);
................................................................................
   979    987         fatalError("cannot import into more than one database");
   980    988       }
   981    989     }
   982    990   
   983    991     /* Process each source database separately */
   984    992     for(iSrcDb=0; iSrcDb<nSrcDb; iSrcDb++){
   985    993       rc = sqlite3_open_v2(azSrcDb[iSrcDb], &db,
   986         -                         SQLITE_OPEN_READWRITE, pDfltVfs->zName);
          994  +                         openFlags4Data, pDfltVfs->zName);
   987    995       if( rc ){
   988    996         fatalError("cannot open source database %s - %s",
   989    997         azSrcDb[iSrcDb], sqlite3_errmsg(db));
   990    998       }
   991    999       rc = sqlite3_exec(db,
   992   1000          "CREATE TABLE IF NOT EXISTS db(\n"
   993   1001          "  dbid INTEGER PRIMARY KEY, -- database id\n"
................................................................................
  1010   1018         if( rc ) fatalError("cannot change description: %s", sqlite3_errmsg(db));
  1011   1019       }
  1012   1020       ossFuzzThisDb = ossFuzz;
  1013   1021   
  1014   1022       /* If the CONFIG(name,value) table exists, read db-specific settings
  1015   1023       ** from that table */
  1016   1024       if( sqlite3_table_column_metadata(db,0,"config",0,0,0,0,0,0)==SQLITE_OK ){
  1017         -      rc = sqlite3_prepare_v2(db, "SELECT name, value FROM config", -1, &pStmt, 0);
         1025  +      rc = sqlite3_prepare_v2(db, "SELECT name, value FROM config",
         1026  +                                  -1, &pStmt, 0);
  1018   1027         if( rc ) fatalError("cannot prepare query of CONFIG table: %s",
  1019   1028                             sqlite3_errmsg(db));
  1020   1029         while( SQLITE_ROW==sqlite3_step(pStmt) ){
  1021   1030           const char *zName = (const char *)sqlite3_column_text(pStmt,0);
  1022   1031           if( zName==0 ) continue;
  1023   1032           if( strcmp(zName, "oss-fuzz")==0 ){
  1024   1033             ossFuzzThisDb = sqlite3_column_int(pStmt,1);
................................................................................
  1049   1058           sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC);
  1050   1059           sqlite3_step(pStmt);
  1051   1060           rc = sqlite3_reset(pStmt);
  1052   1061           if( rc ) fatalError("insert failed for %s", argv[i]);
  1053   1062         }
  1054   1063         sqlite3_finalize(pStmt);
  1055   1064         rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
  1056         -      if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db));
         1065  +      if( rc ) fatalError("cannot commit the transaction: %s",
         1066  +                          sqlite3_errmsg(db));
  1057   1067         rebuild_database(db);
  1058   1068         sqlite3_close(db);
  1059   1069         return 0;
  1060   1070       }
  1061   1071       rc = sqlite3_exec(db, "PRAGMA query_only=1;", 0, 0, 0);
  1062   1072       if( rc ) fatalError("cannot set database to query-only");
  1063   1073       if( zExpDb!=0 || zExpSql!=0 ){
................................................................................
  1193   1203               prevAmt = amt;
  1194   1204             }
  1195   1205           }
  1196   1206           createVFile("main.db", pDb->sz, pDb->a);
  1197   1207           sqlite3_randomness(0,0);
  1198   1208           if( ossFuzzThisDb ){
  1199   1209   #ifndef SQLITE_OSS_FUZZ
  1200         -          fatalError("--oss-fuzz not supported: recompile with -DSQLITE_OSS_FUZZ");
         1210  +          fatalError("--oss-fuzz not supported: recompile"
         1211  +                     " with -DSQLITE_OSS_FUZZ");
  1201   1212   #else
  1202   1213             extern int LLVMFuzzerTestOneInput(const uint8_t*, size_t);
  1203   1214             LLVMFuzzerTestOneInput((const uint8_t*)pSql->a, (size_t)pSql->sz);
  1204   1215   #endif
  1205   1216           }else{
  1206   1217             openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
  1207   1218             if( nativeFlag && pDb->sz==0 ){
................................................................................
  1212   1223             if( rc ) fatalError("cannot open inmem database");
  1213   1224             sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 100000000);
  1214   1225             sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 50);
  1215   1226             if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
  1216   1227             setAlarm(iTimeout);
  1217   1228   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  1218   1229             if( sqlFuzz || vdbeLimitFlag ){
  1219         -            sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag);
         1230  +            sqlite3_progress_handler(db, 100000, progressHandler,
         1231  +                                     &vdbeLimitFlag);
  1220   1232             }
  1221   1233   #endif
  1222   1234             do{
  1223   1235               runSql(db, (char*)pSql->a, runFlags);
  1224   1236             }while( timeoutTest );
  1225   1237             setAlarm(0);
  1226   1238             sqlite3_exec(db, "PRAGMA temp_store_directory=''", 0, 0, 0);

Changes to test/fuzzdata5.db.

cannot compute difference between binary files

Added test/fuzzdata6.db.

cannot compute difference between binary files

Changes to test/index6.test.

   314    314     INSERT INTO t8b VALUES('value', 3);
   315    315     INSERT INTO t8b VALUES('dummy', 4);
   316    316   } {}
   317    317   
   318    318   do_eqp_test index6-8.1 {
   319    319     SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
   320    320   } {
   321         -  0 0 0 {SCAN TABLE t8a} 
   322         -  0 1 1 {SEARCH TABLE t8b USING INDEX i8c (y=?)}
          321  +  QUERY PLAN
          322  +  |--SCAN TABLE t8a
          323  +  `--SEARCH TABLE t8b USING INDEX i8c (y=?)
   323    324   }
   324    325   
   325    326   do_execsql_test index6-8.2 {
   326    327     SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
   327    328   } {
   328    329     1 one value 1 
   329    330     2 two {} {} 

Changes to test/index7.test.

   317    317     INSERT INTO t4 VALUES('def', 'xyz');
   318    318     SELECT * FROM v4 WHERE d='xyz' AND c='def'
   319    319   } {
   320    320     def xyz
   321    321   }
   322    322   do_eqp_test index7-6.4 {
   323    323     SELECT * FROM v4 WHERE d='xyz' AND c='def'
   324         -} {
   325         -  0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)}
   326         -}
          324  +} {SEARCH TABLE t4 USING INDEX i4 (c=?)}
          325  +
   327    326   do_catchsql_test index7-6.5 {
   328    327     CREATE INDEX t5a ON t5(a) WHERE a=#1;
   329    328   } {1 {near "#1": syntax error}}
   330    329   
   331    330   
   332    331   finish_test

Changes to test/indexedby.test.

    36     36   #
    37     37   proc EQP {sql} {
    38     38     uplevel "execsql {EXPLAIN QUERY PLAN $sql}"
    39     39   }
    40     40   
    41     41   # These tests are to check that "EXPLAIN QUERY PLAN" is working as expected.
    42     42   #
    43         -do_execsql_test indexedby-1.2 {
    44         -  EXPLAIN QUERY PLAN select * from t1 WHERE a = 10; 
    45         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
    46         -do_execsql_test indexedby-1.3 {
    47         -  EXPLAIN QUERY PLAN select * from t1 ; 
    48         -} {0 0 0 {SCAN TABLE t1}}
    49         -do_execsql_test indexedby-1.4 {
    50         -  EXPLAIN QUERY PLAN select * from t1, t2 WHERE c = 10; 
           43  +do_eqp_test indexedby-1.2 {
           44  +  select * from t1 WHERE a = 10; 
           45  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
           46  +do_eqp_test indexedby-1.3 {
           47  +  select * from t1 ; 
           48  +} {SCAN TABLE t1}
           49  +do_eqp_test indexedby-1.4 {
           50  +  select * from t1, t2 WHERE c = 10; 
    51     51   } {
    52         -  0 0 1 {SEARCH TABLE t2 USING INDEX i3 (c=?)} 
    53         -  0 1 0 {SCAN TABLE t1}
           52  +  QUERY PLAN
           53  +  |--SEARCH TABLE t2 USING INDEX i3 (c=?)
           54  +  `--SCAN TABLE t1
    54     55   }
    55     56   
    56     57   # Parser tests. Test that an INDEXED BY or NOT INDEX clause can be 
    57     58   # attached to a table in the FROM clause, but not to a sub-select or
    58     59   # SQL view. Also test that specifying an index that does not exist or
    59     60   # is attached to a different table is detected as an error.
    60     61   #
    61         -# EVIDENCE-OF: R-07004-11522 -- syntax diagram qualified-table-name
           62  +# X-EVIDENCE-OF: R-07004-11522 -- syntax diagram qualified-table-name
    62     63   # 
    63     64   # EVIDENCE-OF: R-58230-57098 The "INDEXED BY index-name" phrase
    64     65   # specifies that the named index must be used in order to look up values
    65     66   # on the preceding table.
    66     67   #
    67     68   do_test indexedby-2.1 {
    68     69     execsql { SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'}
................................................................................
   111    112   #
   112    113   # EVIDENCE-OF: R-37002-28871 The "NOT INDEXED" clause specifies that no
   113    114   # index shall be used when accessing the preceding table, including
   114    115   # implied indices create by UNIQUE and PRIMARY KEY constraints. However,
   115    116   # the rowid can still be used to look up entries even when "NOT INDEXED"
   116    117   # is specified.
   117    118   #
   118         -do_execsql_test indexedby-3.1 {
   119         -  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a = 'one' AND b = 'two'
          119  +do_eqp_test indexedby-3.1 {
          120  +  SELECT * FROM t1 WHERE a = 'one' AND b = 'two'
   120    121   } {/SEARCH TABLE t1 USING INDEX/}
   121         -do_execsql_test indexedby-3.1.1 {
   122         -  EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'
   123         -} {0 0 0 {SCAN TABLE t1}}
   124         -do_execsql_test indexedby-3.1.2 {
   125         -  EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE rowid=1
          122  +do_eqp_test indexedby-3.1.1 {
          123  +  SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'
          124  +} {SCAN TABLE t1}
          125  +do_eqp_test indexedby-3.1.2 {
          126  +  SELECT * FROM t1 NOT INDEXED WHERE rowid=1
   126    127   } {/SEARCH TABLE t1 USING INTEGER PRIMARY KEY .rowid=/}
   127    128   
   128    129   
   129         -do_execsql_test indexedby-3.2 {
   130         -  EXPLAIN QUERY PLAN 
          130  +do_eqp_test indexedby-3.2 {
   131    131     SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'
   132         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
   133         -do_execsql_test indexedby-3.3 {
   134         -  EXPLAIN QUERY PLAN 
          132  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
          133  +do_eqp_test indexedby-3.3 {
   135    134     SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two'
   136         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
          135  +} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
   137    136   do_test indexedby-3.4 {
   138    137     catchsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' }
   139    138   } {1 {no query solution}}
   140    139   do_test indexedby-3.5 {
   141    140     catchsql { SELECT * FROM t1 INDEXED BY i2 ORDER BY a }
   142    141   } {1 {no query solution}}
   143    142   do_test indexedby-3.6 {
   144    143     catchsql { SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' }
   145    144   } {0 {}}
   146    145   do_test indexedby-3.7 {
   147    146     catchsql { SELECT * FROM t1 INDEXED BY i1 ORDER BY a }
   148    147   } {0 {}}
   149    148   
   150         -do_execsql_test indexedby-3.8 {
   151         -  EXPLAIN QUERY PLAN 
          149  +do_eqp_test indexedby-3.8 {
   152    150     SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 ORDER BY e 
   153         -} {0 0 0 {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1}}
   154         -do_execsql_test indexedby-3.9 {
   155         -  EXPLAIN QUERY PLAN 
          151  +} {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1}
          152  +do_eqp_test indexedby-3.9 {
   156    153     SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE e = 10 
   157         -} {0 0 0 {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?)}}
          154  +} {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?)}
   158    155   do_test indexedby-3.10 {
   159    156     catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE f = 10 }
   160    157   } {1 {no query solution}}
   161    158   do_test indexedby-3.11 {
   162    159     catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_2 WHERE f = 10 }
   163    160   } {1 {no such index: sqlite_autoindex_t3_2}}
   164    161   
   165    162   # Tests for multiple table cases.
   166    163   #
   167         -do_execsql_test indexedby-4.1 {
   168         -  EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE a = c 
          164  +do_eqp_test indexedby-4.1 {
          165  +  SELECT * FROM t1, t2 WHERE a = c 
   169    166   } {
   170         -  0 0 0 {SCAN TABLE t1} 
   171         -  0 1 1 {SEARCH TABLE t2 USING INDEX i3 (c=?)}
          167  +  QUERY PLAN
          168  +  |--SCAN TABLE t1
          169  +  `--SEARCH TABLE t2 USING INDEX i3 (c=?)
   172    170   }
   173         -do_execsql_test indexedby-4.2 {
   174         -  EXPLAIN QUERY PLAN SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c 
          171  +do_eqp_test indexedby-4.2 {
          172  +  SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c 
   175    173   } {
   176         -  0 0 1 {SCAN TABLE t2} 
   177         -  0 1 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
          174  +  QUERY PLAN
          175  +  |--SCAN TABLE t2
          176  +  `--SEARCH TABLE t1 USING INDEX i1 (a=?)
   178    177   }
   179    178   do_test indexedby-4.3 {
   180    179     catchsql {
   181    180       SELECT * FROM t1 INDEXED BY i1, t2 INDEXED BY i3 WHERE a=c
   182    181     }
   183    182   } {1 {no query solution}}
   184    183   do_test indexedby-4.4 {
................................................................................
   190    189   # Test embedding an INDEXED BY in a CREATE VIEW statement. This block
   191    190   # also tests that nothing bad happens if an index refered to by
   192    191   # a CREATE VIEW statement is dropped and recreated.
   193    192   #
   194    193   do_execsql_test indexedby-5.1 {
   195    194     CREATE VIEW v2 AS SELECT * FROM t1 INDEXED BY i1 WHERE a > 5;
   196    195     EXPLAIN QUERY PLAN SELECT * FROM v2 
   197         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
          196  +} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/}
   198    197   do_execsql_test indexedby-5.2 {
   199    198     EXPLAIN QUERY PLAN SELECT * FROM v2 WHERE b = 10 
   200         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
          199  +} {/*SEARCH TABLE t1 USING INDEX i1 (a>?)*/}
   201    200   do_test indexedby-5.3 {
   202    201     execsql { DROP INDEX i1 }
   203    202     catchsql { SELECT * FROM v2 }
   204    203   } {1 {no such index: i1}}
   205    204   do_test indexedby-5.4 {
   206    205     # Recreate index i1 in such a way as it cannot be used by the view query.
   207    206     execsql { CREATE INDEX i1 ON t1(b) }
................................................................................
   212    211     # be used by the query.
   213    212     execsql { DROP INDEX i1 ; CREATE INDEX i1 ON t1(a) }
   214    213     catchsql { SELECT * FROM v2 }
   215    214   } {0 {}}
   216    215   
   217    216   # Test that "NOT INDEXED" may use the rowid index, but not others.
   218    217   # 
   219         -do_execsql_test indexedby-6.1 {
   220         -  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 10 ORDER BY rowid 
   221         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
   222         -do_execsql_test indexedby-6.2 {
   223         -  EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid 
   224         -} {0 0 0 {SCAN TABLE t1}}
          218  +do_eqp_test indexedby-6.1 {
          219  +  SELECT * FROM t1 WHERE b = 10 ORDER BY rowid 
          220  +} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
          221  +do_eqp_test indexedby-6.2 {
          222  +  SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid 
          223  +} {SCAN TABLE t1}
   225    224   
   226    225   # EVIDENCE-OF: R-40297-14464 The INDEXED BY phrase forces the SQLite
   227    226   # query planner to use a particular named index on a DELETE, SELECT, or
   228    227   # UPDATE statement.
   229    228   #
   230    229   # Test that "INDEXED BY" can be used in a DELETE statement.
   231    230   # 
   232         -do_execsql_test indexedby-7.1 {
   233         -  EXPLAIN QUERY PLAN DELETE FROM t1 WHERE a = 5 
   234         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
   235         -do_execsql_test indexedby-7.2 {
   236         -  EXPLAIN QUERY PLAN DELETE FROM t1 NOT INDEXED WHERE a = 5 
   237         -} {0 0 0 {SCAN TABLE t1}}
   238         -do_execsql_test indexedby-7.3 {
   239         -  EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5 
   240         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
   241         -do_execsql_test indexedby-7.4 {
   242         -  EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10
   243         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
   244         -do_execsql_test indexedby-7.5 {
   245         -  EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10
   246         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
          231  +do_eqp_test indexedby-7.1 {
          232  +  DELETE FROM t1 WHERE a = 5 
          233  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
          234  +do_eqp_test indexedby-7.2 {
          235  +  DELETE FROM t1 NOT INDEXED WHERE a = 5 
          236  +} {SCAN TABLE t1}
          237  +do_eqp_test indexedby-7.3 {
          238  +  DELETE FROM t1 INDEXED BY i1 WHERE a = 5 
          239  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
          240  +do_eqp_test indexedby-7.4 {
          241  +  DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10
          242  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
          243  +do_eqp_test indexedby-7.5 {
          244  +  DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10
          245  +} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
   247    246   do_test indexedby-7.6 {
   248    247     catchsql { DELETE FROM t1 INDEXED BY i2 WHERE a = 5}
   249    248   } {1 {no query solution}}
   250    249   
   251    250   # Test that "INDEXED BY" can be used in an UPDATE statement.
   252    251   # 
   253         -do_execsql_test indexedby-8.1 {
   254         -  EXPLAIN QUERY PLAN UPDATE t1 SET rowid=rowid+1 WHERE a = 5 
   255         -} {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}}
   256         -do_execsql_test indexedby-8.2 {
   257         -  EXPLAIN QUERY PLAN UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5 
   258         -} {0 0 0 {SCAN TABLE t1}}
   259         -do_execsql_test indexedby-8.3 {
   260         -  EXPLAIN QUERY PLAN UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 
   261         -} {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}}
   262         -do_execsql_test indexedby-8.4 {
   263         -  EXPLAIN QUERY PLAN 
          252  +do_eqp_test indexedby-8.1 {
          253  +  UPDATE t1 SET rowid=rowid+1 WHERE a = 5 
          254  +} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
          255  +do_eqp_test indexedby-8.2 {
          256  +  UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5 
          257  +} {SCAN TABLE t1}
          258  +do_eqp_test indexedby-8.3 {
          259  +  UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 
          260  +} {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
          261  +do_eqp_test indexedby-8.4 {
   264    262     UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 AND b = 10
   265         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
   266         -do_execsql_test indexedby-8.5 {
   267         -  EXPLAIN QUERY PLAN 
          263  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
          264  +do_eqp_test indexedby-8.5 {
   268    265     UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5 AND b = 10
   269         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?)}}
          266  +} {SEARCH TABLE t1 USING INDEX i2 (b=?)}
   270    267   do_test indexedby-8.6 {
   271    268     catchsql { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5}
   272    269   } {1 {no query solution}}
   273    270   
   274    271   # Test that bug #3560 is fixed.
   275    272   #
   276    273   do_test indexedby-9.1 {
................................................................................
   337    334     SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3';
   338    335   } {1 1 3}
   339    336   do_execsql_test 11.4 {
   340    337     SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0';
   341    338   } {1 1 3}
   342    339   do_eqp_test 11.5 {
   343    340     SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0';
   344         -} {0 0 0 {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)}}
          341  +} {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)}
   345    342   
   346    343   do_execsql_test 11.6 {
   347    344     CREATE TABLE x2(c INTEGER PRIMARY KEY, a, b TEXT);
   348    345     CREATE INDEX x2i ON x2(a, b);
   349    346     INSERT INTO x2 VALUES(1, 1, 1);
   350    347     INSERT INTO x2 VALUES(2, 1, 1);
   351    348     INSERT INTO x2 VALUES(3, 1, 1);
................................................................................
   358    355     SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3';
   359    356   } {1 1 3}
   360    357   do_execsql_test 11.9 {
   361    358     SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
   362    359   } {1 1 3}
   363    360   do_eqp_test 11.10 {
   364    361     SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
   365         -} {0 0 0 {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}}
          362  +} {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}
   366    363   
   367    364   #-------------------------------------------------------------------------
   368    365   # Check INDEXED BY works (throws an exception) with partial indexes that 
   369    366   # cannot be used.
   370    367   do_execsql_test 12.1 {
   371    368     CREATE TABLE o1(x INTEGER PRIMARY KEY, y, z);
   372    369     CREATE INDEX p1 ON o1(z);

Changes to test/indexexpr2.test.

    87     87   
    88     88   ifcapable json1 {
    89     89     do_eqp_test 3.3.1 {
    90     90       SELECT json_extract(x, '$.b') FROM t2 
    91     91       WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL 
    92     92       GROUP BY json_extract(x, '$.b') COLLATE nocase
    93     93       ORDER BY json_extract(x, '$.b') COLLATE nocase;
    94         -  } {
    95         -    0 0 0 {SCAN TABLE t2} 
    96         -    0 0 0 {USE TEMP B-TREE FOR GROUP BY}
    97         -  }
           94  +  } [string map {"\n  " \n} {
           95  +    QUERY PLAN
           96  +    |--SCAN TABLE t2
           97  +    `--USE TEMP B-TREE FOR GROUP BY
           98  +  }]
    98     99     
    99    100     do_execsql_test 3.3.2 {
   100    101       CREATE INDEX i3 ON t3(json_extract(x, '$.a'), json_extract(x, '$.b'));
   101    102     } {}
   102    103     
   103    104     do_eqp_test 3.3.3 {
   104    105       SELECT json_extract(x, '$.b') FROM t3 
   105    106       WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL 
   106    107       GROUP BY json_extract(x, '$.b') COLLATE nocase
   107    108       ORDER BY json_extract(x, '$.b') COLLATE nocase;
   108         -  } {
   109         -    0 0 0 {SEARCH TABLE t3 USING INDEX i3 (<expr>=?)} 
   110         -    0 0 0 {USE TEMP B-TREE FOR GROUP BY}
   111         -  }
          109  +  } [string map {"\n  " \n} {
          110  +    QUERY PLAN
          111  +    |--SEARCH TABLE t3 USING INDEX i3 (<expr>=?)
          112  +    `--USE TEMP B-TREE FOR GROUP BY
          113  +  }]
   112    114   }
   113    115   
   114    116   do_execsql_test 3.4.0 {
   115    117     CREATE TABLE t4(a, b);
   116    118     INSERT INTO t4 VALUES('.ABC', 1);
   117    119     INSERT INTO t4 VALUES('.abc', 2);
   118    120     INSERT INTO t4 VALUES('.ABC', 3);

Changes to test/join2.test.

   108    108     CREATE TABLE t3_1(k3 PRIMARY KEY, v3) WITHOUT ROWID;
   109    109     CREATE TABLE t3_2(v3, k3 PRIMARY KEY) WITHOUT ROWID;
   110    110   }
   111    111   
   112    112   do_eqp_test 3.1 {
   113    113     SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_1 USING (k3);
   114    114   } {
   115         -  0 0 0 {SCAN TABLE t1} 
   116         -  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
          115  +  QUERY PLAN
          116  +  |--SCAN TABLE t1
          117  +  `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
   117    118   }
   118    119   
   119    120   do_eqp_test 3.2 {
   120    121     SELECT v2 FROM t1 LEFT JOIN t2 USING (k2) LEFT JOIN t3_2 USING (k3);
   121    122   } {
   122         -  0 0 0 {SCAN TABLE t1} 
   123         -  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)}
          123  +  QUERY PLAN
          124  +  |--SCAN TABLE t1
          125  +  `--SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)
   124    126   }
   125    127   
   126    128   #-------------------------------------------------------------------------
   127    129   # Test that tables other than the rightmost can be omitted from a
   128    130   # LEFT JOIN query.
   129    131   #
   130    132   do_execsql_test 4.0 {
................................................................................
   154    156   do_execsql_test 4.1.4 {
   155    157     SELECT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1);
   156    158   } {2 v3 2 v3 1112 {} 1112 {}}
   157    159   
   158    160   do_eqp_test 4.1.5 {
   159    161     SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2);
   160    162   } {
   161         -  0 0 0 {SCAN TABLE c1} 
   162         -  0 1 1 {SEARCH TABLE c2 USING INTEGER PRIMARY KEY (rowid=?)}
   163         -  0 2 2 {SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)}
          163  +  QUERY PLAN
          164  +  |--SCAN TABLE c1
          165  +  |--SEARCH TABLE c2 USING INTEGER PRIMARY KEY (rowid=?)
          166  +  `--SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)
   164    167   }
   165    168   do_eqp_test 4.1.6 {
   166    169     SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1);
   167    170   } {
   168         -  0 0 0 {SCAN TABLE c1} 
   169         -  0 1 2 {SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)}
          171  +  QUERY PLAN
          172  +  |--SCAN TABLE c1
          173  +  `--SEARCH TABLE c3 USING INTEGER PRIMARY KEY (rowid=?)
   170    174   }
   171    175   
   172    176   do_execsql_test 4.2.0 {
   173    177     DROP TABLE c1;
   174    178     DROP TABLE c2;
   175    179     DROP TABLE c3;
   176    180     CREATE TABLE c1(k UNIQUE, v1);
................................................................................
   199    203   do_execsql_test 4.2.4 {
   200    204     SELECT v1, v3 FROM c1 LEFT JOIN c2 LEFT JOIN c3 ON (c3.k=v1+1);
   201    205   } {2 v3 2 v3 1112 {} 1112 {}}
   202    206   
   203    207   do_eqp_test 4.2.5 {
   204    208     SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v2);
   205    209   } {
   206         -  0 0 0 {SCAN TABLE c1} 
   207         -  0 1 1 {SEARCH TABLE c2 USING INDEX sqlite_autoindex_c2_1 (k=?)}
   208         -  0 2 2 {SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)}
          210  +  QUERY PLAN
          211  +  |--SCAN TABLE c1
          212  +  |--SEARCH TABLE c2 USING INDEX sqlite_autoindex_c2_1 (k=?)
          213  +  `--SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)
   209    214   }
   210    215   do_eqp_test 4.2.6 {
   211    216     SELECT v1, v3 FROM c1 LEFT JOIN c2 ON (c2.k=v1) LEFT JOIN c3 ON (c3.k=v1+1);
   212    217   } {
   213         -  0 0 0 {SCAN TABLE c1} 
   214         -  0 1 2 {SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)}
          218  +  QUERY PLAN
          219  +  |--SCAN TABLE c1
          220  +  `--SEARCH TABLE c3 USING INDEX sqlite_autoindex_c3_1 (k=?)
   215    221   }
   216    222   
   217    223   # 2017-11-23 (Thanksgiving day)
   218    224   # OSSFuzz found an assertion fault in the new LEFT JOIN eliminator code.
   219    225   #
   220    226   do_execsql_test 4.3.0 {
   221    227     DROP TABLE IF EXISTS t1;
................................................................................
   241    247     CREATE TABLE s1 (a INTEGER PRIMARY KEY);
   242    248     CREATE TABLE s2 (a INTEGER PRIMARY KEY);
   243    249     CREATE TABLE s3 (a INTEGER);
   244    250     CREATE UNIQUE INDEX ndx on s3(a);
   245    251   }
   246    252   do_eqp_test 5.1 {
   247    253     SELECT s1.a FROM s1 left join s2 using (a);
   248         -} {
   249         -  0 0 0 {SCAN TABLE s1}
   250         -}
          254  +} {SCAN TABLE s1}
          255  +
   251    256   do_eqp_test 5.2 {
   252    257     SELECT s1.a FROM s1 left join s3 using (a);
   253         -} {
   254         -  0 0 0 {SCAN TABLE s1}
   255         -}
          258  +} {SCAN TABLE s1}
   256    259   
   257    260   do_execsql_test 6.0 {
   258    261     CREATE TABLE u1(a INTEGER PRIMARY KEY, b, c);
   259    262     CREATE TABLE u2(a INTEGER PRIMARY KEY, b, c);
   260    263     CREATE INDEX u1ab ON u1(b, c);
   261    264   }
   262    265   do_eqp_test 6.1 {
   263    266     SELECT u2.* FROM u2 LEFT JOIN u1 ON( u1.a=u2.a AND u1.b=u2.b AND u1.c=u2.c );
   264         -} {
   265         -  0 0 0 {SCAN TABLE u2}
   266         -}
          267  +} {SCAN TABLE u2}
   267    268   
   268    269   db close
   269    270   sqlite3 db :memory:
   270    271   do_execsql_test 7.0 {
   271    272     CREATE TABLE t1(a,b);  INSERT INTO t1 VALUES(1,2),(3,4),(5,6);
   272    273     CREATE TABLE t2(c,d);  INSERT INTO t2 VALUES(2,4),(3,6);
   273    274     CREATE TABLE t3(x);    INSERT INTO t3 VALUES(9);

Changes to test/join5.test.

   260    260   }
   261    261   
   262    262   do_eqp_test 7.2 {
   263    263     SELECT * FROM t1 LEFT JOIN t2 ON (
   264    264       t2.x = t1.x AND (t2.y=? OR (t2.y=? AND t2.z IS NOT NULL))
   265    265     );
   266    266   } {
   267         -  0 0 0 {SCAN TABLE t1} 
   268         -  0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)} 
   269         -  0 1 1 {SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)}
          267  +  QUERY PLAN
          268  +  |--SCAN TABLE t1
          269  +  `--MULTI-INDEX OR
          270  +     |--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)
          271  +     `--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)
   270    272   }
   271    273   
   272    274   do_execsql_test 7.3 {
   273    275     CREATE TABLE t3(x);
   274    276   
   275    277     CREATE TABLE t4(x, y, z);
   276    278     CREATE INDEX t4xy ON t4(x, y);
................................................................................
   281    283   
   282    284     ANALYZE;
   283    285   }
   284    286   
   285    287   do_eqp_test 7.4 {
   286    288     SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
   287    289   } {
   288         -  0 0 0 {SCAN TABLE t3} 
   289         -  0 1 1 {SEARCH TABLE t4 USING INDEX t4xz (x=?)}
          290  +  QUERY PLAN
          291  +  |--SCAN TABLE t3
          292  +  `--SEARCH TABLE t4 USING INDEX t4xz (x=?)
   290    293   } 
   291    294   
   292    295   finish_test
   293         -

Changes to test/mallocK.test.

   117    117   
   118    118     SELECT 'x' > '.';
   119    119   } {1}
   120    120   
   121    121   ifcapable stat4 {
   122    122     do_eqp_test 6.1 {
   123    123       SELECT DISTINCT c FROM t3 WHERE b BETWEEN '.xx..' AND '.xxxx';
   124         -  } {
   125         -    0 0 0 {SEARCH TABLE t3 USING INDEX i3 (ANY(a) AND b>? AND b<?)} 
   126         -    0 0 0 {USE TEMP B-TREE FOR DISTINCT}
   127         -  }
          124  +  } [string map {"\n  " \n} {
          125  +    QUERY PLAN
          126  +    |--SEARCH TABLE t3 USING INDEX i3 (ANY(a) AND b>? AND b<?)
          127  +    `--USE TEMP B-TREE FOR DISTINCT
          128  +  }]
   128    129   }
   129    130   
   130    131   do_faultsim_test 6 -faults oom* -body {
   131    132     db cache flush
   132    133     db eval { SELECT DISTINCT c FROM t3 WHERE b BETWEEN '.xx..' AND '.xxxx' }
   133    134   } -test {
   134    135     faultsim_test_result {0 {12 13 14 15}} 

Changes to test/orderby1.test.

   450    450       
   451    451       SELECT b, y FROM t41 CROSS JOIN t42 ON x=a ORDER BY b, y;
   452    452     }
   453    453   } {1 13 1 14 1 15 1 16}
   454    454   
   455    455   # No sorting of queries that omit the FROM clause.
   456    456   #
   457         -do_execsql_test 5.0 {
   458         -  EXPLAIN QUERY PLAN SELECT 5 ORDER BY 1
   459         -} {}
          457  +do_eqp_test 5.0 {
          458  +  SELECT 5 ORDER BY 1
          459  +} {
          460  +  QUERY PLAN
          461  +  `--SCAN CONSTANT ROW
          462  +}
   460    463   do_execsql_test 5.1 {
   461    464     EXPLAIN QUERY PLAN SELECT 5 UNION ALL SELECT 3 ORDER BY 1
   462    465   } {~/B-TREE/}
   463    466   do_execsql_test 5.2 {
   464    467     SELECT 5 UNION ALL SELECT 3 ORDER BY 1
   465    468   } {3 5}
   466    469   do_execsql_test 5.3 {
................................................................................
   508    511     CREATE TABLE t1(a, b);
   509    512     CREATE INDEX i1 ON t1(a);
   510    513   }
   511    514   
   512    515   do_eqp_test 8.1 {
   513    516     SELECT * FROM t1 ORDER BY a, b;
   514    517   } {
   515         -  0 0 0 {SCAN TABLE t1 USING INDEX i1} 
   516         -  0 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
          518  +  QUERY PLAN
          519  +  |--SCAN TABLE t1 USING INDEX i1
          520  +  `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
   517    521   }
   518    522   
   519    523   do_execsql_test 8.2 {
   520    524     WITH cnt(i) AS (
   521    525       SELECT 1 UNION ALL SELECT i+1 FROM cnt WHERE i<10000
   522    526     )
   523    527     INSERT INTO t1 SELECT i%2, randomblob(500) FROM cnt;
................................................................................
   539    543     CREATE TABLE t1(x INTEGER PRIMARY KEY);
   540    544     INSERT INTO t1 VALUES(1),(2);
   541    545     DROP TABLE IF EXISTS t2;
   542    546     CREATE TABLE t2(y);
   543    547     INSERT INTO t2 VALUES(9),(8),(3),(4);
   544    548     SELECT (SELECT x||y FROM t2, t1 ORDER BY x, y);
   545    549   } {13}
          550  +
          551  +# Problem found by OSSFuzz on 2018-05-05.  This was caused by a new
          552  +# optimization that had not been previously released.
          553  +#
          554  +do_execsql_test 10.0 {
          555  +  CREATE TABLE t10(a,b);
          556  +  INSERT INTO t10 VALUES(1,2),(8,9),(3,4),(5,4),(0,7);
          557  +  CREATE INDEX t10b ON t10(b);
          558  +  SELECT b, rowid, '^' FROM t10 ORDER BY b, a LIMIT 4;
          559  +} {2 1 ^ 4 3 ^ 4 4 ^ 7 5 ^}
   546    560   
   547    561   
   548    562   finish_test

Changes to test/pager1.test.

  1145   1145   do_test pager1-5.5.1 {
  1146   1146     sqlite3 db test.db
  1147   1147     execsql { 
  1148   1148       ATTACH 'test.db2' AS aux;
  1149   1149       PRAGMA journal_mode = PERSIST;
  1150   1150       CREATE TABLE t3(a, b);
  1151   1151       INSERT INTO t3 SELECT randomblob(1500), randomblob(1500) FROM t1;
  1152         -    UPDATE t3 SET b = randomblob(1500);
         1152  +    UPDATE t3 SET b = randomblob(1501);
  1153   1153     }
  1154   1154     expr [file size test.db-journal] > 15000
  1155   1155   } {1}
  1156   1156   do_test pager1-5.5.2 {
  1157   1157     execsql {
  1158   1158       PRAGMA synchronous = full;
  1159   1159       BEGIN;

Added test/resetdb.test.

            1  +# 2018-04-28
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# Test cases for SQLITE_DBCONFIG_RESET_DATABASE
           12  +#
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +set testprefix resetdb
           17  +
           18  +ifcapable !vtab||!compound {
           19  +  finish_test
           20  +  return
           21  +}
           22  +
           23  +# Create a sample database
           24  +do_execsql_test 100 {
           25  +  PRAGMA page_size=4096;
           26  +  CREATE TABLE t1(a,b);
           27  +  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20)
           28  +    INSERT INTO t1(a,b) SELECT x, randomblob(300) FROM c;
           29  +  CREATE INDEX t1a ON t1(a);
           30  +  CREATE INDEX t1b ON t1(b);
           31  +  SELECT sum(a), sum(length(b)) FROM t1;
           32  +  PRAGMA integrity_check;
           33  +  PRAGMA journal_mode;
           34  +  PRAGMA page_count;
           35  +} {210 6000 ok delete 8}
           36  +
           37  +# Verify that the same content is seen from a separate database connection
           38  +sqlite3 db2 test.db
           39  +do_test 110 {
           40  +  execsql {
           41  +    SELECT sum(a), sum(length(b)) FROM t1;
           42  +    PRAGMA integrity_check;
           43  +    PRAGMA journal_mode;
           44  +    PRAGMA page_count;
           45  +  } db2
           46  +} {210 6000 ok delete 8}
           47  +
           48  +do_test 200 {
           49  +  # Thoroughly corrupt the database file by overwriting the first
           50  +  # page with randomness.
           51  +  catchsql {
           52  +    UPDATE sqlite_dbpage SET data=randomblob(4096) WHERE pgno=1;
           53  +    PRAGMA quick_check;
           54  +  }
           55  +} {1 {unsupported file format}}
           56  +do_test 201 {
           57  +  catchsql {
           58  +    PRAGMA quick_check;
           59  +  } db2
           60  +} {1 {unsupported file format}}
           61  +
           62  +do_test 210 {
           63  +  # Reset the database file using SQLITE_DBCONFIG_RESET_DATABASE
           64  +  sqlite3_db_config db RESET_DB 1
           65  +  db eval VACUUM
           66  +  sqlite3_db_config db RESET_DB 0
           67  +
           68  +  # Verify that the reset took, even on the separate database connection
           69  +  catchsql {
           70  +     PRAGMA page_count;
           71  +     PRAGMA page_size;
           72  +     PRAGMA quick_check;
           73  +     PRAGMA journal_mode;
           74  +  } db2
           75  +} {0 {1 4096 ok delete}}
           76  +
           77  +# Delete the old connections and database and start over again
           78  +# with a different page size and in WAL mode.
           79  +#
           80  +db close
           81  +db2 close
           82  +forcedelete test.db
           83  +sqlite3 db test.db
           84  +do_execsql_test 300 {
           85  +  PRAGMA page_size=8192;
           86  +  PRAGMA journal_mode=WAL;
           87  +  CREATE TABLE t1(a,b);
           88  +  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20)
           89  +    INSERT INTO t1(a,b) SELECT x, randomblob(1300) FROM c;
           90  +  CREATE INDEX t1a ON t1(a);
           91  +  CREATE INDEX t1b ON t1(b);
           92  +  SELECT sum(a), sum(length(b)) FROM t1;
           93  +  PRAGMA integrity_check;
           94  +  PRAGMA journal_mode;
           95  +  PRAGMA page_size;
           96  +  PRAGMA page_count;
           97  +} {wal 210 26000 ok wal 8192 12}
           98  +sqlite3 db2 test.db
           99  +do_test 310 {
          100  +  execsql {
          101  +    SELECT sum(a), sum(length(b)) FROM t1;
          102  +    PRAGMA integrity_check;
          103  +    PRAGMA journal_mode;
          104  +    PRAGMA page_size;
          105  +    PRAGMA page_count;
          106  +  } db2
          107  +} {210 26000 ok wal 8192 12}
          108  +
          109  +# Corrupt the database again
          110  +do_catchsql_test 320 {
          111  +  UPDATE sqlite_dbpage SET data=randomblob(8192) WHERE pgno=1;
          112  +  PRAGMA quick_check
          113  +} {1 {file is not a database}}
          114  +
          115  +do_test 330 {
          116  +  catchsql {
          117  +    PRAGMA quick_check
          118  +  } db2
          119  +} {1 {file is not a database}}
          120  +
          121  +# Reset the database yet again.  Verify that the page size and
          122  +# journal mode are preserved.
          123  +#
          124  +do_test 400 {
          125  +  sqlite3_db_config db RESET_DB 1
          126  +  db eval VACUUM
          127  +  sqlite3_db_config db RESET_DB 0
          128  +  catchsql {
          129  +     PRAGMA page_count;
          130  +     PRAGMA page_size;
          131  +     PRAGMA journal_mode;
          132  +     PRAGMA quick_check;
          133  +  } db2
          134  +} {0 {1 8192 wal ok}}
          135  +db2 close
          136  +
          137  +
          138  +finish_test

Changes to test/rollback2.test.

    97     97   }
    98     98   
    99     99   #--------------------------------------------------------------------
   100    100   # Try with some index scans
   101    101   #
   102    102   do_eqp_test 3.1 {
   103    103     SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h DESC;
   104         -} {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
          104  +} {SCAN TABLE t1 USING INDEX i1}
   105    105   do_rollback_test 3.2 -setup {
   106    106     BEGIN;
   107    107       DELETE FROM t1 WHERE (i%2)==1;
   108    108   } -select {
   109    109     SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h DESC;
   110    110   } -result {
   111    111     40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10  8  6  4  2
................................................................................
   127    127   # Now with some index scans that feature overflow keys.
   128    128   #
   129    129   set leader [string repeat "abcdefghij" 70]
   130    130   do_execsql_test 4.1 { UPDATE t1 SET h = $leader || h; }
   131    131   
   132    132   do_eqp_test 4.2 {
   133    133     SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h ASC;
   134         -} {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
          134  +} {SCAN TABLE t1 USING INDEX i1}
   135    135   do_rollback_test 4.3 -setup {
   136    136     BEGIN;
   137    137       DELETE FROM t1 WHERE (i%2)==1;
   138    138   } -select {
   139    139     SELECT i FROM t1 WHERE (i%2)==0 ORDER BY h ASC;
   140    140   } -result {
   141    141     2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40

Changes to test/rowvalue.test.

   171    171     INSERT INTO xy VALUES(3, 3, 3);
   172    172     INSERT INTO xy VALUES(4, 4, 4);
   173    173   }
   174    174   
   175    175   
   176    176   foreach {tn sql res eqp} {
   177    177     1 "SELECT * FROM xy WHERE (i, j) IS (2, 2)" {2 2 2} 
   178         -    "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid=?)}"
          178  +    "SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid=?)"
   179    179   
   180    180     2 "SELECT * FROM xy WHERE (k, j) < (2, 3)" {1 1 1 2 2 2}
   181         -    "0 0 0 {SCAN TABLE xy}"
          181  +    "SCAN TABLE xy"
   182    182   
   183    183     3 "SELECT * FROM xy WHERE (i, j) < (2, 3)" {1 1 1 2 2 2}
   184         -    "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid<?)}"
          184  +    "SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid<?)"
   185    185   
   186    186     4 "SELECT * FROM xy WHERE (i, j) > (2, 1)" {2 2 2 3 3 3 4 4 4}
   187         -    "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}"
          187  +    "SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)"
   188    188   
   189    189     5 "SELECT * FROM xy WHERE (i, j) > ('2', 1)" {2 2 2 3 3 3 4 4 4}
   190         -    "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}"
          190  +    "SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)"
   191    191   
   192    192   } {
   193    193     do_eqp_test 7.$tn.1 $sql $eqp
   194    194     do_execsql_test 7.$tn.2 $sql $res
   195    195   }
   196    196   
   197    197   do_execsql_test 8.0 {

Changes to test/rowvalue4.test.

   180    180       INSERT INTO c1(c, d) SELECT a, b FROM c1;
   181    181   
   182    182       CREATE INDEX c1ab ON c1(a, b);
   183    183       CREATE INDEX c1cd ON c1(c, d);
   184    184       ANALYZE;
   185    185     }
   186    186   
   187         -  do_eqp_test 3.1.1 { SELECT * FROM c1 WHERE a=1 AND c=2 } {
   188         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)}
   189         -  }
   190         -  do_eqp_test 3.1.2 { SELECT * FROM c1 WHERE a=1 AND b>'d' AND c=2 } {
   191         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)}
   192         -  }
   193         -  do_eqp_test 3.1.3 { SELECT * FROM c1 WHERE a=1 AND b>'l' AND c=2 } {
   194         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=? AND b>?)}
   195         -  }
   196         -
   197         -  do_eqp_test 3.2.1 { SELECT * FROM c1 WHERE a=1 AND c>1 } {
   198         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c>?)}
   199         -  }
   200         -  do_eqp_test 3.2.2 { SELECT * FROM c1 WHERE a=1 AND c>0 } {
   201         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
   202         -  }
   203         -  do_eqp_test 3.2.3 { SELECT * FROM c1 WHERE a=1 AND c>=1 } {
   204         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
   205         -  }
   206         -  do_eqp_test 3.2.4 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'c') } {
   207         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
   208         -  }
   209         -  do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } {
   210         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1cd ((c,d)>(?,?))}
   211         -  }
   212         -  do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } {
   213         -    0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
   214         -  }
          187  +  do_eqp_test 3.1.1 { SELECT * FROM c1 WHERE a=1 AND c=2 } \
          188  +     {SEARCH TABLE c1 USING INDEX c1cd (c=?)}
          189  +
          190  +  do_eqp_test 3.1.2 { SELECT * FROM c1 WHERE a=1 AND b>'d' AND c=2 } \
          191  +     {SEARCH TABLE c1 USING INDEX c1cd (c=?)}
          192  +
          193  +  do_eqp_test 3.1.3 { SELECT * FROM c1 WHERE a=1 AND b>'l' AND c=2 } \
          194  +     {SEARCH TABLE c1 USING INDEX c1ab (a=? AND b>?)}
          195  +
          196  +  do_eqp_test 3.2.1 { SELECT * FROM c1 WHERE a=1 AND c>1 } \
          197  +     {SEARCH TABLE c1 USING INDEX c1cd (c>?)}
          198  +
          199  +  do_eqp_test 3.2.2 { SELECT * FROM c1 WHERE a=1 AND c>0 } \
          200  +     {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
          201  +
          202  +  do_eqp_test 3.2.3 { SELECT * FROM c1 WHERE a=1 AND c>=1 } \
          203  +     {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
          204  +
          205  +  do_eqp_test 3.2.4 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'c') } \
          206  +     {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
          207  +
          208  +  do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } \
          209  +     {SEARCH TABLE c1 USING INDEX c1cd ((c,d)>(?,?))}
          210  +
          211  +  do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } \
          212  +     {SEARCH TABLE c1 USING INDEX c1ab (a=?)}
          213  +
   215    214   }
   216    215   
   217    216   #------------------------------------------------------------------------
   218    217   
   219    218   do_execsql_test 5.0 {
   220    219     CREATE TABLE d1(x, y);
   221    220     CREATE TABLE d2(a, b, c);
................................................................................
   230    229   }
   231    230   
   232    231   do_eqp_test 5.1 {
   233    232     SELECT * FROM d2 WHERE 
   234    233       (a, b) IN (SELECT x, y FROM d1) AND
   235    234       (c) IN (SELECT y FROM d1)
   236    235   } {
   237         -  0 0 0 {SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)}
   238         -  0 0 0 {EXECUTE LIST SUBQUERY 1} 
   239         -  1 0 0 {SCAN TABLE d1}
   240         -  0 0 0 {EXECUTE LIST SUBQUERY 2} 
   241         -  2 0 0 {SCAN TABLE d1}
          236  +  QUERY PLAN
          237  +  |--SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)
          238  +  |--LIST SUBQUERY
          239  +  |  `--SCAN TABLE d1
          240  +  `--LIST SUBQUERY
          241  +     `--SCAN TABLE d1
   242    242   }
   243    243   
   244    244   do_execsql_test 6.0 {
   245    245     CREATE TABLE e1(a, b, c, d, e);
   246    246     CREATE INDEX e1ab ON e1(a, b);
   247    247     CREATE INDEX e1cde ON e1(c, d, e);
   248    248   }
   249    249   
   250    250   do_eqp_test 6.1 {
   251    251     SELECT * FROM e1 WHERE (a, b) > (?, ?)
   252         -} {
   253         -  0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)>(?,?))}
   254         -}
          252  +} {SEARCH TABLE e1 USING INDEX e1ab ((a,b)>(?,?))}
          253  +
   255    254   do_eqp_test 6.2 {
   256    255     SELECT * FROM e1 WHERE (a, b) < (?, ?)
   257         -} {
   258         -  0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)<(?,?))}
   259         -}
          256  +} {SEARCH TABLE e1 USING INDEX e1ab ((a,b)<(?,?))}
          257  +
   260    258   do_eqp_test 6.3 {
   261    259     SELECT * FROM e1 WHERE c = ? AND (d, e) > (?, ?)
   262         -} {
   263         -  0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?))}
   264         -}
          260  +} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?))}
          261  +
   265    262   do_eqp_test 6.4 {
   266    263     SELECT * FROM e1 WHERE c = ? AND (d, e) < (?, ?)
   267         -} {
   268         -  0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)<(?,?))}
   269         -}
          264  +} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)<(?,?))}
   270    265   
   271    266   do_eqp_test 6.5 {
   272    267     SELECT * FROM e1 WHERE (d, e) BETWEEN (?, ?) AND (?, ?) AND c = ?
   273         -} {
   274         -  0 0 0 
   275         -  {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))}
   276         -}
          268  +} {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))}
   277    269   
   278    270   #-------------------------------------------------------------------------
   279    271   
   280    272   do_execsql_test 7.1 {
   281    273     CREATE TABLE f1(a, b, c);
   282    274     CREATE INDEX f1ab ON f1(a, b);
   283    275   }

Changes to test/scanstatus.test.

   324    324   do_scanstatus_test 5.2.2 { 
   325    325     nLoop 1 nVisit 2 nEst 2.0 zName sqlite_autoindex_t1_1
   326    326     zExplain {SEARCH TABLE t1 USING COVERING INDEX sqlite_autoindex_t1_1 (a=?)}
   327    327   }
   328    328   
   329    329   do_eqp_test 5.3.1 {
   330    330     SELECT count(*) FROM t2 WHERE y = 'j';
   331         -} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}}
          331  +} {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
   332    332   do_execsql_test 5.3.2 {
   333    333     SELECT count(*) FROM t2 WHERE y = 'j';
   334    334   } {19}
   335    335   do_scanstatus_test 5.3.3 { 
   336    336     nLoop 1 nVisit 19 nEst 56.0 zName t2xy zExplain
   337    337     {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
   338    338   }
   339    339   
   340    340   do_eqp_test 5.4.1 {
   341    341     SELECT count(*) FROM t1, t2 WHERE y = c;
   342    342   } {
   343         -  0 0 0 {SCAN TABLE t1 USING COVERING INDEX t1bc}
   344         -  0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
          343  +  QUERY PLAN
          344  +  |--SCAN TABLE t1 USING COVERING INDEX t1bc
          345  +  `--SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)
   345    346   }
   346    347   do_execsql_test 5.4.2 {
   347    348     SELECT count(*) FROM t1, t2 WHERE y = c;
   348    349   } {200}
   349    350   do_scanstatus_test 5.4.3 { 
   350    351     nLoop 1 nVisit 10 nEst 10.0 zName t1bc 
   351    352     zExplain {SCAN TABLE t1 USING COVERING INDEX t1bc}
................................................................................
   352    353     nLoop 10 nVisit 200 nEst 56.0 zName t2xy 
   353    354     zExplain {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)}
   354    355   }
   355    356   
   356    357   do_eqp_test 5.5.1 {
   357    358     SELECT count(*) FROM t1, t3 WHERE y = c;
   358    359   } {
   359         -  0 0 1 {SCAN TABLE t3} 
   360         -  0 1 0 {SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?)}
          360  +  QUERY PLAN
          361  +  |--SCAN TABLE t3
          362  +  `--SEARCH TABLE t1 USING AUTOMATIC COVERING INDEX (c=?)
   361    363   }
   362    364   do_execsql_test 5.5.2 {
   363    365     SELECT count(*) FROM t1, t3 WHERE y = c;
   364    366   } {200}
   365    367   do_scanstatus_test 5.5.3 { 
   366    368     nLoop 1 nVisit 501 nEst 480.0 zName t3 zExplain {SCAN TABLE t3}
   367    369     nLoop 501 nVisit 200 nEst 20.0 zName auto-index zExplain

Changes to test/selectA.test.

  1332   1332   
  1333   1333   do_eqp_test 4.1.2 {
  1334   1334     SELECT c, d FROM t5 
  1335   1335     UNION ALL
  1336   1336     SELECT a, b FROM t4 WHERE f()==f()
  1337   1337     ORDER BY 1,2
  1338   1338   } {
  1339         -  1 0 0 {SCAN TABLE t5 USING INDEX i2} 
  1340         -  1 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
  1341         -  2 0 0 {SCAN TABLE t4 USING INDEX i1} 
  1342         -  2 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY}
  1343         -  0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
         1339  +  QUERY PLAN
         1340  +  `--MERGE (UNION ALL)
         1341  +     |--LEFT
         1342  +     |  |--SCAN TABLE t5 USING INDEX i2
         1343  +     |  `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
         1344  +     `--RIGHT
         1345  +        |--SCAN TABLE t4 USING INDEX i1
         1346  +        `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
  1344   1347   }
  1345   1348   
  1346   1349   do_execsql_test 4.1.3 {
  1347   1350     SELECT c, d FROM t5 
  1348   1351     UNION ALL
  1349   1352     SELECT a, b FROM t4 WHERE f()==f()
  1350   1353     ORDER BY 1,2

Changes to test/selectD.test.

   165    165     SELECT * 
   166    166      FROM t41
   167    167      LEFT JOIN (SELECT count(*) AS cnt, x1.d
   168    168                   FROM (t42 INNER JOIN t43 ON d=g) AS x1
   169    169                  WHERE x1.d>5
   170    170                  GROUP BY x1.d) AS x2
   171    171                     ON t41.b=x2.d;
   172         -} {/.*SEARCH SUBQUERY 1 AS x2 USING AUTOMATIC.*/}
          172  +} {/*SEARCH SUBQUERY 0x* AS x2 USING AUTOMATIC*/}
   173    173   
   174    174   finish_test

Changes to test/shell1.test.

   252    252   } {0 {}}
   253    253   do_test shell1-3.1.3 {
   254    254     catchcmd "test.db" ".backup FOO BAR"
   255    255   } {1 {Error: unknown database FOO}}
   256    256   do_test shell1-3.1.4 {
   257    257     # too many arguments
   258    258     catchcmd "test.db" ".backup FOO BAR BAD"
   259         -} {1 {too many arguments to .backup}}
          259  +} {1 {Usage: .backup ?DB? ?--append? FILENAME}}
   260    260   
   261    261   # .bail ON|OFF           Stop after hitting an error.  Default OFF
   262    262   do_test shell1-3.2.1 {
   263    263     catchcmd "test.db" ".bail"
   264    264   } {1 {Usage: .bail on|off}}
   265    265   do_test shell1-3.2.2 {
   266    266     catchcmd "test.db" ".bail ON"

Changes to test/skipscan2.test.

   195    195     for {set i 0} {$i < 1000} {incr i} {
   196    196       execsql { INSERT INTO t3 VALUES($i%2, $i, 'xyz') }
   197    197     }
   198    198     execsql { ANALYZE }
   199    199   } {}
   200    200   do_eqp_test skipscan2-3.3eqp {
   201    201     SELECT * FROM t3 WHERE b=42;
   202         -} {0 0 0 {SEARCH TABLE t3 USING PRIMARY KEY (ANY(a) AND b=?)}}
          202  +} {SEARCH TABLE t3 USING PRIMARY KEY (ANY(a) AND b=?)}
   203    203   
   204    204   
   205    205   finish_test

Changes to test/skipscan6.test.

   175    175     t3 t3_ba   {100 20 1 1}
   176    176   }
   177    177   
   178    178   # Use index "t3_a", as (a=?) is expected to match only a single row.
   179    179   #
   180    180   do_eqp_test 3.1 {
   181    181     SELECT * FROM t3 WHERE a = ? AND c = ?
   182         -} {
   183         -  0 0 0 {SEARCH TABLE t3 USING INDEX t3_a (a=?)}
   184         -}
          182  +} {SEARCH TABLE t3 USING INDEX t3_a (a=?)}
   185    183   
   186    184   # The same query on table t2. This should use index "t2_a", for the
   187    185   # same reason. At one point though, it was mistakenly using a skip-scan.
   188    186   #
   189    187   do_eqp_test 3.2 {
   190    188     SELECT * FROM t2 WHERE a = ? AND c = ?
   191         -} {
   192         -  0 0 0 {SEARCH TABLE t2 USING INDEX t2_a (a=?)}
   193         -}
   194         -
   195         -finish_test
   196         -
   197         -
   198         -
          189  +} {SEARCH TABLE t2 USING INDEX t2_a (a=?)}
   199    190   
   200    191   finish_test

Changes to test/soak.test.

    63     63     fuzz_malloc.test
    64     64     trans.test
    65     65     corruptC.test
    66     66   }
    67     67   
    68     68   set G(isquick) 1
    69     69   
    70         -set soak_starttime  [clock seconds]
           70  +set soak_starttime  [clock_seconds]
    71     71   set soak_finishtime [expr {$soak_starttime + $TIMEOUT}]
    72     72   
    73     73   # Loop until the timeout is reached or an error occurs.
    74     74   #
    75         -for {set iRun 0} {[clock seconds] < $soak_finishtime} {incr iRun} {
           75  +for {set iRun 0} {[clock_seconds] < $soak_finishtime} {incr iRun} {
    76     76   
    77     77     set iIdx [expr {$iRun % [llength $SOAKTESTS]}]
    78     78     source [file join $testdir [lindex $SOAKTESTS $iIdx]]
    79     79     catch {db close}
    80     80   
    81     81     if {$sqlite_open_file_count>0} {
    82     82       puts "$tail did not close all files: $sqlite_open_file_count"

Changes to test/tester.tcl.

   955    955     uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result]
   956    956   }
   957    957   proc do_timed_execsql_test {testname sql {result {}}} {
   958    958     fix_testname testname
   959    959     uplevel do_test [list $testname] [list "execsql_timed {$sql}"]\
   960    960                                      [list [list {*}$result]]
   961    961   }
          962  +
          963  +# Run an EXPLAIN QUERY PLAN $sql in database "db".  Then rewrite the output
          964  +# as an ASCII-art graph and return a string that is that graph.
          965  +#
          966  +# Hexadecimal literals in the output text are converted into "xxxxxx" since those
          967  +# literals are pointer values that might very from one run of the test to the
          968  +# next, yet we want the output to be consistent.
          969  +#
          970  +proc query_plan_graph {sql} {
          971  +  db eval "EXPLAIN QUERY PLAN $sql" {
          972  +    set dx($id) $detail
          973  +    lappend cx($parent) $id
          974  +  }
          975  +  set a "\n  QUERY PLAN\n"
          976  +  append a [append_graph "  " dx cx 0]
          977  +  return [regsub -all { 0x[A-F0-9]+\y} $a { xxxxxx}]
          978  +}
          979  +
          980  +# Helper routine for [query_plan_graph SQL]:
          981  +#
          982  +# Output rows of the graph that are children of $level.
          983  +#
          984  +#   prefix:  Prepend to every output line
          985  +#
          986  +#   dxname:  Name of an array variable that stores text describe
          987  +#            The description for $id is $dx($id)
          988  +#
          989  +#   cxname:  Name of an array variable holding children of item.
          990  +#            Children of $id are $cx($id)
          991  +#
          992  +#   level:   Render all lines that are children of $level
          993  +# 
          994  +proc append_graph {prefix dxname cxname level} {
          995  +  upvar $dxname dx $cxname cx
          996  +  set a ""
          997  +  set x $cx($level)
          998  +  set n [llength $x]
          999  +  for {set i 0} {$i<$n} {incr i} {
         1000  +    set id [lindex $x $i]
         1001  +    if {$i==$n-1} {
         1002  +      set p1 "`--"
         1003  +      set p2 "   "
         1004  +    } else {
         1005  +      set p1 "|--"
         1006  +      set p2 "|  "
         1007  +    }
         1008  +    append a $prefix$p1$dx($id)\n
         1009  +    if {[info exists cx($id)]} {
         1010  +      append a [append_graph "$prefix$p2" dx cx $id]
         1011  +    }
         1012  +  }
         1013  +  return $a
         1014  +}
         1015  +
         1016  +# Do an EXPLAIN QUERY PLAN test on input $sql with expected results $res
         1017  +#
         1018  +# If $res begins with a "\s+QUERY PLAN\n" then it is assumed to be the 
         1019  +# complete graph which must match the output of [query_plan_graph $sql]
         1020  +# exactly.
         1021  +#
         1022  +# If $res does not begin with "\s+QUERY PLAN\n" then take it is a string
         1023  +# that must be found somewhere in the query plan output.
         1024  +#
   962   1025   proc do_eqp_test {name sql res} {
   963         -  uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res]
         1026  +  if {[regexp {^\s+QUERY PLAN\n} $res]} {
         1027  +    uplevel do_test $name [list [list query_plan_graph $sql]] [list $res]
         1028  +  } else {
         1029  +    if {[string index $res 0]!="/"} {
         1030  +      set res "/*$res*/"
         1031  +    }
         1032  +    uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res]
         1033  +  }
   964   1034   }
         1035  +
   965   1036   
   966   1037   #-------------------------------------------------------------------------
   967   1038   #   Usage: do_select_tests PREFIX ?SWITCHES? TESTLIST
   968   1039   #
   969   1040   # Where switches are:
   970   1041   #
   971   1042   #   -errorformat FMTSTRING

Changes to test/tkt-385a5b56b9.test.

    30     30   
    31     31   do_execsql_test 2.0 {
    32     32     CREATE TABLE t2(x, y NOT NULL);
    33     33     CREATE UNIQUE INDEX t2x ON t2(x);
    34     34     CREATE UNIQUE INDEX t2y ON t2(y);
    35     35   }
    36     36   
    37         -do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } {
    38         -  0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2x}
    39         -}
           37  +do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } \
           38  +  {SCAN TABLE t2 USING COVERING INDEX t2x}
           39  +
           40  +do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } \
           41  +  {SCAN TABLE t2 USING COVERING INDEX t2y}
    40     42   
    41         -do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } {
    42         -  0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2y}
    43         -}
           43  +do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } \
           44  +  {SEARCH TABLE t2 USING INDEX t2y (y=?)}
    44     45   
    45         -do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } {
    46         -  0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)}
    47         -}
           46  +do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } \
           47  +  {SEARCH TABLE t2 USING INDEX t2x (x=?)}
    48     48   
    49         -do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } {
    50         -  0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x=?)}
    51         -}
    52     49   
    53     50   finish_test

Changes to test/tkt-78e04e52ea.test.

    37     37   } {0 {} {} 0 {} 0 1 x CHAR(100) 0 {} 0}
    38     38   do_test tkt-78e04-1.3 {
    39     39     execsql {
    40     40       CREATE INDEX i1 ON ""("" COLLATE nocase);
    41     41     }
    42     42   } {}
    43     43   do_test tkt-78e04-1.4 {
    44         -  execsql {
    45         -    EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';
    46         -  }
    47         -} {0 0 0 {SCAN TABLE  USING COVERING INDEX i1}}
           44  + db eval {EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';}
           45  +} {/*SCAN TABLE  USING COVERING INDEX i1*/}
    48     46   do_test tkt-78e04-1.5 {
    49     47     execsql {
    50     48       DROP TABLE "";
    51     49       SELECT name FROM sqlite_master;
    52     50     }
    53     51   } {t2}
    54     52   
    55     53   do_test tkt-78e04-2.1 {
    56     54     execsql {
    57     55       CREATE INDEX "" ON t2(x);
    58     56       EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=5;
    59     57     }
    60         -} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX  (x=?)}}
           58  +} {/*SEARCH TABLE t2 USING COVERING INDEX  (x=?)*/}
    61     59   do_test tkt-78e04-2.2 {
    62     60     execsql {
    63     61       DROP INDEX "";
    64     62       EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=2;
    65     63     }
    66         -} {0 0 0 {SCAN TABLE t2}}
           64  +} {/*SCAN TABLE t2*/}
    67     65   
    68     66   finish_test

Changes to test/tkt-b75a9ca6b0.test.

    28     28     INSERT INTO t1 VALUES (3, 1);
    29     29   }
    30     30   
    31     31   do_execsql_test 1.1 {
    32     32     CREATE INDEX i1 ON t1(x, y);
    33     33   } 
    34     34   
    35         -set idxscan {0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}}
    36         -set tblscan {0 0 0 {SCAN TABLE t1}}
    37         -set grpsort {0 0 0 {USE TEMP B-TREE FOR GROUP BY}}
    38         -set sort    {0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
           35  +set idxscan {SCAN TABLE t1 USING COVERING INDEX i1}
           36  +set tblscan {SCAN TABLE t1}
           37  +set grpsort {USE TEMP B-TREE FOR GROUP BY}
           38  +set sort    {USE TEMP B-TREE FOR ORDER BY}
    39     39   
    40     40   foreach {tn q res eqp} [subst -nocommands {
    41     41     1 "SELECT * FROM t1 GROUP BY x, y ORDER BY x,y"
    42     42     {1 3  2 2  3 1} {$idxscan}
    43     43   
    44     44     2 "SELECT * FROM t1 GROUP BY x, y ORDER BY x"
    45         -  {1 3  2 2  3 1} {$idxscan $sort}
           45  +  {1 3  2 2  3 1} {$idxscan*$sort}
    46     46   
    47     47     3 "SELECT * FROM t1 GROUP BY y, x ORDER BY y, x"
    48         -  {3 1  2 2  1 3} {$idxscan $sort}
           48  +  {3 1  2 2  1 3} {$idxscan*$sort}
    49     49     
    50     50     4 "SELECT * FROM t1 GROUP BY x ORDER BY x"
    51     51     {1 3  2 2  3 1} {$idxscan}
    52     52   
    53     53     5 "SELECT * FROM t1 GROUP BY y ORDER BY y"
    54         -  {3 1  2 2  1 3} {$tblscan $grpsort}
           54  +  {3 1  2 2  1 3} {$tblscan*$grpsort}
    55     55   
    56     56     6 "SELECT * FROM t1 GROUP BY y ORDER BY x"
    57         -  {1 3  2 2  3 1} {$tblscan $grpsort $sort}
           57  +  {1 3  2 2  3 1} {$tblscan*$grpsort*$sort}
    58     58   
    59     59     7 "SELECT * FROM t1 GROUP BY x, y ORDER BY x, y DESC"
    60         -  {1 3  2 2  3 1} {$idxscan $sort}
           60  +  {1 3  2 2  3 1} {$idxscan*$sort}
    61     61   
    62     62     8 "SELECT * FROM t1 GROUP BY x, y ORDER BY x DESC, y DESC"
    63         -  {3 1  2 2  1 3} {$idxscan $sort}
           63  +  {3 1  2 2  1 3} {$idxscan*$sort}
    64     64   
    65     65     9 "SELECT * FROM t1 GROUP BY x, y ORDER BY x ASC, y ASC"
    66     66     {1 3  2 2  3 1} {$idxscan}
    67     67   
    68     68     10 "SELECT * FROM t1 GROUP BY x, y ORDER BY x COLLATE nocase, y"
    69         -  {1 3  2 2  3 1} {$idxscan $sort}
           69  +  {1 3  2 2  3 1} {$idxscan*$sort}
    70     70   
    71     71   }] {
    72     72     do_execsql_test 1.$tn.1 $q $res
    73     73     do_eqp_test     1.$tn.2 $q $eqp
    74     74   }
    75     75   
    76     76   
    77     77   finish_test

Changes to test/tkt3442.test.

    30     30          id TEXT,
    31     31          node INTEGER
    32     32        );
    33     33        CREATE UNIQUE INDEX ididx ON listhash(id);
    34     34     }
    35     35   } {}
    36     36   
    37         -
    38         -# Explain Query Plan
    39         -#
    40         -proc EQP {sql} {
    41         -  uplevel "execsql {EXPLAIN QUERY PLAN $sql}"
    42         -}
    43         -
    44         -
    45     37   # These tests perform an EXPLAIN QUERY PLAN on both versions of the 
    46     38   # SELECT referenced in ticket #3442 (both '5000' and "5000") 
    47     39   # and verify that the query plan is the same.
    48     40   #
    49         -ifcapable explain {
    50         -  do_test tkt3442-1.2 {
    51         -    EQP { SELECT node FROM listhash WHERE id='5000' LIMIT 1; }
    52         -  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
    53         -  do_test tkt3442-1.3 {
    54         -    EQP { SELECT node FROM listhash WHERE id="5000" LIMIT 1; }
    55         -  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
    56         -}
           41  +do_eqp_test tkt3442-1.2 {
           42  +  SELECT node FROM listhash WHERE id='5000' LIMIT 1;
           43  +} {SEARCH TABLE listhash USING INDEX ididx (id=?)}
           44  +do_eqp_test tkt3442-1.3 {
           45  +  SELECT node FROM listhash WHERE id="5000" LIMIT 1;
           46  +} {SEARCH TABLE listhash USING INDEX ididx (id=?)}
    57     47   
    58     48   
    59     49   # Some extra tests testing other permutations of 5000.
    60     50   #
    61         -ifcapable explain {
    62         -  do_test tkt3442-1.4 {
    63         -    EQP { SELECT node FROM listhash WHERE id=5000 LIMIT 1; }
    64         -  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?)}}
    65         -}
           51  +do_eqp_test tkt3442-1.4 {
           52  +  SELECT node FROM listhash WHERE id=5000 LIMIT 1;
           53  +} {SEARCH TABLE listhash USING INDEX ididx (id=?)}
           54  +
    66     55   do_test tkt3442-1.5 {
    67     56     catchsql {
    68     57       SELECT node FROM listhash WHERE id=[5000] LIMIT 1;
    69     58     }
    70     59   } {1 {no such column: 5000}}
    71     60   
    72     61   finish_test

Changes to test/tpch01.test.

   161    161                                  and p_type = 'LARGE PLATED STEEL'
   162    162                  ) as all_nations
   163    163          group by
   164    164                  o_year
   165    165          order by
   166    166                  o_year;}]
   167    167     set ::eqpres
   168         -} {/0 0 0 {SEARCH TABLE part USING INDEX bootleg_pti .P_TYPE=..} 0 1 2 {SEARCH TABLE lineitem USING INDEX lpki2 .L_PARTKEY=..}.*/}
          168  +} {/*SEARCH TABLE part USING INDEX bootleg_pti *SEARCH TABLE lineitem USING INDEX lpki2*/}
   169    169   do_test tpch01-1.1b {
   170    170     set ::eqpres
   171    171   } {/.* customer .* nation AS n1 .*/}
   172    172   do_test tpch01-1.1c {
   173    173     set ::eqpres
   174    174   } {/.* supplier .* nation AS n2 .*/}
   175    175   
................................................................................
   183    183       c_custkey = o_custkey    and l_orderkey = o_orderkey
   184    184       and o_orderdate >=  '1994-08-01'    and o_orderdate < date('1994-08-01', '+3 month')
   185    185       and l_returnflag = 'R'    and c_nationkey = n_nationkey
   186    186   group by
   187    187       c_custkey,    c_name,    c_acctbal,    c_phone,    n_name, c_address,    c_comment
   188    188   order by
   189    189       revenue desc;
   190         -} {0 0 1 {SEARCH TABLE orders USING INDEX odi (O_ORDERDATE>? AND O_ORDERDATE<?)} 0 1 0 {SEARCH TABLE customer USING INDEX cpki (C_CUSTKEY=?)} 0 2 3 {SEARCH TABLE nation USING INDEX npki (N_NATIONKEY=?)} 0 3 2 {SEARCH TABLE lineitem USING INDEX lpki (L_ORDERKEY=?)} 0 0 0 {USE TEMP B-TREE FOR GROUP BY} 0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
          190  +} {
          191  +  QUERY PLAN
          192  +  |--SEARCH TABLE orders USING INDEX odi (O_ORDERDATE>? AND O_ORDERDATE<?)
          193  +  |--SEARCH TABLE customer USING INDEX cpki (C_CUSTKEY=?)
          194  +  |--SEARCH TABLE nation USING INDEX npki (N_NATIONKEY=?)
          195  +  |--SEARCH TABLE lineitem USING INDEX lpki (L_ORDERKEY=?)
          196  +  |--USE TEMP B-TREE FOR GROUP BY
          197  +  `--USE TEMP B-TREE FOR ORDER BY
          198  +}
   191    199   
   192    200   finish_test

Changes to test/trigger1.test.

   756    756   #
   757    757   do_execsql_test trigger1-19.0 {
   758    758     CREATE TABLE t19(a INT PRIMARY KEY, b, c)WITHOUT ROWID;
   759    759     INSERT INTO t19(a,b,c) VALUES(1,2,3);
   760    760     CREATE TRIGGER t19r3 BEFORE UPDATE ON t19 BEGIN SELECT new.b; END;
   761    761     UPDATE t19 SET c=b WHERE a=1;
   762    762     SELECT * FROM t19;
          763  +} {1 2 2}
          764  +do_execsql_test trigger1-19.1 {
          765  +  DELETE FROM t19;
          766  +  INSERT INTO t19(a,b,c) VALUES(1,2,3);
          767  +  UPDATE t19 SET c=CASE WHEN b=2 THEN b ELSE b+99 END WHERE a=1;
          768  +  SELECT * FROM t19;
   763    769   } {1 2 2}
   764    770   
   765    771   finish_test

Changes to test/unordered.test.

    36     36     if {$idxmode == "unordered"} {
    37     37       execsql { UPDATE sqlite_stat1 SET stat = stat || ' unordered' }
    38     38     }
    39     39     db close
    40     40     sqlite3 db test.db
    41     41     foreach {tn sql r(ordered) r(unordered)} {
    42     42       1   "SELECT * FROM t1 ORDER BY a"
    43         -        {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
    44         -        {0 0 0 {SCAN TABLE t1} 0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
           43  +        {SCAN TABLE t1 USING INDEX i1}
           44  +        {SCAN TABLE t1*USE TEMP B-TREE FOR ORDER BY}
    45     45       2   "SELECT * FROM t1 WHERE a > 100"
    46         -        {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
    47         -        {0 0 0 {SCAN TABLE t1}}
           46  +        {SEARCH TABLE t1 USING INDEX i1 (a>?)}
           47  +        {SCAN TABLE t1}
    48     48       3   "SELECT * FROM t1 WHERE a = ? ORDER BY rowid"
    49         -        {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
    50         -        {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)} 
    51         -         0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
           49  +        {SEARCH TABLE t1 USING INDEX i1 (a=?)}
           50  +        {SEARCH TABLE t1 USING INDEX i1 (a=?)*USE TEMP B-TREE FOR ORDER BY}
    52     51       4   "SELECT max(a) FROM t1"
    53         -        {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1}}
    54         -        {0 0 0 {SEARCH TABLE t1}}
           52  +        {SEARCH TABLE t1 USING COVERING INDEX i1}
           53  +        {SEARCH TABLE t1}
    55     54       5   "SELECT group_concat(b) FROM t1 GROUP BY a"
    56         -        {0 0 0 {SCAN TABLE t1 USING INDEX i1}}
    57         -        {0 0 0 {SCAN TABLE t1} 0 0 0 {USE TEMP B-TREE FOR GROUP BY}}
           55  +        {SCAN TABLE t1 USING INDEX i1}
           56  +        {SCAN TABLE t1*USE TEMP B-TREE FOR GROUP BY}
    58     57   
    59     58       6   "SELECT * FROM t1 WHERE a = ?"
    60         -        {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
    61         -        {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
           59  +        {SEARCH TABLE t1 USING INDEX i1 (a=?)}
           60  +        {SEARCH TABLE t1 USING INDEX i1 (a=?)}
    62     61       7   "SELECT count(*) FROM t1"
    63         -        {0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}}
    64         -        {0 0 0 {SCAN TABLE t1}}
           62  +        {SCAN TABLE t1 USING COVERING INDEX i1}
           63  +        {SCAN TABLE t1}
    65     64     } {
    66     65       do_eqp_test 1.$idxmode.$tn $sql $r($idxmode)
    67     66     }
    68     67   }
    69     68   
    70     69   finish_test

Changes to test/where3.test.

   231    231     CREATE TABLE t301(a INTEGER PRIMARY KEY,b,c);
   232    232     CREATE INDEX t301c ON t301(c);
   233    233     INSERT INTO t301 VALUES(1,2,3);
   234    234     INSERT INTO t301 VALUES(2,2,3);
   235    235     CREATE TABLE t302(x, y);
   236    236     INSERT INTO t302 VALUES(4,5);
   237    237     ANALYZE;
   238         -  explain query plan SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
          238  +}
          239  +do_eqp_test where3-3.0a {
          240  +  SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
   239    241   } {
   240         -  0 0 0 {SCAN TABLE t302} 
   241         -  0 1 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)}
          242  +  QUERY PLAN
          243  +  |--SCAN TABLE t302
          244  +  `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
   242    245   }
   243         -do_execsql_test where3-3.1 {
   244         -  explain query plan
          246  +do_eqp_test where3-3.1 {
   245    247     SELECT * FROM t301, t302 WHERE t302.x=5 AND t301.a=t302.y;
   246    248   } {
   247         -  0 0 1 {SCAN TABLE t302} 
   248         -  0 1 0 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)}
          249  +  QUERY PLAN
          250  +  |--SCAN TABLE t302
          251  +  `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
   249    252   }
   250    253   do_execsql_test where3-3.2 {
   251    254     SELECT * FROM t301 WHERE c=3 AND a IS NULL;
   252    255   } {}
   253    256   do_execsql_test where3-3.3 {
   254    257     SELECT * FROM t301 WHERE c=3 AND a IS NOT NULL;
   255    258   } {1 2 3 2 2 3}
................................................................................
   304    307                       fk INTEGER DEFAULT NULL, parent INTEGER,
   305    308                       position INTEGER, title LONGVARCHAR,
   306    309                       keyword_id INTEGER, folder_type TEXT,
   307    310                       dateAdded INTEGER, lastModified INTEGER);
   308    311     CREATE INDEX bbb_111 ON bbb (fk, type);
   309    312     CREATE INDEX bbb_222 ON bbb (parent, position);
   310    313     CREATE INDEX bbb_333 ON bbb (fk, lastModified);
   311         -
   312         -  EXPLAIN QUERY PLAN
          314  +}
          315  +do_eqp_test where3-5.0a {
   313    316      SELECT bbb.title AS tag_title 
   314    317        FROM aaa JOIN bbb ON bbb.id = aaa.parent  
   315    318       WHERE aaa.fk = 'constant'
   316    319         AND LENGTH(bbb.title) > 0
   317    320         AND bbb.parent = 4
   318    321       ORDER BY bbb.title COLLATE NOCASE ASC;
   319    322   } {
   320         -  0 0 0 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} 
   321         -  0 1 1 {SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)} 
   322         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          323  +  QUERY PLAN
          324  +  |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
          325  +  |--SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)
          326  +  `--USE TEMP B-TREE FOR ORDER BY
   323    327   }
   324         -do_execsql_test where3-5.1 {
   325         -  EXPLAIN QUERY PLAN
          328  +do_eqp_test where3-5.1 {
   326    329      SELECT bbb.title AS tag_title 
   327    330        FROM aaa JOIN aaa AS bbb ON bbb.id = aaa.parent  
   328    331       WHERE aaa.fk = 'constant'
   329    332         AND LENGTH(bbb.title) > 0
   330    333         AND bbb.parent = 4
   331    334       ORDER BY bbb.title COLLATE NOCASE ASC;
   332    335   } {
   333         -  0 0 0 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} 
   334         -  0 1 1 {SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)} 
   335         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          336  +  QUERY PLAN
          337  +  |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
          338  +  |--SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)
          339  +  `--USE TEMP B-TREE FOR ORDER BY
   336    340   }
   337         -do_execsql_test where3-5.2 {
   338         -  EXPLAIN QUERY PLAN
          341  +do_eqp_test where3-5.2 {
   339    342      SELECT bbb.title AS tag_title 
   340    343        FROM bbb JOIN aaa ON bbb.id = aaa.parent  
   341    344       WHERE aaa.fk = 'constant'
   342    345         AND LENGTH(bbb.title) > 0
   343    346         AND bbb.parent = 4
   344    347       ORDER BY bbb.title COLLATE NOCASE ASC;
   345    348   } {
   346         -  0 0 1 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} 
   347         -  0 1 0 {SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)} 
   348         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          349  +  QUERY PLAN
          350  +  |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
          351  +  |--SEARCH TABLE bbb USING INTEGER PRIMARY KEY (rowid=?)
          352  +  `--USE TEMP B-TREE FOR ORDER BY
   349    353   }
   350         -do_execsql_test where3-5.3 {
   351         -  EXPLAIN QUERY PLAN
          354  +do_eqp_test where3-5.3 {
   352    355      SELECT bbb.title AS tag_title 
   353    356        FROM aaa AS bbb JOIN aaa ON bbb.id = aaa.parent  
   354    357       WHERE aaa.fk = 'constant'
   355    358         AND LENGTH(bbb.title) > 0
   356    359         AND bbb.parent = 4
   357    360       ORDER BY bbb.title COLLATE NOCASE ASC;
   358    361   } {
   359         -  0 0 1 {SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)} 
   360         -  0 1 0 {SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)} 
   361         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          362  +  QUERY PLAN
          363  +  |--SEARCH TABLE aaa USING INDEX aaa_333 (fk=?)
          364  +  |--SEARCH TABLE aaa AS bbb USING INTEGER PRIMARY KEY (rowid=?)
          365  +  `--USE TEMP B-TREE FOR ORDER BY
   362    366   }
   363    367   
   364    368   # Name resolution with NATURAL JOIN and USING
   365    369   #
   366    370   do_test where3-6.setup {
   367    371     db eval {
   368    372       CREATE TABLE t6w(a, w);

Changes to test/where7.test.

 23337  23337         c2 INTEGER,
 23338  23338         c4 INTEGER,
 23339  23339         FOREIGN KEY (c8) REFERENCES t301(c8)
 23340  23340     );
 23341  23341     CREATE INDEX t302_c3 on t302(c3);
 23342  23342     CREATE INDEX t302_c8_c3 on t302(c8, c3);
 23343  23343     CREATE INDEX t302_c5 on t302(c5);
 23344         -  
 23345         -  EXPLAIN QUERY PLAN
        23344  +}
        23345  +do_eqp_test where7-3.2 {
 23346  23346     SELECT t302.c1 
 23347  23347       FROM t302 JOIN t301 ON t302.c8 = +t301.c8
 23348  23348       WHERE t302.c2 = 19571
 23349  23349         AND t302.c3 > 1287603136
 23350  23350         AND (t301.c4 = 1407449685622784
 23351  23351              OR t301.c8 = 1407424651264000)
 23352  23352      ORDER BY t302.c5 LIMIT 200;
 23353  23353   } {
 23354         -  0 0 1 {SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?)} 
 23355         -  0 0 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)} 
 23356         -  0 1 0 {SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)} 
 23357         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
        23354  +  QUERY PLAN
        23355  +  |--MULTI-INDEX OR
        23356  +  |  |--SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?)
        23357  +  |  `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
        23358  +  |--SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)
        23359  +  `--USE TEMP B-TREE FOR ORDER BY
 23358  23360   }
 23359  23361   
 23360  23362   finish_test

Changes to test/where9.test.

   353    353        WHERE t1.a=t3.y OR t1.b=t3.y*11 OR (t1.c=27027 AND round(t1.d)==80)
   354    354       ORDER BY 1, 2, 3
   355    355     }
   356    356   } {1 80 2 1 80 28 1 80 54 1 80 80 2 80 2 2 80 28 2 80 54 2 80 80 scan 1 sort 1}
   357    357   
   358    358   
   359    359   ifcapable explain {
   360         -  do_execsql_test where9-3.1 {
   361         -    EXPLAIN QUERY PLAN
          360  +  do_eqp_test where9-3.1 {
   362    361       SELECT t2.a FROM t1, t2
   363    362       WHERE t1.a=80 AND ((t1.c=t2.c AND t1.d=t2.d) OR t1.f=t2.f)
   364         -  } {
   365         -    0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)} 
   366         -    0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?)} 
   367         -    0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)}
   368         -  }
   369         -  do_execsql_test where9-3.2 {
   370         -    EXPLAIN QUERY PLAN
          363  +  } [string map {"\n  " \n} {
          364  +    QUERY PLAN
          365  +    |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
          366  +    `--MULTI-INDEX OR
          367  +       |--SEARCH TABLE t2 USING INDEX t2d (d=?)
          368  +       `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
          369  +  }]
          370  +  do_eqp_test where9-3.2 {
   371    371       SELECT coalesce(t2.a,9999)
   372    372       FROM t1 LEFT JOIN t2 ON (t1.c+1=t2.c AND t1.d=t2.d) OR (t1.f||'x')=t2.f
   373    373       WHERE t1.a=80
   374         -  } {
   375         -    0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)} 
   376         -    0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?)} 
   377         -    0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)}
   378         -  }
          374  +  } [string map {"\n  " \n} {
          375  +    QUERY PLAN
          376  +    |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
          377  +    `--MULTI-INDEX OR
          378  +       |--SEARCH TABLE t2 USING INDEX t2d (d=?)
          379  +       `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
          380  +  }]
   379    381   } 
   380    382   
   381    383   # Make sure that INDEXED BY and multi-index OR clauses play well with
   382    384   # one another.
   383    385   #
   384    386   do_test where9-4.1 {
   385    387     count_steps {
................................................................................
   442    444       SELECT a FROM t1 INDEXED BY t1d
   443    445        WHERE b>1000
   444    446          AND (c=31031 OR d IS NULL)
   445    447        ORDER BY +a
   446    448     }
   447    449   } {1 {no query solution}}
   448    450   
   449         -ifcapable explain {
   450         -  # The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
   451         -  # the former is an equality test which is expected to return fewer rows.
   452         -  #
   453         -  do_execsql_test where9-5.1 {
   454         -    EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)
   455         -  } {
   456         -    0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?)} 
   457         -    0 0 0 {SEARCH TABLE t1 USING INDEX t1d (d=?)}
   458         -  }
   459         -
   460         -  # In contrast, b=1000 is preferred over any OR-clause.
   461         -  #
   462         -  do_execsql_test where9-5.2 {
   463         -    EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL)
   464         -  } {
   465         -    0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)}
   466         -  }
   467         -
   468         -  # Likewise, inequalities in an AND are preferred over inequalities in
   469         -  # an OR.
   470         -  #
   471         -  do_execsql_test where9-5.3 {
   472         -    EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c>=31031 OR d IS NULL)
   473         -  } {
   474         -    0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>?)}
   475         -  }
          451  +# The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
          452  +# the former is an equality test which is expected to return fewer rows.
          453  +#
          454  +do_eqp_test where9-5.1 {
          455  +  SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)
          456  +} {
          457  +  QUERY PLAN
          458  +  `--MULTI-INDEX OR
          459  +     |--SEARCH TABLE t1 USING INDEX t1c (c=?)
          460  +     `--SEARCH TABLE t1 USING INDEX t1d (d=?)
   476    461   }
          462  +
          463  +# In contrast, b=1000 is preferred over any OR-clause.
          464  +#
          465  +do_eqp_test where9-5.2 {
          466  +  SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL)
          467  +} {SEARCH TABLE t1 USING INDEX t1b (b=?)}
          468  +
          469  +# Likewise, inequalities in an AND are preferred over inequalities in
          470  +# an OR.
          471  +#
          472  +do_eqp_test where9-5.3 {
          473  +  SELECT a FROM t1 WHERE b>1000 AND (c>=31031 OR d IS NULL)
          474  +} {SEARCH TABLE t1 USING INDEX t1b (b>?)}
   477    475   
   478    476   ############################################################################
   479    477   # Make sure OR-clauses work correctly on UPDATE and DELETE statements.
   480    478   
   481    479   do_test where9-6.2.1 {
   482    480     db eval {SELECT count(*) FROM t1 UNION ALL SELECT a FROM t1 WHERE a>=85}
   483    481   } {99 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99}

Changes to test/whereG.test.

    62     62   } {}
    63     63   do_eqp_test whereG-1.1 {
    64     64     SELECT DISTINCT aname
    65     65       FROM album, composer, track
    66     66      WHERE unlikely(cname LIKE '%bach%')
    67     67        AND composer.cid=track.cid
    68     68        AND album.aid=track.aid;
    69         -} {/.*composer.*track.*album.*/}
           69  +} {composer*track*album}
    70     70   do_execsql_test whereG-1.2 {
    71     71     SELECT DISTINCT aname
    72     72       FROM album, composer, track
    73     73      WHERE unlikely(cname LIKE '%bach%')
    74     74        AND composer.cid=track.cid
    75     75        AND album.aid=track.aid;
    76     76   } {{Mass in B Minor, BWV 232}}
................................................................................
   191    191   
   192    192   do_execsql_test 5.1 {
   193    193     CREATE TABLE t1(a, b, c);
   194    194     CREATE INDEX i1 ON t1(a, b);
   195    195   }
   196    196   do_eqp_test 5.1.2 {
   197    197     SELECT * FROM t1 WHERE a>?
   198         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?)}}
          198  +} {SEARCH TABLE t1 USING INDEX i1 (a>?)}
   199    199   do_eqp_test 5.1.3 {
   200    200     SELECT * FROM t1 WHERE likelihood(a>?, 0.9)
   201         -} {0 0 0 {SCAN TABLE t1}}
          201  +} {SCAN TABLE t1}
   202    202   do_eqp_test 5.1.4 {
   203    203     SELECT * FROM t1 WHERE likely(a>?)
   204         -} {0 0 0 {SCAN TABLE t1}}
          204  +} {SCAN TABLE t1}
   205    205   
   206    206   do_test 5.2 {
   207    207     for {set i 0} {$i < 100} {incr i} {
   208    208       execsql { INSERT INTO t1 VALUES('abc', $i, $i); }
   209    209     }
   210    210     execsql { INSERT INTO t1 SELECT 'def', b, c FROM t1; }
   211    211     execsql { ANALYZE }
   212    212   } {}
   213    213   do_eqp_test 5.2.2 {
   214    214     SELECT * FROM t1 WHERE likelihood(b>?, 0.01)
   215         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (ANY(a) AND b>?)}}
          215  +} {SEARCH TABLE t1 USING INDEX i1 (ANY(a) AND b>?)}
   216    216   do_eqp_test 5.2.3 {
   217    217     SELECT * FROM t1 WHERE likelihood(b>?, 0.9)
   218         -} {0 0 0 {SCAN TABLE t1}}
          218  +} {SCAN TABLE t1}
   219    219   do_eqp_test 5.2.4 {
   220    220     SELECT * FROM t1 WHERE likely(b>?)
   221         -} {0 0 0 {SCAN TABLE t1}}
          221  +} {SCAN TABLE t1}
   222    222   
   223    223   do_eqp_test 5.3.1 {
   224    224     SELECT * FROM t1 WHERE a=?
   225         -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
          225  +} {SEARCH TABLE t1 USING INDEX i1 (a=?)}
   226    226   do_eqp_test 5.3.2 {
   227    227     SELECT * FROM t1 WHERE likelihood(a=?, 0.9)
   228         -} {0 0 0 {SCAN TABLE t1}}
          228  +} {SCAN TABLE t1}
   229    229   do_eqp_test 5.3.3 {
   230    230     SELECT * FROM t1 WHERE likely(a=?)
   231         -} {0 0 0 {SCAN TABLE t1}}
          231  +} {SCAN TABLE t1}
   232    232   
   233    233   # 2015-06-18
   234    234   # Ticket [https://www.sqlite.org/see/tktview/472f0742a1868fb58862bc588ed70]
   235    235   #
   236    236   do_execsql_test 6.0 {
   237    237     DROP TABLE IF EXISTS t1;
   238    238     CREATE TABLE t1(i int, x, y, z);

Changes to test/whereI.test.

    25     25     CREATE INDEX i1 ON t1(b);
    26     26     CREATE INDEX i2 ON t1(c);
    27     27   }
    28     28   
    29     29   do_eqp_test 1.1 {
    30     30     SELECT a FROM t1 WHERE b='b' OR c='x'
    31     31   } {
    32         -  0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b=?)} 
    33         -  0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}
           32  +  QUERY PLAN
           33  +  `--MULTI-INDEX OR
           34  +     |--SEARCH TABLE t1 USING INDEX i1 (b=?)
           35  +     `--SEARCH TABLE t1 USING INDEX i2 (c=?)
    34     36   }
    35     37   
    36     38   do_execsql_test 1.2 {
    37     39     SELECT a FROM t1 WHERE b='b' OR c='x'
    38     40   } {2 3}
    39     41   
    40     42   do_execsql_test 1.3 {
................................................................................
    53     55     CREATE INDEX i3 ON t2(b);
    54     56     CREATE INDEX i4 ON t2(c);
    55     57   }
    56     58   
    57     59   do_eqp_test 2.1 {
    58     60     SELECT a FROM t2 WHERE b='b' OR c='x'
    59     61   } {
    60         -  0 0 0 {SEARCH TABLE t2 USING INDEX i3 (b=?)} 
    61         -  0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?)}
           62  +  QUERY PLAN
           63  +  `--MULTI-INDEX OR
           64  +     |--SEARCH TABLE t2 USING INDEX i3 (b=?)
           65  +     `--SEARCH TABLE t2 USING INDEX i4 (c=?)
    62     66   }
    63     67   
    64     68   do_execsql_test 2.2 {
    65     69     SELECT a FROM t2 WHERE b='b' OR c='x'
    66     70   } {ii iii}
    67     71   
    68     72   do_execsql_test 2.3 {

Changes to test/whereJ.test.

   398    398   
   399    399   # This one should use index "idx_c".
   400    400   do_eqp_test 3.4 {
   401    401     SELECT * FROM t1 WHERE 
   402    402       a = 4 AND b BETWEEN 20 AND 80           -- Matches 80 rows
   403    403         AND
   404    404       c BETWEEN 150 AND 160                   -- Matches 10 rows
   405         -} {
   406         -  0 0 0 {SEARCH TABLE t1 USING INDEX idx_c (c>? AND c<?)}
   407         -}
          405  +} {SEARCH TABLE t1 USING INDEX idx_c (c>? AND c<?)}
   408    406   
   409    407   # This one should use index "idx_ab".
   410    408   do_eqp_test 3.5 {
   411    409     SELECT * FROM t1 WHERE 
   412    410       a = 5 AND b BETWEEN 20 AND 80           -- Matches 1 row
   413    411         AND
   414    412       c BETWEEN 150 AND 160                   -- Matches 10 rows
   415         -} {
   416         -  0 0 0 {SEARCH TABLE t1 USING INDEX idx_ab (a=? AND b>? AND b<?)}
   417         -}
          413  +} {SEARCH TABLE t1 USING INDEX idx_ab (a=? AND b>? AND b<?)}
   418    414   
   419    415   ###########################################################################################
   420    416   
   421    417   # Reset the database and setup for a test case derived from actual SQLite users
   422    418   #
   423    419   db close
   424    420   sqlite3 db test.db

Changes to test/wherelimit.test.

    47     47     do_test wherelimit-0.2 {
    48     48       catchsql {DELETE FROM t1 WHERE x=1 ORDER BY x}
    49     49     } {1 {ORDER BY without LIMIT on DELETE}}
    50     50     do_test wherelimit-0.3 {
    51     51       catchsql {UPDATE t1 SET y=1 WHERE x=1 ORDER BY x}
    52     52     } {1 {ORDER BY without LIMIT on UPDATE}}
    53     53   
    54         -  execsql { DROP TABLE t1 }
    55         -
    56     54     # no AS on table sources
           55  +  #
           56  +  # UPDATE: As of version 3.24, AS clauses are allowed as part of
           57  +  # UPDATE or DELETE statements.
    57     58     do_test wherelimit-0.4 {
    58         -    catchsql {DELETE FROM t1 AS a WHERE x=1}
    59         -  } {1 {near "AS": syntax error}}
    60         -  do_test wherelimit-0.5 {
           59  +    catchsql {DELETE FROM t1 AS a WHERE a.x=1}
           60  +  } {0 {}}
           61  +  do_test wherelimit-0.5.1 {
    61     62       catchsql {UPDATE t1 AS a SET y=1 WHERE x=1}
    62         -  } {1 {near "AS": syntax error}}
           63  +  } {0 {}}
           64  +  do_test wherelimit-0.5.2 {
           65  +    catchsql {UPDATE t1 AS a SET y=1 WHERE t1.x=1}
           66  +  } {1 {no such column: t1.x}}
    63     67   
    64     68     # OFFSET w/o LIMIT
    65     69     do_test wherelimit-0.6 {
    66     70       catchsql {DELETE FROM t1 WHERE x=1 OFFSET 2}
    67     71     } {1 {near "OFFSET": syntax error}}
    68     72     do_test wherelimit-0.7 {
    69     73       catchsql {UPDATE t1 SET y=1 WHERE x=1 OFFSET 2}
    70     74     } {1 {near "OFFSET": syntax error}}
    71     75   
           76  +  execsql { DROP TABLE t1 }
    72     77   
    73     78     # check deletes w/o where clauses but with limit/offsets
    74     79     create_test_data 5
    75     80     do_test wherelimit-1.0 {
    76     81       execsql {SELECT count(*) FROM t1}
    77     82     } {25}
    78     83     do_test wherelimit-1.1 {

Changes to test/with1.test.

   988    988       FROM xyz ORDER BY 1
   989    989     )
   990    990     SELECT 1 FROM xyz;
   991    991   } 1
   992    992   
   993    993   # EXPLAIN QUERY PLAN on a self-join of a CTE
   994    994   #
   995         -do_execsql_test 19.1 {
          995  +do_execsql_test 19.1a {
   996    996     DROP TABLE IF EXISTS t1;
   997    997     CREATE TABLE t1(x);
   998         -  EXPLAIN QUERY PLAN
          998  +}
          999  +do_eqp_test 19.1b {
   999   1000     WITH
  1000   1001       x1(a) AS (values(100))
  1001   1002     INSERT INTO t1(x)
  1002   1003       SELECT * FROM (WITH x2(y) AS (SELECT * FROM x1) SELECT y+a FROM x1, x2);
  1003   1004     SELECT * FROM t1;
  1004         -} {0 0 0 {SCAN SUBQUERY 1} 0 1 1 {SCAN SUBQUERY 1}}
         1005  +} {
         1006  +  QUERY PLAN
         1007  +  |--MATERIALIZE xxxxxx
         1008  +  |  `--SCAN CONSTANT ROW
         1009  +  |--SCAN SUBQUERY xxxxxx
         1010  +  `--SCAN SUBQUERY xxxxxx
         1011  +}
  1005   1012   
  1006   1013   # 2017-10-28.
  1007   1014   # See check-in https://sqlite.org/src/info/0926df095faf72c2
  1008   1015   # Tried to optimize co-routine processing by changing a Copy opcode
  1009   1016   # into SCopy.  But OSSFuzz found two (similar) cases where that optimization
  1010   1017   # does not work.
  1011   1018   #

Changes to test/with3.test.

    75     75       ANALYZE;
    76     76   
    77     77     }
    78     78   
    79     79     do_eqp_test 3.1.2 {
    80     80       WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1)
    81     81       SELECT * FROM cnt, y1 WHERE i=a
    82         -  } {
    83         -    3 0 0 {SCAN TABLE cnt} 
    84         -    1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)}
    85         -    0 0 0 {SCAN SUBQUERY 1} 
    86         -    0 1 1 {SEARCH TABLE y1 USING INDEX y1a (a=?)}
    87         -  }
           82  +  } [string map {"\n  " \n} {
           83  +    QUERY PLAN
           84  +    |--MATERIALIZE xxxxxx
           85  +    |  |--SETUP
           86  +    |  |  `--SCAN CONSTANT ROW
           87  +    |  `--RECURSIVE STEP
           88  +    |     `--SCAN TABLE cnt
           89  +    |--SCAN SUBQUERY xxxxxx
           90  +    `--SEARCH TABLE y1 USING INDEX y1a (a=?)
           91  +  }]
    88     92   
    89     93     do_eqp_test 3.1.3 {
    90     94       WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1000000)
    91     95       SELECT * FROM cnt, y1 WHERE i=a
    92         -  } {
    93         -    3 0 0 {SCAN TABLE cnt} 
    94         -    1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)}
    95         -    0 0 1 {SCAN TABLE y1} 
    96         -    0 1 0 {SEARCH SUBQUERY 1 USING AUTOMATIC COVERING INDEX (i=?)}
    97         -  }
           96  +  } [string map {"\n  " \n} {
           97  +    QUERY PLAN
           98  +    |--MATERIALIZE xxxxxx
           99  +    |  |--SETUP
          100  +    |  |  `--SCAN CONSTANT ROW
          101  +    |  `--RECURSIVE STEP
          102  +    |     `--SCAN TABLE cnt
          103  +    |--SCAN TABLE y1
          104  +    `--SEARCH SUBQUERY xxxxxx USING AUTOMATIC COVERING INDEX (i=?)
          105  +  }]
    98    106   }
    99    107   
   100    108   do_execsql_test 3.2.1 {
   101    109     CREATE TABLE w1(pk INTEGER PRIMARY KEY, x INTEGER);
   102    110     CREATE TABLE w2(pk INTEGER PRIMARY KEY);
   103    111   }
   104    112   
   105    113   do_eqp_test 3.2.2 {
   106    114     WITH RECURSIVE c(w,id) AS (SELECT 0, (SELECT pk FROM w2 LIMIT 1)
   107    115        UNION ALL SELECT c.w + 1, x FROM w1, c LIMIT 1)
   108    116        SELECT * FROM c, w2, w1
   109    117        WHERE c.id=w2.pk AND c.id=w1.pk;
   110    118   } {
   111         -  2 0 0 {EXECUTE SCALAR SUBQUERY 3} 
   112         -  3 0 0 {SCAN TABLE w2} 
   113         -  4 0 0 {SCAN TABLE w1}
   114         -  4 1 1 {SCAN TABLE c} 
   115         -  1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} 0 0 0 {SCAN SUBQUERY 1}
   116         -  0 1 1 {SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)} 
   117         -  0 2 2 {SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)}
          119  +  QUERY PLAN
          120  +  |--MATERIALIZE xxxxxx
          121  +  |  |--SETUP
          122  +  |  |  |--SCAN CONSTANT ROW
          123  +  |  |  `--SCALAR SUBQUERY
          124  +  |  |     `--SCAN TABLE w2
          125  +  |  `--RECURSIVE STEP
          126  +  |     |--SCAN TABLE w1
          127  +  |     `--SCAN TABLE c
          128  +  |--SCAN SUBQUERY xxxxxx
          129  +  |--SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)
          130  +  `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)
   118    131   }
   119    132   
   120    133   finish_test

Changes to test/without_rowid1.test.

   234    234     INSERT INTO t45 VALUES(5, 'two', 'x');
   235    235     INSERT INTO t45 VALUES(7, 'two', 'x');
   236    236     INSERT INTO t45 VALUES(9, 'two', 'x');
   237    237   }
   238    238   
   239    239   do_eqp_test 5.1 {
   240    240     SELECT * FROM t45 WHERE b=? AND a>?
   241         -} {/*USING INDEX i45 (b=? AND a>?)*/}
          241  +} {USING INDEX i45 (b=? AND a>?)}
   242    242   
   243    243   do_execsql_test 5.2 {
   244    244     SELECT * FROM t45 WHERE b='two' AND a>4
   245    245   } {5 two x 7 two x 9 two x}
   246    246   
   247    247   do_execsql_test 5.3 {
   248    248     SELECT * FROM t45 WHERE b='one' AND a<8
................................................................................
   253    253     WITH r(x) AS (
   254    254       SELECT 1 UNION ALL SELECT x+1 FROM r WHERE x<100
   255    255     )
   256    256     INSERT INTO t46 SELECT x / 20, x % 20, x % 10, x FROM r;
   257    257   }
   258    258   
   259    259   set queries {
   260         -  1    2    "c = 5 AND a = 1"          {/*i46 (c=? AND a=?)*/}
   261         -  2    6    "c = 4 AND a < 3"          {/*i46 (c=? AND a<?)*/}
   262         -  3    4    "c = 2 AND a >= 3"         {/*i46 (c=? AND a>?)*/}
   263         -  4    1    "c = 2 AND a = 1 AND b<10" {/*i46 (c=? AND a=? AND b<?)*/}
   264         -  5    1    "c = 0 AND a = 0 AND b>5"  {/*i46 (c=? AND a=? AND b>?)*/}
          260  +  1    2    "c = 5 AND a = 1"          {i46 (c=? AND a=?)}
          261  +  2    6    "c = 4 AND a < 3"          {i46 (c=? AND a<?)}
          262  +  3    4    "c = 2 AND a >= 3"         {i46 (c=? AND a>?)}
          263  +  4    1    "c = 2 AND a = 1 AND b<10" {i46 (c=? AND a=? AND b<?)}
          264  +  5    1    "c = 0 AND a = 0 AND b>5"  {i46 (c=? AND a=? AND b>?)}
   265    265   }
   266    266   
   267    267   foreach {tn cnt where eqp} $queries {
   268    268     do_execsql_test 5.5.$tn.1 "SELECT count(*) FROM t46 WHERE $where" $cnt
   269    269   }
   270    270   
   271    271   do_execsql_test 5.6 {