/ Check-in [0f707d15]
Login

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

Overview
Comment:Merge changes from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: 0f707d1532d6c8277cf0f70821a83e0af621ce9b
User & Date: drh 2016-06-15 10:21:06
Context
2016-07-25
17:31
Merge 3.14 alpha changes from trunk. check-in: e98cefb1 user: drh tags: apple-osx
2016-06-15
10:21
Merge changes from trunk. check-in: 0f707d15 user: drh tags: apple-osx
2016-06-13
19:58
Fix RBU so that it builds with -DSQLITE_ENABLE_8_3_NAMES. Fix "PRAGMA compile_options" for SQLITE_ENABLE_8_3_NAMES such that it reports the numeric setting: "1" or "2". check-in: 0230ca17 user: drh tags: trunk
2016-05-23
02:57
Merge changes from trunk. check-in: 815cc2bb user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   416    416     $(TOP)/ext/rbu/test_rbu.c 
   417    417   
   418    418   # Statically linked extensions
   419    419   #
   420    420   TESTSRC += \
   421    421     $(TOP)/ext/misc/amatch.c \
   422    422     $(TOP)/ext/misc/closure.c \
          423  +  $(TOP)/ext/misc/csv.c \
   423    424     $(TOP)/ext/misc/eval.c \
   424    425     $(TOP)/ext/misc/fileio.c \
   425    426     $(TOP)/ext/misc/fuzzer.c \
   426    427     $(TOP)/ext/fts5/fts5_tcl.c \
   427    428     $(TOP)/ext/fts5/fts5_test_mi.c \
   428    429     $(TOP)/ext/fts5/fts5_test_tok.c \
   429    430     $(TOP)/ext/misc/ieee754.c \
................................................................................
   548    549   
   549    550   # executables needed for testing
   550    551   #
   551    552   TESTPROGS = \
   552    553     testfixture$(TEXE) \
   553    554     sqlite3$(TEXE) \
   554    555     sqlite3_analyzer$(TEXE) \
   555         -  sqldiff$(TEXE)
          556  +  sqldiff$(TEXE) \
          557  +  dbhash$(TEXE)
   556    558   
   557    559   # Databases containing fuzzer test cases
   558    560   #
   559    561   FUZZDATA = \
   560    562     $(TOP)/test/fuzzdata1.db \
   561    563     $(TOP)/test/fuzzdata2.db \
   562    564     $(TOP)/test/fuzzdata3.db \
................................................................................
   598    600   	$(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \
   599    601   		$(TOP)/src/shell.c sqlite3.c \
   600    602   		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
   601    603   
   602    604   sqldiff$(TEXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
   603    605   	$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
   604    606   
          607  +dbhash$(TEXE):	$(TOP)/tool/dbhash.c sqlite3.c sqlite3.h
          608  +	$(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.c $(TLIBS)
          609  +
   605    610   scrub$(TEXE):	$(TOP)/ext/misc/scrub.c sqlite3.o
   606    611   	$(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \
   607    612   		$(TOP)/ext/misc/scrub.c sqlite3.o $(TLIBS)
   608    613   
   609    614   srcck1$(BEXE):	$(TOP)/tool/srcck1.c
   610    615   	$(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c
   611    616   
................................................................................
  1259   1264   	rm -f sqlite-*-output.vsix
  1260   1265   	rm -f mptester mptester.exe
  1261   1266   	rm -f rbu rbu.exe
  1262   1267   	rm -f srcck1 srcck1.exe
  1263   1268   	rm -f fuzzershell fuzzershell.exe
  1264   1269   	rm -f fuzzcheck fuzzcheck.exe
  1265   1270   	rm -f sqldiff sqldiff.exe
         1271  +	rm -f dbhash dbhash.exe
  1266   1272   	rm -f fts5.* fts5parse.*
  1267   1273   
  1268   1274   distclean:	clean
  1269   1275   	rm -f config.h config.log config.status libtool Makefile sqlite3.pc
  1270   1276   
  1271   1277   #
  1272   1278   # Windows section

Changes to Makefile.msc.

  1289   1289     $(TOP)\ext\session\test_session.c
  1290   1290   
  1291   1291   # Statically linked extensions.
  1292   1292   #
  1293   1293   TESTEXT = \
  1294   1294     $(TOP)\ext\misc\amatch.c \
  1295   1295     $(TOP)\ext\misc\closure.c \
         1296  +  $(TOP)\ext\misc\csv.c \
  1296   1297     $(TOP)\ext\misc\eval.c \
  1297   1298     $(TOP)\ext\misc\fileio.c \
  1298   1299     $(TOP)\ext\misc\fuzzer.c \
  1299   1300     $(TOP)\ext\fts5\fts5_tcl.c \
  1300   1301     $(TOP)\ext\fts5\fts5_test_mi.c \
  1301   1302     $(TOP)\ext\fts5\fts5_test_tok.c \
  1302   1303     $(TOP)\ext\misc\ieee754.c \
................................................................................
  1373   1374   
  1374   1375   # executables needed for testing
  1375   1376   #
  1376   1377   TESTPROGS = \
  1377   1378     testfixture.exe \
  1378   1379     $(SQLITE3EXE) \
  1379   1380     sqlite3_analyzer.exe \
  1380         -  sqldiff.exe
         1381  +  sqldiff.exe \
         1382  +  dbhash.exe
  1381   1383   
  1382   1384   # Databases containing fuzzer test cases
  1383   1385   #
  1384   1386   FUZZDATA = \
  1385   1387     $(TOP)\test\fuzzdata1.db \
  1386   1388     $(TOP)\test\fuzzdata2.db \
  1387   1389     $(TOP)\test\fuzzdata3.db \
................................................................................
  1451   1453   	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \
  1452   1454   		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1453   1455   
  1454   1456   # <<mark>>
  1455   1457   sqldiff.exe:	$(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H)
  1456   1458   	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1457   1459   
         1460  +dbhash.exe:	$(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
         1461  +	$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1462  +
  1458   1463   scrub.exe:	$(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H)
  1459   1464   	$(LTLINK) $(NO_WARN) $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1460   1465   
  1461   1466   srcck1.exe:	$(TOP)\tool\srcck1.c
  1462   1467   	$(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c
  1463   1468   
  1464   1469   sourcetest:	srcck1.exe sqlite3.c
................................................................................
  2100   2105   	del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
  2101   2106   	del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
  2102   2107   	del /Q sqlite3.c sqlite3-*.c 2>NUL
  2103   2108   	del /Q sqlite3rc.h 2>NUL
  2104   2109   	del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
  2105   2110   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
  2106   2111   	del /Q sqlite-*-output.vsix 2>NUL
  2107         -	del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL
         2112  +	del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
  2108   2113   	del /Q fts5.* fts5parse.* 2>NUL
  2109   2114   # <</mark>>

Changes to autoconf/configure.ac.

    26     26   # Check for library functions that SQLite can optionally use.
    27     27   AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r])
    28     28   AC_FUNC_STRERROR_R
    29     29   
    30     30   AC_CONFIG_FILES([Makefile sqlite3.pc])
    31     31   AC_SUBST(BUILD_CFLAGS)
    32     32   
    33         -#-----------------------------------------------------------------------
           33  +#-------------------------------------------------------------------------
           34  +# Two options to enable readline compatible libraries: 
           35  +#
    34     36   #   --enable-editline
    35     37   #   --enable-readline
    36     38   #
    37         -AC_ARG_ENABLE(editline, [AS_HELP_STRING(
    38         -  [--enable-editline], 
    39         -  [use BSD libedit])], 
    40         -  [], [enable_editline=yes])
    41         -AC_ARG_ENABLE(readline, [AS_HELP_STRING(
    42         -  [--enable-readline], 
    43         -  [use readline])], 
    44         -  [], [enable_readline=yes])
    45         -if test x"$enable_editline" != xno ; then
    46         -  sLIBS=$LIBS
    47         -  LIBS=""
    48         -  AC_SEARCH_LIBS([readline],[edit],[enable_readline=no],[enable_editline=no])
    49         -  READLINE_LIBS=$LIBS
    50         -  if test x"$LIBS" != "x"; then
    51         -    AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline)
    52         -    enable_readline=no
    53         -  else
    54         -    unset ac_cv_search_readline
    55         -  fi
    56         -  LIBS=$sLIBS
    57         -fi
    58         -if test x"$enable_readline" != xno ; then
    59         -  sLIBS=$LIBS
    60         -  LIBS=""
    61         -  AC_SEARCH_LIBS(tgetent, curses ncurses ncursesw, [], [])
    62         -  AC_SEARCH_LIBS(readline, readline, [], [enable_readline=no])
    63         -  AC_CHECK_FUNCS(readline, [], [])
    64         -  READLINE_LIBS=$LIBS
    65         -  LIBS=$sLIBS
    66         -fi
           39  +# Both are enabled by default. If, after command line processing both are
           40  +# still enabled, the script searches for editline first and automatically
           41  +# disables readline if it is found. So, to use readline explicitly, the
           42  +# user must pass "--disable-editline". To disable command line editing
           43  +# support altogether, "--disable-editline --disable-readline".
           44  +#
           45  +# When searching for either library, check for headers before libraries 
           46  +# as some distros supply packages that contain libraries but not header
           47  +# files, which come as a separate development package.
           48  +#
           49  +AC_ARG_ENABLE(editline, [AS_HELP_STRING([--enable-editline],[use BSD libedit])])
           50  +AC_ARG_ENABLE(readline, [AS_HELP_STRING([--enable-readline],[use readline])])
           51  +
           52  +AS_IF([ test x"$enable_editline" != xno ],[
           53  +  AC_CHECK_HEADERS([editline/readline.h],[
           54  +    sLIBS=$LIBS
           55  +    LIBS=""
           56  +    AC_SEARCH_LIBS([readline],[edit],[
           57  +      AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline)
           58  +      READLINE_LIBS=$LIBS
           59  +      enable_readline=no
           60  +    ])
           61  +    AS_UNSET(ac_cv_search_readline)
           62  +    LIBS=$sLIBS
           63  +  ])
           64  +])
           65  +
           66  +AS_IF([ test x"$enable_readline" != xno ],[
           67  +  AC_CHECK_HEADERS([readline/readline.h],[
           68  +    sLIBS=$LIBS
           69  +    LIBS=""
           70  +    AC_SEARCH_LIBS(tgetent, termcap curses ncurses ncursesw, [], [])
           71  +    AC_SEARCH_LIBS(readline,[readline edit], [
           72  +      AC_DEFINE([HAVE_READLINE],1,Define to use readline or wrapper)
           73  +      READLINE_LIBS=$LIBS
           74  +    ])
           75  +    LIBS=$sLIBS
           76  +  ])
           77  +])
           78  +
    67     79   AC_SUBST(READLINE_LIBS)
    68     80   #-----------------------------------------------------------------------
    69     81   
    70     82   #-----------------------------------------------------------------------
    71     83   #   --enable-threadsafe
    72     84   #
    73     85   AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(

Changes to ext/fts5/fts5Int.h.

   682    682   
   683    683   typedef struct Fts5PoslistPopulator Fts5PoslistPopulator;
   684    684   Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr*, int);
   685    685   int sqlite3Fts5ExprPopulatePoslists(
   686    686       Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int
   687    687   );
   688    688   void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
   689         -void sqlite3Fts5ExprClearEof(Fts5Expr*);
   690    689   
   691    690   int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
   692    691   
   693    692   int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
   694    693   
   695    694   /*******************************************
   696    695   ** The fts5_expr.c API above this point is used by the other hand-written

Changes to ext/fts5/fts5_expr.c.

  2613   2613     return 1;
  2614   2614   }
  2615   2615   
  2616   2616   void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){
  2617   2617     fts5ExprCheckPoslists(pExpr->pRoot, iRowid);
  2618   2618   }
  2619   2619   
  2620         -static void fts5ExprClearEof(Fts5ExprNode *pNode){
  2621         -  int i;
  2622         -  for(i=0; i<pNode->nChild; i++){
  2623         -    fts5ExprClearEof(pNode->apChild[i]);
  2624         -  }
  2625         -  pNode->bEof = 0;
  2626         -}
  2627         -void sqlite3Fts5ExprClearEof(Fts5Expr *pExpr){
  2628         -  fts5ExprClearEof(pExpr->pRoot);
  2629         -}
  2630         -
  2631   2620   /*
  2632   2621   ** This function is only called for detail=columns tables. 
  2633   2622   */
  2634   2623   int sqlite3Fts5ExprPhraseCollist(
  2635   2624     Fts5Expr *pExpr, 
  2636   2625     int iPhrase, 
  2637   2626     const u8 **ppCollist, 

Changes to ext/fts5/fts5_main.c.

  1182   1182       assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
  1183   1183       assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
  1184   1184       assert( pCsr->iLastRowid==LARGEST_INT64 );
  1185   1185       assert( pCsr->iFirstRowid==SMALLEST_INT64 );
  1186   1186       pCsr->ePlan = FTS5_PLAN_SOURCE;
  1187   1187       pCsr->pExpr = pTab->pSortCsr->pExpr;
  1188   1188       rc = fts5CursorFirst(pTab, pCsr, bDesc);
  1189         -    sqlite3Fts5ExprClearEof(pCsr->pExpr);
  1190   1189     }else if( pMatch ){
  1191   1190       const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
  1192   1191       if( zExpr==0 ) zExpr = "";
  1193   1192   
  1194   1193       rc = fts5CursorParseRank(pConfig, pCsr, pRank);
  1195   1194       if( rc==SQLITE_OK ){
  1196   1195         if( zExpr[0]=='*' ){

Changes to ext/fts5/test/fts5rank.test.

    87     87   } {1 3 2}
    88     88   
    89     89   do_test 2.7 {
    90     90     execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db
    91     91   } {1 3 2}
    92     92   
    93     93   
           94  +#--------------------------------------------------------------------------
           95  +# At one point there was a problem with queries such as:
           96  +#
           97  +#   ... MATCH 'x OR y' ORDER BY rank;
           98  +#
           99  +# if there were zero occurrences of token 'y' in the dataset. The
          100  +# following tests verify that that problem has been addressed.
          101  +#
          102  +foreach_detail_mode $::testprefix {
          103  +  do_execsql_test 3.0 {
          104  +    CREATE VIRTUAL TABLE y1 USING fts5(z, detail=%DETAIL%);
          105  +    INSERT INTO y1 VALUES('test xyz');
          106  +    INSERT INTO y1 VALUES('test test xyz test');
          107  +    INSERT INTO y1 VALUES('test test xyz');
          108  +  }
          109  +
          110  +  do_execsql_test 3.1 {
          111  +    SELECT rowid FROM y1('test OR tset');
          112  +  } {1 2 3}
          113  +
          114  +  do_execsql_test 3.2 {
          115  +    SELECT rowid FROM y1('test OR tset') ORDER BY bm25(y1)
          116  +  } {2 3 1}
    94    117   
          118  +  do_execsql_test 3.3 {
          119  +    SELECT rowid FROM y1('test OR tset') ORDER BY +rank
          120  +  } {2 3 1}
    95    121   
    96         -
          122  +  do_execsql_test 3.4 {
          123  +    SELECT rowid FROM y1('test OR tset') ORDER BY rank
          124  +  } {2 3 1}
          125  +}
    97    126   
    98    127   
    99    128   finish_test
   100    129   

Added ext/misc/csv.c.

            1  +/*
            2  +** 2016-05-28
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file contains the implementation of an SQLite virtual table for
           14  +** reading CSV files.
           15  +**
           16  +** Usage:
           17  +**
           18  +**    .load ./csv
           19  +**    CREATE VIRTUAL TABLE temp.csv USING csv(filename=FILENAME);
           20  +**    SELECT * FROM csv;
           21  +**
           22  +** The columns are named "c1", "c2", "c3", ... by default.  But the
           23  +** application can define its own CREATE TABLE statement as an additional
           24  +** parameter.  For example:
           25  +**
           26  +**    CREATE VIRTUAL TABLE temp.csv2 USING csv(
           27  +**       filename = "../http.log",
           28  +**       schema = "CREATE TABLE x(date,ipaddr,url,referrer,userAgent)"
           29  +**    );
           30  +**
           31  +** Instead of specifying a file, the text of the CSV can be loaded using
           32  +** the data= parameter.
           33  +**
           34  +** If the columns=N parameter is supplied, then the CSV file is assumed to have
           35  +** N columns.  If the columns parameter is omitted, the CSV file is opened
           36  +** as soon as the virtual table is constructed and the first row of the CSV
           37  +** is read in order to count the tables.
           38  +**
           39  +** Some extra debugging features (used for testing virtual tables) are available
           40  +** if this module is compiled with -DSQLITE_TEST.
           41  +*/
           42  +#include <sqlite3ext.h>
           43  +SQLITE_EXTENSION_INIT1
           44  +#include <string.h>
           45  +#include <stdlib.h>
           46  +#include <assert.h>
           47  +#include <stdarg.h>
           48  +#include <ctype.h>
           49  +#include <stdio.h>
           50  +
           51  +/*
           52  +** A macro to hint to the compiler that a function should not be
           53  +** inlined.
           54  +*/
           55  +#if defined(__GNUC__)
           56  +#  define CSV_NOINLINE  __attribute__((noinline))
           57  +#elif defined(_MSC_VER) && _MSC_VER>=1310
           58  +#  define CSV_NOINLINE  __declspec(noinline)
           59  +#else
           60  +#  define CSV_NOINLINE
           61  +#endif
           62  +
           63  +
           64  +/* Max size of the error message in a CsvReader */
           65  +#define CSV_MXERR 200
           66  +
           67  +/* Size of the CsvReader input buffer */
           68  +#define CSV_INBUFSZ 1024
           69  +
           70  +/* A context object used when read a CSV file. */
           71  +typedef struct CsvReader CsvReader;
           72  +struct CsvReader {
           73  +  FILE *in;              /* Read the CSV text from this input stream */
           74  +  char *z;               /* Accumulated text for a field */
           75  +  int n;                 /* Number of bytes in z */
           76  +  int nAlloc;            /* Space allocated for z[] */
           77  +  int nLine;             /* Current line number */
           78  +  char cTerm;            /* Character that terminated the most recent field */
           79  +  size_t iIn;            /* Next unread character in the input buffer */
           80  +  size_t nIn;            /* Number of characters in the input buffer */
           81  +  char *zIn;             /* The input buffer */
           82  +  char zErr[CSV_MXERR];  /* Error message */
           83  +};
           84  +
           85  +/* Initialize a CsvReader object */
           86  +static void csv_reader_init(CsvReader *p){
           87  +  p->in = 0;
           88  +  p->z = 0;
           89  +  p->n = 0;
           90  +  p->nAlloc = 0;
           91  +  p->nLine = 0;
           92  +  p->nIn = 0;
           93  +  p->zIn = 0;
           94  +  p->zErr[0] = 0;
           95  +}
           96  +
           97  +/* Close and reset a CsvReader object */
           98  +static void csv_reader_reset(CsvReader *p){
           99  +  if( p->in ){
          100  +    fclose(p->in);
          101  +    sqlite3_free(p->zIn);
          102  +  }
          103  +  sqlite3_free(p->z);
          104  +  csv_reader_init(p);
          105  +}
          106  +
          107  +/* Report an error on a CsvReader */
          108  +static void csv_errmsg(CsvReader *p, const char *zFormat, ...){
          109  +  va_list ap;
          110  +  va_start(ap, zFormat);
          111  +  sqlite3_vsnprintf(CSV_MXERR, p->zErr, zFormat, ap);
          112  +  va_end(ap);
          113  +}
          114  +
          115  +/* Open the file associated with a CsvReader
          116  +** Return the number of errors.
          117  +*/
          118  +static int csv_reader_open(
          119  +  CsvReader *p,               /* The reader to open */
          120  +  const char *zFilename,      /* Read from this filename */
          121  +  const char *zData           /*  ... or use this data */
          122  +){
          123  +  if( zFilename ){
          124  +    p->zIn = sqlite3_malloc( CSV_INBUFSZ );
          125  +    if( p->zIn==0 ){
          126  +      csv_errmsg(p, "out of memory");
          127  +      return 1;
          128  +    }
          129  +    p->in = fopen(zFilename, "rb");
          130  +    if( p->in==0 ){
          131  +      csv_reader_reset(p);
          132  +      csv_errmsg(p, "cannot open '%s' for reading", zFilename);
          133  +      return 1;
          134  +    }
          135  +  }else{
          136  +    assert( p->in==0 );
          137  +    p->zIn = (char*)zData;
          138  +    p->nIn = strlen(zData);
          139  +  }
          140  +  return 0;
          141  +}
          142  +
          143  +/* The input buffer has overflowed.  Refill the input buffer, then
          144  +** return the next character
          145  +*/
          146  +static CSV_NOINLINE int csv_getc_refill(CsvReader *p){
          147  +  size_t got;
          148  +
          149  +  assert( p->iIn>=p->nIn );  /* Only called on an empty input buffer */
          150  +  assert( p->in!=0 );        /* Only called if reading froma file */
          151  +
          152  +  got = fread(p->zIn, 1, CSV_INBUFSZ, p->in);
          153  +  if( got==0 ) return EOF;
          154  +  p->nIn = got;
          155  +  p->iIn = 1;
          156  +  return p->zIn[0];
          157  +}
          158  +
          159  +/* Return the next character of input.  Return EOF at end of input. */
          160  +static int csv_getc(CsvReader *p){
          161  +  if( p->iIn >= p->nIn ){
          162  +    if( p->in!=0 ) return csv_getc_refill(p);
          163  +    return EOF;
          164  +  }
          165  +  return p->zIn[p->iIn++];
          166  +}
          167  +
          168  +/* Increase the size of p->z and append character c to the end. 
          169  +** Return 0 on success and non-zero if there is an OOM error */
          170  +static CSV_NOINLINE int csv_resize_and_append(CsvReader *p, char c){
          171  +  char *zNew;
          172  +  int nNew = p->nAlloc*2 + 100;
          173  +  zNew = sqlite3_realloc64(p->z, nNew);
          174  +  if( zNew ){
          175  +    p->z = zNew;
          176  +    p->nAlloc = nNew;
          177  +    p->z[p->n++] = c;
          178  +    return 0;
          179  +  }else{
          180  +    csv_errmsg(p, "out of memory");
          181  +    return 1;
          182  +  }
          183  +}
          184  +
          185  +/* Append a single character to the CsvReader.z[] array.
          186  +** Return 0 on success and non-zero if there is an OOM error */
          187  +static int csv_append(CsvReader *p, char c){
          188  +  if( p->n>=p->nAlloc-1 ) return csv_resize_and_append(p, c);
          189  +  p->z[p->n++] = c;
          190  +  return 0;
          191  +}
          192  +
          193  +/* Read a single field of CSV text.  Compatible with rfc4180 and extended
          194  +** with the option of having a separator other than ",".
          195  +**
          196  +**   +  Input comes from p->in.
          197  +**   +  Store results in p->z of length p->n.  Space to hold p->z comes
          198  +**      from sqlite3_malloc64().
          199  +**   +  Keep track of the line number in p->nLine.
          200  +**   +  Store the character that terminates the field in p->cTerm.  Store
          201  +**      EOF on end-of-file.
          202  +**
          203  +** Return "" at EOF.  Return 0 on an OOM error.
          204  +*/
          205  +static char *csv_read_one_field(CsvReader *p){
          206  +  int c;
          207  +  p->n = 0;
          208  +  c = csv_getc(p);
          209  +  if( c==EOF ){
          210  +    p->cTerm = EOF;
          211  +    return "";
          212  +  }
          213  +  if( c=='"' ){
          214  +    int pc, ppc;
          215  +    int startLine = p->nLine;
          216  +    pc = ppc = 0;
          217  +    while( 1 ){
          218  +      c = csv_getc(p);
          219  +      if( c<='"' || pc=='"' ){
          220  +        if( c=='\n' ) p->nLine++;
          221  +        if( c=='"' ){
          222  +          if( pc=='"' ){
          223  +            pc = 0;
          224  +            continue;
          225  +          }
          226  +        }
          227  +        if( (c==',' && pc=='"')
          228  +         || (c=='\n' && pc=='"')
          229  +         || (c=='\n' && pc=='\r' && ppc=='"')
          230  +         || (c==EOF && pc=='"')
          231  +        ){
          232  +          do{ p->n--; }while( p->z[p->n]!='"' );
          233  +          p->cTerm = c;
          234  +          break;
          235  +        }
          236  +        if( pc=='"' && c!='\r' ){
          237  +          csv_errmsg(p, "line %d: unescaped %c character", p->nLine, '"');
          238  +          break;
          239  +        }
          240  +        if( c==EOF ){
          241  +          csv_errmsg(p, "line %d: unterminated %c-quoted field\n",
          242  +                     startLine, '"');
          243  +          p->cTerm = c;
          244  +          break;
          245  +        }
          246  +      }
          247  +      if( csv_append(p, (char)c) ) return 0;
          248  +      ppc = pc;
          249  +      pc = c;
          250  +    }
          251  +  }else{
          252  +    while( c>',' || (c!=EOF && c!=',' && c!='\n') ){
          253  +      if( csv_append(p, (char)c) ) return 0;
          254  +      c = csv_getc(p);
          255  +    }
          256  +    if( c=='\n' ){
          257  +      p->nLine++;
          258  +      if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
          259  +    }
          260  +    p->cTerm = c;
          261  +  }
          262  +  if( p->z ) p->z[p->n] = 0;
          263  +  return p->z;
          264  +}
          265  +
          266  +
          267  +/* Forward references to the various virtual table methods implemented
          268  +** in this file. */
          269  +static int csvtabCreate(sqlite3*, void*, int, const char*const*, 
          270  +                           sqlite3_vtab**,char**);
          271  +static int csvtabConnect(sqlite3*, void*, int, const char*const*, 
          272  +                           sqlite3_vtab**,char**);
          273  +static int csvtabBestIndex(sqlite3_vtab*,sqlite3_index_info*);
          274  +static int csvtabDisconnect(sqlite3_vtab*);
          275  +static int csvtabOpen(sqlite3_vtab*, sqlite3_vtab_cursor**);
          276  +static int csvtabClose(sqlite3_vtab_cursor*);
          277  +static int csvtabFilter(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
          278  +                          int argc, sqlite3_value **argv);
          279  +static int csvtabNext(sqlite3_vtab_cursor*);
          280  +static int csvtabEof(sqlite3_vtab_cursor*);
          281  +static int csvtabColumn(sqlite3_vtab_cursor*,sqlite3_context*,int);
          282  +static int csvtabRowid(sqlite3_vtab_cursor*,sqlite3_int64*);
          283  +
          284  +/* An instance of the CSV virtual table */
          285  +typedef struct CsvTable {
          286  +  sqlite3_vtab base;              /* Base class.  Must be first */
          287  +  char *zFilename;                /* Name of the CSV file */
          288  +  char *zData;                    /* Raw CSV data in lieu of zFilename */
          289  +  long iStart;                    /* Offset to start of data in zFilename */
          290  +  int nCol;                       /* Number of columns in the CSV file */
          291  +  unsigned int tstFlags;          /* Bit values used for testing */
          292  +} CsvTable;
          293  +
          294  +/* Allowed values for tstFlags */
          295  +#define CSVTEST_FIDX  0x0001      /* Pretend that constrained searchs cost less*/
          296  +
          297  +/* A cursor for the CSV virtual table */
          298  +typedef struct CsvCursor {
          299  +  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
          300  +  CsvReader rdr;                  /* The CsvReader object */
          301  +  char **azVal;                   /* Value of the current row */
          302  +  int *aLen;                      /* Length of each entry */
          303  +  sqlite3_int64 iRowid;           /* The current rowid.  Negative for EOF */
          304  +} CsvCursor;
          305  +
          306  +/* Transfer error message text from a reader into a CsvTable */
          307  +static void csv_xfer_error(CsvTable *pTab, CsvReader *pRdr){
          308  +  sqlite3_free(pTab->base.zErrMsg);
          309  +  pTab->base.zErrMsg = sqlite3_mprintf("%s", pRdr->zErr);
          310  +}
          311  +
          312  +/*
          313  +** This method is the destructor fo a CsvTable object.
          314  +*/
          315  +static int csvtabDisconnect(sqlite3_vtab *pVtab){
          316  +  CsvTable *p = (CsvTable*)pVtab;
          317  +  sqlite3_free(p->zFilename);
          318  +  sqlite3_free(p->zData);
          319  +  sqlite3_free(p);
          320  +  return SQLITE_OK;
          321  +}
          322  +
          323  +/* Skip leading whitespace.  Return a pointer to the first non-whitespace
          324  +** character, or to the zero terminator if the string has only whitespace */
          325  +static const char *csv_skip_whitespace(const char *z){
          326  +  while( isspace((unsigned char)z[0]) ) z++;
          327  +  return z;
          328  +}
          329  +
          330  +/* Remove trailing whitespace from the end of string z[] */
          331  +static void csv_trim_whitespace(char *z){
          332  +  size_t n = strlen(z);
          333  +  while( n>0 && isspace((unsigned char)z[n]) ) n--;
          334  +  z[n] = 0;
          335  +}
          336  +
          337  +/* Dequote the string */
          338  +static void csv_dequote(char *z){
          339  +  int i, j;
          340  +  char cQuote = z[0];
          341  +  size_t n;
          342  +
          343  +  if( cQuote!='\'' && cQuote!='"' ) return;
          344  +  n = strlen(z);
          345  +  if( n<2 || z[n-1]!=z[0] ) return;
          346  +  for(i=1, j=0; i<n-1; i++){
          347  +    if( z[i]==cQuote && z[i+1]==cQuote ) i++;
          348  +    z[j++] = z[i];
          349  +  }
          350  +  z[j] = 0;
          351  +}
          352  +
          353  +/* Check to see if the string is of the form:  "TAG = VALUE" with optional
          354  +** whitespace before and around tokens.  If it is, return a pointer to the
          355  +** first character of VALUE.  If it is not, return NULL.
          356  +*/
          357  +static const char *csv_parameter(const char *zTag, int nTag, const char *z){
          358  +  z = csv_skip_whitespace(z);
          359  +  if( strncmp(zTag, z, nTag)!=0 ) return 0;
          360  +  z = csv_skip_whitespace(z+nTag);
          361  +  if( z[0]!='=' ) return 0;
          362  +  return csv_skip_whitespace(z+1);
          363  +}
          364  +
          365  +/* Decode a parameter that requires a dequoted string.
          366  +**
          367  +** Return 1 if the parameter is seen, or 0 if not.  1 is returned
          368  +** even if there is an error.  If an error occurs, then an error message
          369  +** is left in p->zErr.  If there are no errors, p->zErr[0]==0.
          370  +*/
          371  +static int csv_string_parameter(
          372  +  CsvReader *p,            /* Leave the error message here, if there is one */
          373  +  const char *zParam,      /* Parameter we are checking for */
          374  +  const char *zArg,        /* Raw text of the virtual table argment */
          375  +  char **pzVal             /* Write the dequoted string value here */
          376  +){
          377  +  const char *zValue;
          378  +  zValue = csv_parameter(zParam,strlen(zParam),zArg);
          379  +  if( zValue==0 ) return 0;
          380  +  p->zErr[0] = 0;
          381  +  if( *pzVal ){
          382  +    csv_errmsg(p, "more than one '%s' parameter", zParam);
          383  +    return 1;
          384  +  }
          385  +  *pzVal = sqlite3_mprintf("%s", zValue);
          386  +  if( *pzVal==0 ){
          387  +    csv_errmsg(p, "out of memory");
          388  +    return 1;
          389  +  }
          390  +  csv_trim_whitespace(*pzVal);
          391  +  csv_dequote(*pzVal);
          392  +  return 1;
          393  +}
          394  +
          395  +
          396  +/* Return 0 if the argument is false and 1 if it is true.  Return -1 if
          397  +** we cannot really tell.
          398  +*/
          399  +static int csv_boolean(const char *z){
          400  +  if( sqlite3_stricmp("yes",z)==0
          401  +   || sqlite3_stricmp("on",z)==0
          402  +   || sqlite3_stricmp("true",z)==0
          403  +   || (z[0]=='1' && z[0]==0)
          404  +  ){
          405  +    return 1;
          406  +  }
          407  +  if( sqlite3_stricmp("no",z)==0
          408  +   || sqlite3_stricmp("off",z)==0
          409  +   || sqlite3_stricmp("false",z)==0
          410  +   || (z[0]=='0' && z[1]==0)
          411  +  ){
          412  +    return 0;
          413  +  }
          414  +  return -1;
          415  +}
          416  +
          417  +
          418  +/*
          419  +** Parameters:
          420  +**    filename=FILENAME          Name of file containing CSV content
          421  +**    data=TEXT                  Direct CSV content.
          422  +**    schema=SCHEMA              Alternative CSV schema.
          423  +**    header=YES|NO              First row of CSV defines the names of
          424  +**                               columns if "yes".  Default "no".
          425  +**    columns=N                  Assume the CSV file contains N columns.
          426  +**
          427  +** Only available if compiled with SQLITE_TEST:
          428  +**    
          429  +**    testflags=N                Bitmask of test flags.  Optional
          430  +**
          431  +** If schema= is omitted, then the columns are named "c0", "c1", "c2",
          432  +** and so forth.  If columns=N is omitted, then the file is opened and
          433  +** the number of columns in the first row is counted to determine the
          434  +** column count.  If header=YES, then the first row is skipped.
          435  +*/
          436  +static int csvtabConnect(
          437  +  sqlite3 *db,
          438  +  void *pAux,
          439  +  int argc, const char *const*argv,
          440  +  sqlite3_vtab **ppVtab,
          441  +  char **pzErr
          442  +){
          443  +  CsvTable *pNew = 0;        /* The CsvTable object to construct */
          444  +  int bHeader = -1;          /* header= flags.  -1 means not seen yet */
          445  +  int rc = SQLITE_OK;        /* Result code from this routine */
          446  +  int i, j;                  /* Loop counters */
          447  +#ifdef SQLITE_TEST
          448  +  int tstFlags = 0;          /* Value for testflags=N parameter */
          449  +#endif
          450  +  int nCol = -99;            /* Value of the columns= parameter */
          451  +  CsvReader sRdr;            /* A CSV file reader used to store an error
          452  +                             ** message and/or to count the number of columns */
          453  +  static const char *azParam[] = {
          454  +     "filename", "data", "schema", 
          455  +  };
          456  +  char *azPValue[3];         /* Parameter values */
          457  +# define CSV_FILENAME (azPValue[0])
          458  +# define CSV_DATA     (azPValue[1])
          459  +# define CSV_SCHEMA   (azPValue[2])
          460  +
          461  +
          462  +  assert( sizeof(azPValue)==sizeof(azParam) );
          463  +  memset(&sRdr, 0, sizeof(sRdr));
          464  +  memset(azPValue, 0, sizeof(azPValue));
          465  +  for(i=3; i<argc; i++){
          466  +    const char *z = argv[i];
          467  +    const char *zValue;
          468  +    for(j=0; j<sizeof(azParam)/sizeof(azParam[0]); j++){
          469  +      if( csv_string_parameter(&sRdr, azParam[j], z, &azPValue[j]) ) break;
          470  +    }
          471  +    if( j<sizeof(azParam)/sizeof(azParam[0]) ){
          472  +      if( sRdr.zErr[0] ) goto csvtab_connect_error;
          473  +    }else
          474  +    if( (zValue = csv_parameter("header",6,z))!=0 ){
          475  +      int x;
          476  +      if( bHeader>=0 ){
          477  +        csv_errmsg(&sRdr, "more than one 'header' parameter");
          478  +        goto csvtab_connect_error;
          479  +      }
          480  +      x = csv_boolean(zValue);
          481  +      if( x==1 ){
          482  +        bHeader = 1;
          483  +      }else if( x==0 ){
          484  +        bHeader = 0;
          485  +      }else{
          486  +        csv_errmsg(&sRdr, "unrecognized argument to 'header': %s", zValue);
          487  +        goto csvtab_connect_error;
          488  +      }
          489  +    }else
          490  +#ifdef SQLITE_TEST
          491  +    if( (zValue = csv_parameter("testflags",9,z))!=0 ){
          492  +      tstFlags = (unsigned int)atoi(zValue);
          493  +    }else
          494  +#endif
          495  +    if( (zValue = csv_parameter("columns",7,z))!=0 ){
          496  +      if( nCol>0 ){
          497  +        csv_errmsg(&sRdr, "more than one 'columns' parameter");
          498  +        goto csvtab_connect_error;
          499  +      }
          500  +      nCol = atoi(zValue);
          501  +      if( nCol<=0 ){
          502  +        csv_errmsg(&sRdr, "must have at least one column");
          503  +        goto csvtab_connect_error;
          504  +      }
          505  +    }else
          506  +    {
          507  +      csv_errmsg(&sRdr, "unrecognized parameter '%s'", z);
          508  +      goto csvtab_connect_error;
          509  +    }
          510  +  }
          511  +  if( (CSV_FILENAME==0)==(CSV_DATA==0) ){
          512  +    csv_errmsg(&sRdr, "must either filename= or data= but not both");
          513  +    goto csvtab_connect_error;
          514  +  }
          515  +  if( nCol<=0 && csv_reader_open(&sRdr, CSV_FILENAME, CSV_DATA) ){
          516  +    goto csvtab_connect_error;
          517  +  }
          518  +  pNew = sqlite3_malloc( sizeof(*pNew) );
          519  +  *ppVtab = (sqlite3_vtab*)pNew;
          520  +  if( pNew==0 ) goto csvtab_connect_oom;
          521  +  memset(pNew, 0, sizeof(*pNew));
          522  +  if( nCol>0 ){
          523  +    pNew->nCol = nCol;
          524  +  }else{
          525  +    do{
          526  +      const char *z = csv_read_one_field(&sRdr);
          527  +      if( z==0 ) goto csvtab_connect_oom;
          528  +      pNew->nCol++;
          529  +    }while( sRdr.cTerm==',' );
          530  +  }
          531  +  pNew->zFilename = CSV_FILENAME;  CSV_FILENAME = 0;
          532  +  pNew->zData = CSV_DATA;          CSV_DATA = 0;
          533  +#ifdef SQLITE_TEST
          534  +  pNew->tstFlags = tstFlags;
          535  +#endif
          536  +  pNew->iStart = bHeader==1 ? ftell(sRdr.in) : 0;
          537  +  csv_reader_reset(&sRdr);
          538  +  if( CSV_SCHEMA==0 ){
          539  +    char *zSep = "";
          540  +    CSV_SCHEMA = sqlite3_mprintf("CREATE TABLE x(");
          541  +    if( CSV_SCHEMA==0 ) goto csvtab_connect_oom;
          542  +    for(i=0; i<pNew->nCol; i++){
          543  +      CSV_SCHEMA = sqlite3_mprintf("%z%sc%d TEXT",CSV_SCHEMA, zSep, i);
          544  +      zSep = ",";
          545  +    }
          546  +    CSV_SCHEMA = sqlite3_mprintf("%z);", CSV_SCHEMA);
          547  +  }
          548  +  rc = sqlite3_declare_vtab(db, CSV_SCHEMA);
          549  +  if( rc ) goto csvtab_connect_error;
          550  +  for(i=0; i<sizeof(azPValue)/sizeof(azPValue[0]); i++){
          551  +    sqlite3_free(azPValue[i]);
          552  +  }
          553  +  return SQLITE_OK;
          554  +
          555  +csvtab_connect_oom:
          556  +  rc = SQLITE_NOMEM;
          557  +  csv_errmsg(&sRdr, "out of memory");
          558  +
          559  +csvtab_connect_error:
          560  +  if( pNew ) csvtabDisconnect(&pNew->base);
          561  +  for(i=0; i<sizeof(azPValue)/sizeof(azPValue[0]); i++){
          562  +    sqlite3_free(azPValue[i]);
          563  +  }
          564  +  if( sRdr.zErr[0] ){
          565  +    sqlite3_free(*pzErr);
          566  +    *pzErr = sqlite3_mprintf("%s", sRdr.zErr);
          567  +  }
          568  +  csv_reader_reset(&sRdr);
          569  +  if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
          570  +  return rc;
          571  +}
          572  +
          573  +/*
          574  +** Reset the current row content held by a CsvCursor.
          575  +*/
          576  +static void csvtabCursorRowReset(CsvCursor *pCur){
          577  +  CsvTable *pTab = (CsvTable*)pCur->base.pVtab;
          578  +  int i;
          579  +  for(i=0; i<pTab->nCol; i++){
          580  +    sqlite3_free(pCur->azVal[i]);
          581  +    pCur->azVal[i] = 0;
          582  +    pCur->aLen[i] = 0;
          583  +  }
          584  +}
          585  +
          586  +/*
          587  +** The xConnect and xCreate methods do the same thing, but they must be
          588  +** different so that the virtual table is not an eponymous virtual table.
          589  +*/
          590  +static int csvtabCreate(
          591  +  sqlite3 *db,
          592  +  void *pAux,
          593  +  int argc, const char *const*argv,
          594  +  sqlite3_vtab **ppVtab,
          595  +  char **pzErr
          596  +){
          597  + return csvtabConnect(db, pAux, argc, argv, ppVtab, pzErr);
          598  +}
          599  +
          600  +/*
          601  +** Destructor for a CsvCursor.
          602  +*/
          603  +static int csvtabClose(sqlite3_vtab_cursor *cur){
          604  +  CsvCursor *pCur = (CsvCursor*)cur;
          605  +  csvtabCursorRowReset(pCur);
          606  +  csv_reader_reset(&pCur->rdr);
          607  +  sqlite3_free(cur);
          608  +  return SQLITE_OK;
          609  +}
          610  +
          611  +/*
          612  +** Constructor for a new CsvTable cursor object.
          613  +*/
          614  +static int csvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
          615  +  CsvTable *pTab = (CsvTable*)p;
          616  +  CsvCursor *pCur;
          617  +  size_t nByte;
          618  +  nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(int))*pTab->nCol;
          619  +  pCur = sqlite3_malloc( nByte );
          620  +  if( pCur==0 ) return SQLITE_NOMEM;
          621  +  memset(pCur, 0, nByte);
          622  +  pCur->azVal = (char**)&pCur[1];
          623  +  pCur->aLen = (int*)&pCur->azVal[pTab->nCol];
          624  +  *ppCursor = &pCur->base;
          625  +  if( csv_reader_open(&pCur->rdr, pTab->zFilename, pTab->zData) ){
          626  +    csv_xfer_error(pTab, &pCur->rdr);
          627  +    return SQLITE_ERROR;
          628  +  }
          629  +  return SQLITE_OK;
          630  +}
          631  +
          632  +
          633  +/*
          634  +** Advance a CsvCursor to its next row of input.
          635  +** Set the EOF marker if we reach the end of input.
          636  +*/
          637  +static int csvtabNext(sqlite3_vtab_cursor *cur){
          638  +  CsvCursor *pCur = (CsvCursor*)cur;
          639  +  CsvTable *pTab = (CsvTable*)cur->pVtab;
          640  +  int i = 0;
          641  +  char *z;
          642  +  do{
          643  +    z = csv_read_one_field(&pCur->rdr);
          644  +    if( z==0 ){
          645  +      csv_xfer_error(pTab, &pCur->rdr);
          646  +      break;
          647  +    }
          648  +    if( i<pTab->nCol ){
          649  +      if( pCur->aLen[i] < pCur->rdr.n+1 ){
          650  +        char *zNew = sqlite3_realloc(pCur->azVal[i], pCur->rdr.n+1);
          651  +        if( zNew==0 ){
          652  +          csv_errmsg(&pCur->rdr, "out of memory");
          653  +          csv_xfer_error(pTab, &pCur->rdr);
          654  +          break;
          655  +        }
          656  +        pCur->azVal[i] = zNew;
          657  +        pCur->aLen[i] = pCur->rdr.n+1;
          658  +      }
          659  +      memcpy(pCur->azVal[i], z, pCur->rdr.n+1);
          660  +      i++;
          661  +    }
          662  +  }while( pCur->rdr.cTerm==',' );
          663  +  while( i<pTab->nCol ){
          664  +    sqlite3_free(pCur->azVal[i]);
          665  +    pCur->azVal[i] = 0;
          666  +    pCur->aLen[i] = 0;
          667  +    i++;
          668  +  }
          669  +  if( z==0 || pCur->rdr.cTerm==EOF ){
          670  +    pCur->iRowid = -1;
          671  +  }else{
          672  +    pCur->iRowid++;
          673  +  }
          674  +  return SQLITE_OK;
          675  +}
          676  +
          677  +/*
          678  +** Return values of columns for the row at which the CsvCursor
          679  +** is currently pointing.
          680  +*/
          681  +static int csvtabColumn(
          682  +  sqlite3_vtab_cursor *cur,   /* The cursor */
          683  +  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
          684  +  int i                       /* Which column to return */
          685  +){
          686  +  CsvCursor *pCur = (CsvCursor*)cur;
          687  +  CsvTable *pTab = (CsvTable*)cur->pVtab;
          688  +  if( i>=0 && i<pTab->nCol && pCur->azVal[i]!=0 ){
          689  +    sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_STATIC);
          690  +  }
          691  +  return SQLITE_OK;
          692  +}
          693  +
          694  +/*
          695  +** Return the rowid for the current row.
          696  +*/
          697  +static int csvtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          698  +  CsvCursor *pCur = (CsvCursor*)cur;
          699  +  *pRowid = pCur->iRowid;
          700  +  return SQLITE_OK;
          701  +}
          702  +
          703  +/*
          704  +** Return TRUE if the cursor has been moved off of the last
          705  +** row of output.
          706  +*/
          707  +static int csvtabEof(sqlite3_vtab_cursor *cur){
          708  +  CsvCursor *pCur = (CsvCursor*)cur;
          709  +  return pCur->iRowid<0;
          710  +}
          711  +
          712  +/*
          713  +** Only a full table scan is supported.  So xFilter simply rewinds to
          714  +** the beginning.
          715  +*/
          716  +static int csvtabFilter(
          717  +  sqlite3_vtab_cursor *pVtabCursor, 
          718  +  int idxNum, const char *idxStr,
          719  +  int argc, sqlite3_value **argv
          720  +){
          721  +  CsvCursor *pCur = (CsvCursor*)pVtabCursor;
          722  +  CsvTable *pTab = (CsvTable*)pVtabCursor->pVtab;
          723  +  pCur->iRowid = 0;
          724  +  if( pCur->rdr.in==0 ){
          725  +    assert( pCur->rdr.zIn==pTab->zData );
          726  +    assert( pTab->iStart<=pCur->rdr.nIn );
          727  +    pCur->rdr.iIn = pTab->iStart;
          728  +  }else{
          729  +    fseek(pCur->rdr.in, pTab->iStart, SEEK_SET);
          730  +    pCur->rdr.iIn = 0;
          731  +    pCur->rdr.nIn = 0;
          732  +  }
          733  +  return csvtabNext(pVtabCursor);
          734  +}
          735  +
          736  +/*
          737  +** Only a forward full table scan is supported.  xBestIndex is mostly
          738  +** a no-op.  If CSVTEST_FIDX is set, then the presence of equality
          739  +** constraints lowers the estimated cost, which is fiction, but is useful
          740  +** for testing certain kinds of virtual table behavior.
          741  +*/
          742  +static int csvtabBestIndex(
          743  +  sqlite3_vtab *tab,
          744  +  sqlite3_index_info *pIdxInfo
          745  +){
          746  +  pIdxInfo->estimatedCost = 1000000;
          747  +#ifdef SQLITE_TEST
          748  +  if( (((CsvTable*)tab)->tstFlags & CSVTEST_FIDX)!=0 ){
          749  +    /* The usual (and sensible) case is to always do a full table scan.
          750  +    ** The code in this branch only runs when testflags=1.  This code
          751  +    ** generates an artifical and unrealistic plan which is useful
          752  +    ** for testing virtual table logic but is not helpful to real applications.
          753  +    **
          754  +    ** Any ==, LIKE, or GLOB constraint is marked as usable by the virtual
          755  +    ** table (even though it is not) and the cost of running the virtual table
          756  +    ** is reduced from 1 million to just 10.  The constraints are *not* marked
          757  +    ** as omittable, however, so the query planner should still generate a
          758  +    ** plan that gives a correct answer, even if they plan is not optimal.
          759  +    */
          760  +    int i;
          761  +    int nConst = 0;
          762  +    for(i=0; i<pIdxInfo->nConstraint; i++){
          763  +      unsigned char op;
          764  +      if( pIdxInfo->aConstraint[i].usable==0 ) continue;
          765  +      op = pIdxInfo->aConstraint[i].op;
          766  +      if( op==SQLITE_INDEX_CONSTRAINT_EQ 
          767  +       || op==SQLITE_INDEX_CONSTRAINT_LIKE
          768  +       || op==SQLITE_INDEX_CONSTRAINT_GLOB
          769  +      ){
          770  +        pIdxInfo->estimatedCost = 10;
          771  +        pIdxInfo->aConstraintUsage[nConst].argvIndex = nConst+1;
          772  +        nConst++;
          773  +      }
          774  +    }
          775  +  }
          776  +#endif
          777  +  return SQLITE_OK;
          778  +}
          779  +
          780  +
          781  +static sqlite3_module CsvModule = {
          782  +  0,                       /* iVersion */
          783  +  csvtabCreate,            /* xCreate */
          784  +  csvtabConnect,           /* xConnect */
          785  +  csvtabBestIndex,         /* xBestIndex */
          786  +  csvtabDisconnect,        /* xDisconnect */
          787  +  csvtabDisconnect,        /* xDestroy */
          788  +  csvtabOpen,              /* xOpen - open a cursor */
          789  +  csvtabClose,             /* xClose - close a cursor */
          790  +  csvtabFilter,            /* xFilter - configure scan constraints */
          791  +  csvtabNext,              /* xNext - advance a cursor */
          792  +  csvtabEof,               /* xEof - check for end of scan */
          793  +  csvtabColumn,            /* xColumn - read data */
          794  +  csvtabRowid,             /* xRowid - read data */
          795  +  0,                       /* xUpdate */
          796  +  0,                       /* xBegin */
          797  +  0,                       /* xSync */
          798  +  0,                       /* xCommit */
          799  +  0,                       /* xRollback */
          800  +  0,                       /* xFindMethod */
          801  +  0,                       /* xRename */
          802  +};
          803  +
          804  +#ifdef SQLITE_TEST
          805  +/*
          806  +** For virtual table testing, make a version of the CSV virtual table
          807  +** available that has an xUpdate function.  But the xUpdate always returns
          808  +** SQLITE_READONLY since the CSV file is not really writable.
          809  +*/
          810  +static int csvtabUpdate(sqlite3_vtab *p,int n,sqlite3_value**v,sqlite3_int64*x){
          811  +  return SQLITE_READONLY;
          812  +}
          813  +static sqlite3_module CsvModuleFauxWrite = {
          814  +  0,                       /* iVersion */
          815  +  csvtabCreate,            /* xCreate */
          816  +  csvtabConnect,           /* xConnect */
          817  +  csvtabBestIndex,         /* xBestIndex */
          818  +  csvtabDisconnect,        /* xDisconnect */
          819  +  csvtabDisconnect,        /* xDestroy */
          820  +  csvtabOpen,              /* xOpen - open a cursor */
          821  +  csvtabClose,             /* xClose - close a cursor */
          822  +  csvtabFilter,            /* xFilter - configure scan constraints */
          823  +  csvtabNext,              /* xNext - advance a cursor */
          824  +  csvtabEof,               /* xEof - check for end of scan */
          825  +  csvtabColumn,            /* xColumn - read data */
          826  +  csvtabRowid,             /* xRowid - read data */
          827  +  csvtabUpdate,            /* xUpdate */
          828  +  0,                       /* xBegin */
          829  +  0,                       /* xSync */
          830  +  0,                       /* xCommit */
          831  +  0,                       /* xRollback */
          832  +  0,                       /* xFindMethod */
          833  +  0,                       /* xRename */
          834  +};
          835  +#endif /* SQLITE_TEST */
          836  +
          837  +
          838  +
          839  +#ifdef _WIN32
          840  +__declspec(dllexport)
          841  +#endif
          842  +/* 
          843  +** This routine is called when the extension is loaded.  The new
          844  +** CSV virtual table module is registered with the calling database
          845  +** connection.
          846  +*/
          847  +int sqlite3_csv_init(
          848  +  sqlite3 *db, 
          849  +  char **pzErrMsg, 
          850  +  const sqlite3_api_routines *pApi
          851  +){
          852  +  int rc;
          853  +  SQLITE_EXTENSION_INIT2(pApi);
          854  +  rc = sqlite3_create_module(db, "csv", &CsvModule, 0);
          855  +#ifdef SQLITE_TEST
          856  +  if( rc==SQLITE_OK ){
          857  +    rc = sqlite3_create_module(db, "csv_wr", &CsvModuleFauxWrite, 0);
          858  +  }
          859  +#endif
          860  +  return rc;
          861  +}

Added ext/misc/vfsstat.c.

            1  +/*
            2  +** 2016-05-27
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file contains the implementation of an SQLite vfs shim that
           14  +** tracks I/O.  Access to the accumulated status counts is provided using
           15  +** an eponymous virtual table.
           16  +*/
           17  +#include <sqlite3ext.h>
           18  +SQLITE_EXTENSION_INIT1
           19  +
           20  +/*
           21  +** This module contains code for a wrapper VFS that cause stats for
           22  +** most VFS calls to be recorded.
           23  +**
           24  +** To use this module, first compile it as a loadable extension.  See
           25  +** https://www.sqlite.org/loadext.html#build for compilations instructions.
           26  +**
           27  +** After compliing, load this extension, then open database connections to be
           28  +** measured.  Query usages status using the vfsstat virtual table:
           29  +**
           30  +**         SELECT * FROM vfsstat;
           31  +**
           32  +** Reset counters using UPDATE statements against vfsstat:
           33  +**
           34  +**         UPDATE vfsstat SET count=0;
           35  +**
           36  +** EXAMPLE SCRIPT:
           37  +**
           38  +**      .load ./vfsstat
           39  +**      .open test.db
           40  +**      DROP TABLE IF EXISTS t1;
           41  +**      CREATE TABLE t1(x,y);
           42  +**      INSERT INTO t1 VALUES(123, randomblob(5000));
           43  +**      CREATE INDEX t1x ON t1(x);
           44  +**      DROP TABLE t1;
           45  +**      VACUUM;
           46  +**      SELECT * FROM vfsstat WHERE count>0;
           47  +**
           48  +** LIMITATIONS:
           49  +** 
           50  +** This module increments counters without using mutex protection.  So if
           51  +** two or more threads try to use this module at the same time, race conditions
           52  +** may occur which mess up the counts.  This is harmless, other than giving
           53  +** incorrect statistics.
           54  +*/
           55  +#include <string.h>
           56  +#include <stdlib.h>
           57  +#include <assert.h>
           58  +
           59  +/*
           60  +** File types
           61  +*/
           62  +#define VFSSTAT_MAIN         0   /* Main database file */
           63  +#define VFSSTAT_JOURNAL      1   /* Rollback journal */
           64  +#define VFSSTAT_WAL          2   /* Write-ahead log file */
           65  +#define VFSSTAT_MASTERJRNL   3   /* Master journal */
           66  +#define VFSSTAT_SUBJRNL      4   /* Subjournal */
           67  +#define VFSSTAT_TEMPDB       5   /* TEMP database */
           68  +#define VFSSTAT_TEMPJRNL     6   /* Journal for TEMP database */
           69  +#define VFSSTAT_TRANSIENT    7   /* Transient database */
           70  +#define VFSSTAT_ANY          8   /* Unspecified file type */
           71  +#define VFSSTAT_nFile        9   /* This many file types */
           72  +
           73  +/* Names of the file types.  These are allowed values for the
           74  +** first column of the vfsstat virtual table.
           75  +*/
           76  +static const char *azFile[] = {
           77  +  "database", "journal", "wal", "master-journal", "sub-journal",
           78  +  "temp-database", "temp-journal", "transient-db", "*"
           79  +};
           80  +
           81  +/*
           82  +** Stat types
           83  +*/
           84  +#define VFSSTAT_BYTESIN      0   /* Bytes read in */
           85  +#define VFSSTAT_BYTESOUT     1   /* Bytes written out */   
           86  +#define VFSSTAT_READ         2   /* Read requests */
           87  +#define VFSSTAT_WRITE        3   /* Write requests */
           88  +#define VFSSTAT_SYNC         4   /* Syncs */
           89  +#define VFSSTAT_OPEN         5   /* File opens */
           90  +#define VFSSTAT_LOCK         6   /* Lock requests */
           91  +#define VFSSTAT_ACCESS       0   /* xAccess calls.  filetype==ANY only */
           92  +#define VFSSTAT_DELETE       1   /* xDelete calls.  filetype==ANY only */
           93  +#define VFSSTAT_FULLPATH     2   /* xFullPathname calls.  ANY only */
           94  +#define VFSSTAT_RANDOM       3   /* xRandomness calls.    ANY only */
           95  +#define VFSSTAT_SLEEP        4   /* xSleep calls.         ANY only */
           96  +#define VFSSTAT_CURTIME      5   /* xCurrentTime calls.   ANY only */
           97  +#define VFSSTAT_nStat        7   /* This many stat types */
           98  +
           99  +
          100  +/* Names for the second column of the vfsstat virtual table for all
          101  +** cases except when the first column is "*" or VFSSTAT_ANY. */
          102  +static const char *azStat[] = {
          103  +  "bytes-in", "bytes-out", "read", "write", "sync", "open", "lock",
          104  +};
          105  +static const char *azStatAny[] = {
          106  +  "access", "delete", "fullpathname", "randomness", "sleep", "currenttimestamp",
          107  +  "not-used"
          108  +};
          109  +
          110  +/* Total number of counters */
          111  +#define VFSSTAT_MXCNT  (VFSSTAT_nStat*VFSSTAT_nFile)
          112  +
          113  +/*
          114  +** Performance stats are collected in an instance of the following
          115  +** global array.
          116  +*/
          117  +static sqlite3_uint64 aVfsCnt[VFSSTAT_MXCNT];
          118  +
          119  +/*
          120  +** Access to a specific counter
          121  +*/
          122  +#define STATCNT(filetype,stat) (aVfsCnt[(filetype)*VFSSTAT_nStat+(stat)])
          123  +
          124  +/*
          125  +** Forward declaration of objects used by this utility
          126  +*/
          127  +typedef struct VStatVfs VStatVfs;
          128  +typedef struct VStatFile VStatFile;
          129  +
          130  +/* An instance of the VFS */
          131  +struct VStatVfs {
          132  +  sqlite3_vfs base;               /* VFS methods */
          133  +  sqlite3_vfs *pVfs;              /* Parent VFS */
          134  +};
          135  +
          136  +/* An open file */
          137  +struct VStatFile {
          138  +  sqlite3_file base;              /* IO methods */
          139  +  sqlite3_file *pReal;            /* Underlying file handle */
          140  +  unsigned char eFiletype;        /* What type of file is this */
          141  +};
          142  +
          143  +#define REALVFS(p) (((VStatVfs*)(p))->pVfs)
          144  +
          145  +/*
          146  +** Methods for VStatFile
          147  +*/
          148  +static int vstatClose(sqlite3_file*);
          149  +static int vstatRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
          150  +static int vstatWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
          151  +static int vstatTruncate(sqlite3_file*, sqlite3_int64 size);
          152  +static int vstatSync(sqlite3_file*, int flags);
          153  +static int vstatFileSize(sqlite3_file*, sqlite3_int64 *pSize);
          154  +static int vstatLock(sqlite3_file*, int);
          155  +static int vstatUnlock(sqlite3_file*, int);
          156  +static int vstatCheckReservedLock(sqlite3_file*, int *pResOut);
          157  +static int vstatFileControl(sqlite3_file*, int op, void *pArg);
          158  +static int vstatSectorSize(sqlite3_file*);
          159  +static int vstatDeviceCharacteristics(sqlite3_file*);
          160  +static int vstatShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
          161  +static int vstatShmLock(sqlite3_file*, int offset, int n, int flags);
          162  +static void vstatShmBarrier(sqlite3_file*);
          163  +static int vstatShmUnmap(sqlite3_file*, int deleteFlag);
          164  +static int vstatFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
          165  +static int vstatUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
          166  +
          167  +/*
          168  +** Methods for VStatVfs
          169  +*/
          170  +static int vstatOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
          171  +static int vstatDelete(sqlite3_vfs*, const char *zName, int syncDir);
          172  +static int vstatAccess(sqlite3_vfs*, const char *zName, int flags, int *);
          173  +static int vstatFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
          174  +static void *vstatDlOpen(sqlite3_vfs*, const char *zFilename);
          175  +static void vstatDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
          176  +static void (*vstatDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
          177  +static void vstatDlClose(sqlite3_vfs*, void*);
          178  +static int vstatRandomness(sqlite3_vfs*, int nByte, char *zOut);
          179  +static int vstatSleep(sqlite3_vfs*, int microseconds);
          180  +static int vstatCurrentTime(sqlite3_vfs*, double*);
          181  +static int vstatGetLastError(sqlite3_vfs*, int, char *);
          182  +static int vstatCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
          183  +
          184  +static VStatVfs vstat_vfs = {
          185  +  {
          186  +    2,                            /* iVersion */
          187  +    0,                            /* szOsFile (set by register_vstat()) */
          188  +    1024,                         /* mxPathname */
          189  +    0,                            /* pNext */
          190  +    "vfslog",                     /* zName */
          191  +    0,                            /* pAppData */
          192  +    vstatOpen,                     /* xOpen */
          193  +    vstatDelete,                   /* xDelete */
          194  +    vstatAccess,                   /* xAccess */
          195  +    vstatFullPathname,             /* xFullPathname */
          196  +    vstatDlOpen,                   /* xDlOpen */
          197  +    vstatDlError,                  /* xDlError */
          198  +    vstatDlSym,                    /* xDlSym */
          199  +    vstatDlClose,                  /* xDlClose */
          200  +    vstatRandomness,               /* xRandomness */
          201  +    vstatSleep,                    /* xSleep */
          202  +    vstatCurrentTime,              /* xCurrentTime */
          203  +    vstatGetLastError,             /* xGetLastError */
          204  +    vstatCurrentTimeInt64          /* xCurrentTimeInt64 */
          205  +  },
          206  +  0
          207  +};
          208  +
          209  +static const sqlite3_io_methods vstat_io_methods = {
          210  +  3,                              /* iVersion */
          211  +  vstatClose,                      /* xClose */
          212  +  vstatRead,                       /* xRead */
          213  +  vstatWrite,                      /* xWrite */
          214  +  vstatTruncate,                   /* xTruncate */
          215  +  vstatSync,                       /* xSync */
          216  +  vstatFileSize,                   /* xFileSize */
          217  +  vstatLock,                       /* xLock */
          218  +  vstatUnlock,                     /* xUnlock */
          219  +  vstatCheckReservedLock,          /* xCheckReservedLock */
          220  +  vstatFileControl,                /* xFileControl */
          221  +  vstatSectorSize,                 /* xSectorSize */
          222  +  vstatDeviceCharacteristics,      /* xDeviceCharacteristics */
          223  +  vstatShmMap,                     /* xShmMap */
          224  +  vstatShmLock,                    /* xShmLock */
          225  +  vstatShmBarrier,                 /* xShmBarrier */
          226  +  vstatShmUnmap,                   /* xShmUnmap */
          227  +  vstatFetch,                      /* xFetch */
          228  +  vstatUnfetch                     /* xUnfetch */
          229  +};
          230  +
          231  +
          232  +
          233  +/*
          234  +** Close an vstat-file.
          235  +*/
          236  +static int vstatClose(sqlite3_file *pFile){
          237  +  VStatFile *p = (VStatFile *)pFile;
          238  +  int rc = SQLITE_OK;
          239  +
          240  +  if( p->pReal->pMethods ){
          241  +    rc = p->pReal->pMethods->xClose(p->pReal);
          242  +  }
          243  +  return rc;
          244  +}
          245  +
          246  +
          247  +/*
          248  +** Read data from an vstat-file.
          249  +*/
          250  +static int vstatRead(
          251  +  sqlite3_file *pFile, 
          252  +  void *zBuf, 
          253  +  int iAmt, 
          254  +  sqlite_int64 iOfst
          255  +){
          256  +  int rc;
          257  +  VStatFile *p = (VStatFile *)pFile;
          258  +
          259  +  rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
          260  +  STATCNT(p->eFiletype,VFSSTAT_READ)++;
          261  +  if( rc==SQLITE_OK ){
          262  +    STATCNT(p->eFiletype,VFSSTAT_BYTESIN) += iAmt;
          263  +  }
          264  +  return rc;
          265  +}
          266  +
          267  +/*
          268  +** Write data to an vstat-file.
          269  +*/
          270  +static int vstatWrite(
          271  +  sqlite3_file *pFile,
          272  +  const void *z,
          273  +  int iAmt,
          274  +  sqlite_int64 iOfst
          275  +){
          276  +  int rc;
          277  +  VStatFile *p = (VStatFile *)pFile;
          278  +
          279  +  rc = p->pReal->pMethods->xWrite(p->pReal, z, iAmt, iOfst);
          280  +  STATCNT(p->eFiletype,VFSSTAT_WRITE)++;
          281  +  if( rc==SQLITE_OK ){
          282  +    STATCNT(p->eFiletype,VFSSTAT_BYTESOUT) += iAmt;
          283  +  }
          284  +  return rc;
          285  +}
          286  +
          287  +/*
          288  +** Truncate an vstat-file.
          289  +*/
          290  +static int vstatTruncate(sqlite3_file *pFile, sqlite_int64 size){
          291  +  int rc;
          292  +  VStatFile *p = (VStatFile *)pFile;
          293  +  rc = p->pReal->pMethods->xTruncate(p->pReal, size);
          294  +  return rc;
          295  +}
          296  +
          297  +/*
          298  +** Sync an vstat-file.
          299  +*/
          300  +static int vstatSync(sqlite3_file *pFile, int flags){
          301  +  int rc;
          302  +  VStatFile *p = (VStatFile *)pFile;
          303  +  rc = p->pReal->pMethods->xSync(p->pReal, flags);
          304  +  STATCNT(p->eFiletype,VFSSTAT_SYNC)++;
          305  +  return rc;
          306  +}
          307  +
          308  +/*
          309  +** Return the current file-size of an vstat-file.
          310  +*/
          311  +static int vstatFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
          312  +  int rc;
          313  +  VStatFile *p = (VStatFile *)pFile;
          314  +  rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
          315  +  return rc;
          316  +}
          317  +
          318  +/*
          319  +** Lock an vstat-file.
          320  +*/
          321  +static int vstatLock(sqlite3_file *pFile, int eLock){
          322  +  int rc;
          323  +  VStatFile *p = (VStatFile *)pFile;
          324  +  rc = p->pReal->pMethods->xLock(p->pReal, eLock);
          325  +  STATCNT(p->eFiletype,VFSSTAT_LOCK)++;
          326  +  return rc;
          327  +}
          328  +
          329  +/*
          330  +** Unlock an vstat-file.
          331  +*/
          332  +static int vstatUnlock(sqlite3_file *pFile, int eLock){
          333  +  int rc;
          334  +  VStatFile *p = (VStatFile *)pFile;
          335  +  rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
          336  +  STATCNT(p->eFiletype,VFSSTAT_LOCK)++;
          337  +  return rc;
          338  +}
          339  +
          340  +/*
          341  +** Check if another file-handle holds a RESERVED lock on an vstat-file.
          342  +*/
          343  +static int vstatCheckReservedLock(sqlite3_file *pFile, int *pResOut){
          344  +  int rc;
          345  +  VStatFile *p = (VStatFile *)pFile;
          346  +  rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
          347  +  STATCNT(p->eFiletype,VFSSTAT_LOCK)++;
          348  +  return rc;
          349  +}
          350  +
          351  +/*
          352  +** File control method. For custom operations on an vstat-file.
          353  +*/
          354  +static int vstatFileControl(sqlite3_file *pFile, int op, void *pArg){
          355  +  VStatFile *p = (VStatFile *)pFile;
          356  +  int rc;
          357  +  rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
          358  +  if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
          359  +    *(char**)pArg = sqlite3_mprintf("vstat/%z", *(char**)pArg);
          360  +  }
          361  +  return rc;
          362  +}
          363  +
          364  +/*
          365  +** Return the sector-size in bytes for an vstat-file.
          366  +*/
          367  +static int vstatSectorSize(sqlite3_file *pFile){
          368  +  int rc;
          369  +  VStatFile *p = (VStatFile *)pFile;
          370  +  rc = p->pReal->pMethods->xSectorSize(p->pReal);
          371  +  return rc;
          372  +}
          373  +
          374  +/*
          375  +** Return the device characteristic flags supported by an vstat-file.
          376  +*/
          377  +static int vstatDeviceCharacteristics(sqlite3_file *pFile){
          378  +  int rc;
          379  +  VStatFile *p = (VStatFile *)pFile;
          380  +  rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
          381  +  return rc;
          382  +}
          383  +
          384  +/* Create a shared memory file mapping */
          385  +static int vstatShmMap(
          386  +  sqlite3_file *pFile,
          387  +  int iPg,
          388  +  int pgsz,
          389  +  int bExtend,
          390  +  void volatile **pp
          391  +){
          392  +  VStatFile *p = (VStatFile *)pFile;
          393  +  return p->pReal->pMethods->xShmMap(p->pReal, iPg, pgsz, bExtend, pp);
          394  +}
          395  +
          396  +/* Perform locking on a shared-memory segment */
          397  +static int vstatShmLock(sqlite3_file *pFile, int offset, int n, int flags){
          398  +  VStatFile *p = (VStatFile *)pFile;
          399  +  return p->pReal->pMethods->xShmLock(p->pReal, offset, n, flags);
          400  +}
          401  +
          402  +/* Memory barrier operation on shared memory */
          403  +static void vstatShmBarrier(sqlite3_file *pFile){
          404  +  VStatFile *p = (VStatFile *)pFile;
          405  +  p->pReal->pMethods->xShmBarrier(p->pReal);
          406  +}
          407  +
          408  +/* Unmap a shared memory segment */
          409  +static int vstatShmUnmap(sqlite3_file *pFile, int deleteFlag){
          410  +  VStatFile *p = (VStatFile *)pFile;
          411  +  return p->pReal->pMethods->xShmUnmap(p->pReal, deleteFlag);
          412  +}
          413  +
          414  +/* Fetch a page of a memory-mapped file */
          415  +static int vstatFetch(
          416  +  sqlite3_file *pFile,
          417  +  sqlite3_int64 iOfst,
          418  +  int iAmt,
          419  +  void **pp
          420  +){
          421  +  VStatFile *p = (VStatFile *)pFile;
          422  +  return p->pReal->pMethods->xFetch(p->pReal, iOfst, iAmt, pp);
          423  +}
          424  +
          425  +/* Release a memory-mapped page */
          426  +static int vstatUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
          427  +  VStatFile *p = (VStatFile *)pFile;
          428  +  return p->pReal->pMethods->xUnfetch(p->pReal, iOfst, pPage);
          429  +}
          430  +
          431  +/*
          432  +** Open an vstat file handle.
          433  +*/
          434  +static int vstatOpen(
          435  +  sqlite3_vfs *pVfs,
          436  +  const char *zName,
          437  +  sqlite3_file *pFile,
          438  +  int flags,
          439  +  int *pOutFlags
          440  +){
          441  +  int rc;
          442  +  VStatFile *p = (VStatFile*)pFile;
          443  +
          444  +  p->pReal = (sqlite3_file*)&p[1];
          445  +  rc = REALVFS(pVfs)->xOpen(REALVFS(pVfs), zName, p->pReal, flags, pOutFlags);
          446  +  if( flags & SQLITE_OPEN_MAIN_DB ){
          447  +    p->eFiletype = VFSSTAT_MAIN;
          448  +  }else if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
          449  +    p->eFiletype = VFSSTAT_JOURNAL;
          450  +  }else if( flags & SQLITE_OPEN_WAL ){
          451  +    p->eFiletype = VFSSTAT_WAL;
          452  +  }else if( flags & SQLITE_OPEN_MASTER_JOURNAL ){
          453  +    p->eFiletype = VFSSTAT_MASTERJRNL;
          454  +  }else if( flags & SQLITE_OPEN_SUBJOURNAL ){
          455  +    p->eFiletype = VFSSTAT_SUBJRNL;
          456  +  }else if( flags & SQLITE_OPEN_TEMP_DB ){
          457  +    p->eFiletype = VFSSTAT_TEMPDB;
          458  +  }else if( flags & SQLITE_OPEN_TEMP_JOURNAL ){
          459  +    p->eFiletype = VFSSTAT_TEMPJRNL;
          460  +  }else{
          461  +    p->eFiletype = VFSSTAT_TRANSIENT;
          462  +  }
          463  +  STATCNT(p->eFiletype,VFSSTAT_OPEN)++;
          464  +  pFile->pMethods = rc ? 0 : &vstat_io_methods;
          465  +  return rc;
          466  +}
          467  +
          468  +/*
          469  +** Delete the file located at zPath. If the dirSync argument is true,
          470  +** ensure the file-system modifications are synced to disk before
          471  +** returning.
          472  +*/
          473  +static int vstatDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
          474  +  int rc;
          475  +  rc = REALVFS(pVfs)->xDelete(REALVFS(pVfs), zPath, dirSync);
          476  +  STATCNT(VFSSTAT_ANY,VFSSTAT_DELETE)++;
          477  +  return rc;
          478  +}
          479  +
          480  +/*
          481  +** Test for access permissions. Return true if the requested permission
          482  +** is available, or false otherwise.
          483  +*/
          484  +static int vstatAccess(
          485  +  sqlite3_vfs *pVfs, 
          486  +  const char *zPath, 
          487  +  int flags, 
          488  +  int *pResOut
          489  +){
          490  +  int rc;
          491  +  rc = REALVFS(pVfs)->xAccess(REALVFS(pVfs), zPath, flags, pResOut);
          492  +  STATCNT(VFSSTAT_ANY,VFSSTAT_ACCESS)++;
          493  +  return rc;
          494  +}
          495  +
          496  +/*
          497  +** Populate buffer zOut with the full canonical pathname corresponding
          498  +** to the pathname in zPath. zOut is guaranteed to point to a buffer
          499  +** of at least (INST_MAX_PATHNAME+1) bytes.
          500  +*/
          501  +static int vstatFullPathname(
          502  +  sqlite3_vfs *pVfs, 
          503  +  const char *zPath, 
          504  +  int nOut, 
          505  +  char *zOut
          506  +){
          507  +  STATCNT(VFSSTAT_ANY,VFSSTAT_FULLPATH)++;
          508  +  return REALVFS(pVfs)->xFullPathname(REALVFS(pVfs), zPath, nOut, zOut);
          509  +}
          510  +
          511  +/*
          512  +** Open the dynamic library located at zPath and return a handle.
          513  +*/
          514  +static void *vstatDlOpen(sqlite3_vfs *pVfs, const char *zPath){
          515  +  return REALVFS(pVfs)->xDlOpen(REALVFS(pVfs), zPath);
          516  +}
          517  +
          518  +/*
          519  +** Populate the buffer zErrMsg (size nByte bytes) with a human readable
          520  +** utf-8 string describing the most recent error encountered associated 
          521  +** with dynamic libraries.
          522  +*/
          523  +static void vstatDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
          524  +  REALVFS(pVfs)->xDlError(REALVFS(pVfs), nByte, zErrMsg);
          525  +}
          526  +
          527  +/*
          528  +** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
          529  +*/
          530  +static void (*vstatDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
          531  +  return REALVFS(pVfs)->xDlSym(REALVFS(pVfs), p, zSym);
          532  +}
          533  +
          534  +/*
          535  +** Close the dynamic library handle pHandle.
          536  +*/
          537  +static void vstatDlClose(sqlite3_vfs *pVfs, void *pHandle){
          538  +  REALVFS(pVfs)->xDlClose(REALVFS(pVfs), pHandle);
          539  +}
          540  +
          541  +/*
          542  +** Populate the buffer pointed to by zBufOut with nByte bytes of 
          543  +** random data.
          544  +*/
          545  +static int vstatRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
          546  +  STATCNT(VFSSTAT_ANY,VFSSTAT_RANDOM)++;
          547  +  return REALVFS(pVfs)->xRandomness(REALVFS(pVfs), nByte, zBufOut);
          548  +}
          549  +
          550  +/*
          551  +** Sleep for nMicro microseconds. Return the number of microseconds 
          552  +** actually slept.
          553  +*/
          554  +static int vstatSleep(sqlite3_vfs *pVfs, int nMicro){
          555  +  STATCNT(VFSSTAT_ANY,VFSSTAT_SLEEP)++;
          556  +  return REALVFS(pVfs)->xSleep(REALVFS(pVfs), nMicro);
          557  +}
          558  +
          559  +/*
          560  +** Return the current time as a Julian Day number in *pTimeOut.
          561  +*/
          562  +static int vstatCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
          563  +  STATCNT(VFSSTAT_ANY,VFSSTAT_CURTIME)++;
          564  +  return REALVFS(pVfs)->xCurrentTime(REALVFS(pVfs), pTimeOut);
          565  +}
          566  +
          567  +static int vstatGetLastError(sqlite3_vfs *pVfs, int a, char *b){
          568  +  return REALVFS(pVfs)->xGetLastError(REALVFS(pVfs), a, b);
          569  +}
          570  +static int vstatCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
          571  +  STATCNT(VFSSTAT_ANY,VFSSTAT_CURTIME)++;
          572  +  return REALVFS(pVfs)->xCurrentTimeInt64(REALVFS(pVfs), p);
          573  +}
          574  +
          575  +/*
          576  +** A virtual table for accessing the stats collected by this VFS shim
          577  +*/
          578  +static int vstattabConnect(sqlite3*, void*, int, const char*const*, 
          579  +                           sqlite3_vtab**,char**);
          580  +static int vstattabBestIndex(sqlite3_vtab*,sqlite3_index_info*);
          581  +static int vstattabDisconnect(sqlite3_vtab*);
          582  +static int vstattabOpen(sqlite3_vtab*, sqlite3_vtab_cursor**);
          583  +static int vstattabClose(sqlite3_vtab_cursor*);
          584  +static int vstattabFilter(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
          585  +                          int argc, sqlite3_value **argv);
          586  +static int vstattabNext(sqlite3_vtab_cursor*);
          587  +static int vstattabEof(sqlite3_vtab_cursor*);
          588  +static int vstattabColumn(sqlite3_vtab_cursor*,sqlite3_context*,int);
          589  +static int vstattabRowid(sqlite3_vtab_cursor*,sqlite3_int64*);
          590  +static int vstattabUpdate(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*);
          591  +
          592  +/* A cursor for the vfsstat virtual table */
          593  +typedef struct VfsStatCursor {
          594  +  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
          595  +  int i;                          /* Pointing to this aVfsCnt[] value */
          596  +} VfsStatCursor;
          597  +
          598  +
          599  +static int vstattabConnect(
          600  +  sqlite3 *db,
          601  +  void *pAux,
          602  +  int argc, const char *const*argv,
          603  +  sqlite3_vtab **ppVtab,
          604  +  char **pzErr
          605  +){
          606  +  sqlite3_vtab *pNew;
          607  +  int rc;
          608  +
          609  +/* Column numbers */
          610  +#define VSTAT_COLUMN_FILE  0 
          611  +#define VSTAT_COLUMN_STAT  1
          612  +#define VSTAT_COLUMN_COUNT 2
          613  +
          614  +  rc = sqlite3_declare_vtab(db,"CREATE TABLE x(file,stat,count)");
          615  +  if( rc==SQLITE_OK ){
          616  +    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
          617  +    if( pNew==0 ) return SQLITE_NOMEM;
          618  +    memset(pNew, 0, sizeof(*pNew));
          619  +  }
          620  +  return rc;
          621  +}
          622  +
          623  +/*
          624  +** This method is the destructor for vstat table object.
          625  +*/
          626  +static int vstattabDisconnect(sqlite3_vtab *pVtab){
          627  +  sqlite3_free(pVtab);
          628  +  return SQLITE_OK;
          629  +}
          630  +
          631  +/*
          632  +** Constructor for a new vstat table cursor object.
          633  +*/
          634  +static int vstattabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
          635  +  VfsStatCursor *pCur;
          636  +  pCur = sqlite3_malloc( sizeof(*pCur) );
          637  +  if( pCur==0 ) return SQLITE_NOMEM;
          638  +  memset(pCur, 0, sizeof(*pCur));
          639  +  *ppCursor = &pCur->base;
          640  +  return SQLITE_OK;
          641  +}
          642  +
          643  +
          644  +/*
          645  +** Destructor for a VfsStatCursor.
          646  +*/
          647  +static int vstattabClose(sqlite3_vtab_cursor *cur){
          648  +  sqlite3_free(cur);
          649  +  return SQLITE_OK;
          650  +}
          651  +
          652  +
          653  +/*
          654  +** Advance a VfsStatCursor to its next row of output.
          655  +*/
          656  +static int vstattabNext(sqlite3_vtab_cursor *cur){
          657  +  ((VfsStatCursor*)cur)->i++;
          658  +  return SQLITE_OK;
          659  +}
          660  +
          661  +/*
          662  +** Return values of columns for the row at which the VfsStatCursor
          663  +** is currently pointing.
          664  +*/
          665  +static int vstattabColumn(
          666  +  sqlite3_vtab_cursor *cur,   /* The cursor */
          667  +  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
          668  +  int i                       /* Which column to return */
          669  +){
          670  +  VfsStatCursor *pCur = (VfsStatCursor*)cur;
          671  +  switch( i ){
          672  +    case VSTAT_COLUMN_FILE: {
          673  +      sqlite3_result_text(ctx, azFile[pCur->i/VFSSTAT_nStat], -1, SQLITE_STATIC);
          674  +      break;
          675  +    }
          676  +    case VSTAT_COLUMN_STAT: {
          677  +      const char **az;
          678  +      az = (pCur->i/VFSSTAT_nStat)==VFSSTAT_ANY ? azStatAny : azStat;
          679  +      sqlite3_result_text(ctx, az[pCur->i%VFSSTAT_nStat], -1, SQLITE_STATIC);
          680  +      break;
          681  +    }
          682  +    case VSTAT_COLUMN_COUNT: {
          683  +      sqlite3_result_int64(ctx, aVfsCnt[pCur->i]);
          684  +      break;
          685  +    }
          686  +  }
          687  +  return SQLITE_OK;
          688  +}
          689  +
          690  +/*
          691  +** Return the rowid for the current row.
          692  +*/
          693  +static int vstattabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          694  +  VfsStatCursor *pCur = (VfsStatCursor*)cur;
          695  +  *pRowid = pCur->i;
          696  +  return SQLITE_OK;
          697  +}
          698  +
          699  +/*
          700  +** Return TRUE if the cursor has been moved off of the last
          701  +** row of output.
          702  +*/
          703  +static int vstattabEof(sqlite3_vtab_cursor *cur){
          704  +  VfsStatCursor *pCur = (VfsStatCursor*)cur;
          705  +  return pCur->i >= VFSSTAT_MXCNT;
          706  +}
          707  +
          708  +/*
          709  +** Only a full table scan is supported.  So xFilter simply rewinds to
          710  +** the beginning.
          711  +*/
          712  +static int vstattabFilter(
          713  +  sqlite3_vtab_cursor *pVtabCursor, 
          714  +  int idxNum, const char *idxStr,
          715  +  int argc, sqlite3_value **argv
          716  +){
          717  +  VfsStatCursor *pCur = (VfsStatCursor*)pVtabCursor;
          718  +  pCur->i = 0;
          719  +  return SQLITE_OK;
          720  +}
          721  +
          722  +/*
          723  +** Only a forwards full table scan is supported.  xBestIndex is a no-op.
          724  +*/
          725  +static int vstattabBestIndex(
          726  +  sqlite3_vtab *tab,
          727  +  sqlite3_index_info *pIdxInfo
          728  +){
          729  +  return SQLITE_OK;
          730  +}
          731  +
          732  +/*
          733  +** Any VSTAT_COLUMN_COUNT can be changed to a positive integer.
          734  +** No deletions or insertions are allowed.  No changes to other
          735  +** columns are allowed.
          736  +*/
          737  +static int vstattabUpdate(
          738  +  sqlite3_vtab *tab,
          739  +  int argc, sqlite3_value **argv,
          740  +  sqlite3_int64 *pRowid
          741  +){
          742  +  sqlite3_int64 iRowid, x;
          743  +  if( argc==1 ) return SQLITE_ERROR;
          744  +  if( sqlite3_value_type(argv[0])!=SQLITE_INTEGER ) return SQLITE_ERROR;
          745  +  iRowid = sqlite3_value_int64(argv[0]);
          746  +  if( iRowid!=sqlite3_value_int64(argv[1]) ) return SQLITE_ERROR;
          747  +  if( iRowid<0 || iRowid>=VFSSTAT_MXCNT ) return SQLITE_ERROR;
          748  +  if( sqlite3_value_type(argv[VSTAT_COLUMN_COUNT+2])!=SQLITE_INTEGER ){
          749  +    return SQLITE_ERROR;
          750  +  }
          751  +  x = sqlite3_value_int64(argv[VSTAT_COLUMN_COUNT+2]);
          752  +  if( x<0 ) return SQLITE_ERROR;
          753  +  aVfsCnt[iRowid] = x;
          754  +  return SQLITE_OK;
          755  +}
          756  +
          757  +static sqlite3_module VfsStatModule = {
          758  +  0,                         /* iVersion */
          759  +  0,                         /* xCreate */
          760  +  vstattabConnect,           /* xConnect */
          761  +  vstattabBestIndex,         /* xBestIndex */
          762  +  vstattabDisconnect,        /* xDisconnect */
          763  +  0,                         /* xDestroy */
          764  +  vstattabOpen,              /* xOpen - open a cursor */
          765  +  vstattabClose,             /* xClose - close a cursor */
          766  +  vstattabFilter,            /* xFilter - configure scan constraints */
          767  +  vstattabNext,              /* xNext - advance a cursor */
          768  +  vstattabEof,               /* xEof - check for end of scan */
          769  +  vstattabColumn,            /* xColumn - read data */
          770  +  vstattabRowid,             /* xRowid - read data */
          771  +  vstattabUpdate,            /* xUpdate */
          772  +  0,                         /* xBegin */
          773  +  0,                         /* xSync */
          774  +  0,                         /* xCommit */
          775  +  0,                         /* xRollback */
          776  +  0,                         /* xFindMethod */
          777  +  0,                         /* xRename */
          778  +};
          779  +
          780  +/*
          781  +** This routine is an sqlite3_auto_extension() callback, invoked to register
          782  +** the vfsstat virtual table for all new database connections.
          783  +*/
          784  +static int vstatRegister(
          785  +  sqlite3 *db,
          786  +  const char **pzErrMsg,
          787  +  const struct sqlite3_api_routines *pThunk
          788  +){
          789  +  return sqlite3_create_module(db, "vfsstat", &VfsStatModule, 0);
          790  +}
          791  +
          792  +#ifdef _WIN32
          793  +__declspec(dllexport)
          794  +#endif
          795  +/* 
          796  +** This routine is called when the extension is loaded.
          797  +**
          798  +** Register the new VFS.  Make arrangement to register the virtual table
          799  +** for each new database connection.
          800  +*/
          801  +int sqlite3_vfsstat_init(
          802  +  sqlite3 *db, 
          803  +  char **pzErrMsg, 
          804  +  const sqlite3_api_routines *pApi
          805  +){
          806  +  int rc = SQLITE_OK;
          807  +  SQLITE_EXTENSION_INIT2(pApi);
          808  +  vstat_vfs.pVfs = sqlite3_vfs_find(0);
          809  +  vstat_vfs.base.szOsFile = sizeof(VStatFile) + vstat_vfs.pVfs->szOsFile;
          810  +  rc = sqlite3_vfs_register(&vstat_vfs.base, 1);
          811  +  if( rc==SQLITE_OK ){
          812  +    rc = sqlite3_auto_extension((void(*)(void))vstatRegister);
          813  +  }
          814  +  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
          815  +  return rc;
          816  +}

Changes to ext/rbu/rbu_common.tcl.

    31     31       sqlite3rbu rbu $target $rbu
    32     32       set rc [rbu step]
    33     33       rbu close
    34     34       if {$rc != "SQLITE_OK"} break
    35     35     }
    36     36     set rc
    37     37   }
           38  +
           39  +proc do_rbu_vacuum_test {tn step} {
           40  +  uplevel [list do_test $tn.1 {
           41  +    if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
           42  +    while 1 {
           43  +      if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
           44  +      set rc [rbu step]
           45  +      if {$rc!="SQLITE_OK"} break
           46  +      if {$step==1} { rbu close }
           47  +    }
           48  +    rbu close
           49  +  } {SQLITE_DONE}]
           50  +
           51  +  uplevel [list do_execsql_test $tn.2 {
           52  +    PRAGMA integrity_check
           53  +  } ok]
           54  +}
    38     55   

Changes to ext/rbu/rbuvacuum.test.

    13     13   # contains tests to ensure that the sqlite3rbu_vacuum() API works as
    14     14   # expected.
    15     15   #
    16     16   
    17     17   source [file join [file dirname [info script]] rbu_common.tcl]
    18     18   set ::testprefix rbuvacuum
    19     19   
    20         -proc do_rbu_vacuum_test {tn step} {
    21         -  uplevel [list do_test $tn.1 {
    22         -    if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
    23         -    while 1 {
    24         -      if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
    25         -      set rc [rbu step]
    26         -      if {$rc!="SQLITE_OK"} break
    27         -      if {$step==1} { rbu close }
    28         -    }
    29         -    rbu close
    30         -  } {SQLITE_DONE}]
    31         -
    32         -  uplevel [list do_execsql_test $tn.2 {
    33         -    PRAGMA integrity_check
    34         -  } ok]
    35         -}
    36         -
    37     20   foreach step {0 1} {
    38     21   
    39     22     set ::testprefix rbuvacuum-step=$step
    40     23     reset_db
    41     24   
    42     25     # Simplest possible vacuum.
    43     26     do_execsql_test 1.0 {
................................................................................
   399    382   
   400    383     sqlite3_create_collation_v2 $db1 length length_cmp noop
   401    384     sqlite3_create_collation_v2 $db2 length length_cmp noop
   402    385   
   403    386     while {[rbu step]=="SQLITE_OK"} {}
   404    387     list [catch { rbu close } msg] $msg
   405    388   } {0 SQLITE_DONE}
   406         -
   407    389   
   408    390   catch { db close }
   409    391   finish_test
   410    392   

Added ext/rbu/rbuvacuum2.test.

            1  +# 2016 June 1
            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  +# This file contains tests for the RBU module. More specifically, it
           13  +# contains tests to ensure that the sqlite3rbu_vacuum() API works as
           14  +# expected.
           15  +#
           16  +
           17  +source [file join [file dirname [info script]] rbu_common.tcl]
           18  +
           19  +foreach step {0 1} {
           20  +  set ::testprefix rbuvacuum2-$step
           21  +  
           22  +  #-------------------------------------------------------------------------
           23  +  # Test that a database that contains fts3 tables can be vacuumed.
           24  +  #
           25  +  ifcapable fts3 {
           26  +    reset_db
           27  +    do_execsql_test 1.1 {
           28  +      CREATE VIRTUAL TABLE t1 USING fts3(z, y);
           29  +      INSERT INTO t1 VALUES('fix this issue', 'at some point');
           30  +    }
           31  +  
           32  +    do_rbu_vacuum_test 1.2 $step
           33  +  
           34  +    do_execsql_test 1.3 {
           35  +      SELECT * FROM t1;
           36  +    } {{fix this issue} {at some point}}
           37  +  
           38  +    do_execsql_test 1.4 {
           39  +      SELECT rowid FROM t1 WHERE t1 MATCH 'fix';
           40  +    } {1}
           41  +
           42  +    do_execsql_test 1.5 {
           43  +      INSERT INTO t1 VALUES('a b c', 'd e f');
           44  +      INSERT INTO t1 VALUES('l h i', 'd e f');
           45  +      DELETE FROM t1 WHERE docid = 2;
           46  +      INSERT INTO t1 VALUES('a b c', 'x y z');
           47  +    }
           48  +
           49  +    do_rbu_vacuum_test 1.6 $step
           50  +    do_execsql_test 1.7 {
           51  +      INSERT INTO t1(t1) VALUES('integrity-check');
           52  +      SELECT * FROM t1;
           53  +    } {
           54  +      {fix this issue} {at some point}
           55  +      {l h i} {d e f}
           56  +      {a b c} {x y z}
           57  +    }
           58  +  }
           59  +  
           60  +  #-------------------------------------------------------------------------
           61  +  # Test that a database that contains fts5 tables can be vacuumed.
           62  +  #
           63  +  ifcapable fts5 {
           64  +    reset_db
           65  +    do_execsql_test 2.1 {
           66  +      CREATE VIRTUAL TABLE t1 USING fts5(z, y);
           67  +      INSERT INTO t1 VALUES('fix this issue', 'at some point');
           68  +    }
           69  +  
           70  +    do_rbu_vacuum_test 2.2 $step
           71  +  
           72  +    do_execsql_test 2.3 {
           73  +      SELECT * FROM t1;
           74  +    } {{fix this issue} {at some point}}
           75  +  
           76  +    do_execsql_test 2.4 {
           77  +      SELECT rowid FROM t1 ('fix');
           78  +    } {1}
           79  +
           80  +    do_execsql_test 2.5 {
           81  +      INSERT INTO t1 VALUES('a b c', 'd e f');
           82  +      INSERT INTO t1 VALUES('l h i', 'd e f');
           83  +      DELETE FROM t1 WHERE rowid = 2;
           84  +      INSERT INTO t1 VALUES('a b c', 'x y z');
           85  +    }
           86  +
           87  +    do_rbu_vacuum_test 2.6 $step
           88  +    do_execsql_test 2.7 {
           89  +      INSERT INTO t1(t1) VALUES('integrity-check');
           90  +      SELECT * FROM t1;
           91  +    } {
           92  +      {fix this issue} {at some point}
           93  +      {l h i} {d e f}
           94  +      {a b c} {x y z}
           95  +    }
           96  +  }
           97  +
           98  +  #-------------------------------------------------------------------------
           99  +  # Test that a database that contains an rtree table can be vacuumed.
          100  +  #
          101  +  ifcapable rtree {
          102  +    reset_db
          103  +    do_execsql_test 3.1 {
          104  +      CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
          105  +      INSERT INTO rt VALUES(1, 45, 55);
          106  +      INSERT INTO rt VALUES(2, 50, 60);
          107  +      INSERT INTO rt VALUES(3, 55, 65);
          108  +    }
          109  +  
          110  +    do_rbu_vacuum_test 3.2 $step
          111  +  
          112  +    do_execsql_test 3.3 {
          113  +      SELECT * FROM rt;
          114  +    } {1 45.0 55.0 2 50.0 60.0 3 55.0 65.0}
          115  +  
          116  +    do_execsql_test 3.4.1 {
          117  +      SELECT rowid FROM rt WHERE x2>51 AND x1 < 51
          118  +    } {1 2}
          119  +    do_execsql_test 3.4.2 {
          120  +      SELECT rowid FROM rt WHERE x2>59 AND x1 < 59
          121  +    } {2 3}
          122  +
          123  +    do_rbu_vacuum_test 3.5 $step
          124  +
          125  +    do_execsql_test 3.6.1 {
          126  +      SELECT rowid FROM rt WHERE x2>51 AND x1 < 51
          127  +    } {1 2}
          128  +    do_execsql_test 3.6.2 {
          129  +      SELECT rowid FROM rt WHERE x2>59 AND x1 < 59
          130  +    } {2 3}
          131  +  }
          132  +
          133  +  ifcapable trigger {
          134  +    reset_db
          135  +    do_execsql_test 4.1 {
          136  +      CREATE TABLE t1(a, b, c);
          137  +      INSERT INTO t1 VALUES(1, 2, 3);
          138  +      CREATE VIEW v1 AS SELECT * FROM t1;
          139  +      CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END;
          140  +    }
          141  +
          142  +    do_execsql_test 4.2 {
          143  +      SELECT * FROM sqlite_master;
          144  +    } {
          145  +    table t1 t1 2 {CREATE TABLE t1(a, b, c)}
          146  +    view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t1}
          147  +    trigger tr1 t1 0 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END}
          148  +    }
          149  +
          150  +    do_rbu_vacuum_test 4.3 $step
          151  +    do_execsql_test 4.4 {
          152  +      SELECT * FROM sqlite_master;
          153  +    } {
          154  +    table t1 t1 2 {CREATE TABLE t1(a, b, c)}
          155  +    view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t1}
          156  +    trigger tr1 t1 0 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END}
          157  +    }
          158  +  }
          159  +
          160  +}
          161  +
          162  +finish_test

Changes to ext/rbu/sqlite3rbu.c.

   917    917   ** left in the RBU handle passed as the first argument. A copy of the 
   918    918   ** error code is returned.
   919    919   */
   920    920   static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
   921    921     int rc;
   922    922     memset(pIter, 0, sizeof(RbuObjIter));
   923    923   
   924         -  rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, 
          924  +  rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, 
          925  +    sqlite3_mprintf(
   925    926         "SELECT rbu_target_name(name, type='view') AS target, name "
   926    927         "FROM sqlite_master "
   927    928         "WHERE type IN ('table', 'view') AND target IS NOT NULL "
          929  +      " %s "
   928    930         "ORDER BY name"
   929         -  );
          931  +  , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : ""));
   930    932   
   931    933     if( rc==SQLITE_OK ){
   932    934       rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
   933    935           "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
   934    936           "  FROM main.sqlite_master "
   935    937           "  WHERE type='index' AND tbl_name = ?"
   936    938       );
................................................................................
  2501   2503   static void rbuFileSuffix3(const char *zBase, char *z){
  2502   2504   #ifdef SQLITE_ENABLE_8_3_NAMES
  2503   2505   #if SQLITE_ENABLE_8_3_NAMES<2
  2504   2506     if( sqlite3_uri_boolean(zBase, "8_3_names", 0) )
  2505   2507   #endif
  2506   2508     {
  2507   2509       int i, sz;
  2508         -    sz = sqlite3Strlen30(z);
         2510  +    sz = (int)strlen(z)&0xffffff;
  2509   2511       for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
  2510         -    if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
         2512  +    if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
  2511   2513     }
  2512   2514   #endif
  2513   2515   }
  2514   2516   
  2515   2517   /*
  2516   2518   ** Return the current wal-index header checksum for the target database 
  2517   2519   ** as a 64-bit integer.

Changes to ext/rtree/rtree.c.

  2797   2797     if( f<d ){
  2798   2798       f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY));
  2799   2799     }
  2800   2800     return f;
  2801   2801   }
  2802   2802   #endif /* !defined(SQLITE_RTREE_INT_ONLY) */
  2803   2803   
         2804  +/*
         2805  +** A constraint has failed while inserting a row into an rtree table. 
         2806  +** Assuming no OOM error occurs, this function sets the error message 
         2807  +** (at pRtree->base.zErrMsg) to an appropriate value and returns
         2808  +** SQLITE_CONSTRAINT.
         2809  +**
         2810  +** Parameter iCol is the index of the leftmost column involved in the
         2811  +** constraint failure. If it is 0, then the constraint that failed is
         2812  +** the unique constraint on the id column. Otherwise, it is the rtree
         2813  +** (c1<=c2) constraint on columns iCol and iCol+1 that has failed.
         2814  +**
         2815  +** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT.
         2816  +*/
         2817  +static int rtreeConstraintError(Rtree *pRtree, int iCol){
         2818  +  sqlite3_stmt *pStmt = 0;
         2819  +  char *zSql; 
         2820  +  int rc;
         2821  +
         2822  +  assert( iCol==0 || iCol%2 );
         2823  +  zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName);
         2824  +  if( zSql ){
         2825  +    rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0);
         2826  +  }else{
         2827  +    rc = SQLITE_NOMEM;
         2828  +  }
         2829  +  sqlite3_free(zSql);
         2830  +
         2831  +  if( rc==SQLITE_OK ){
         2832  +    if( iCol==0 ){
         2833  +      const char *zCol = sqlite3_column_name(pStmt, 0);
         2834  +      pRtree->base.zErrMsg = sqlite3_mprintf(
         2835  +          "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol
         2836  +      );
         2837  +    }else{
         2838  +      const char *zCol1 = sqlite3_column_name(pStmt, iCol);
         2839  +      const char *zCol2 = sqlite3_column_name(pStmt, iCol+1);
         2840  +      pRtree->base.zErrMsg = sqlite3_mprintf(
         2841  +          "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2
         2842  +      );
         2843  +    }
         2844  +  }
         2845  +
         2846  +  sqlite3_finalize(pStmt);
         2847  +  return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc);
         2848  +}
         2849  +
         2850  +
  2804   2851   
  2805   2852   /*
  2806   2853   ** The xUpdate method for rtree module virtual tables.
  2807   2854   */
  2808   2855   static int rtreeUpdate(
  2809   2856     sqlite3_vtab *pVtab, 
  2810   2857     int nData, 
................................................................................
  2847   2894   
  2848   2895   #ifndef SQLITE_RTREE_INT_ONLY
  2849   2896       if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
  2850   2897         for(ii=0; ii<nData-4; ii+=2){
  2851   2898           cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
  2852   2899           cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
  2853   2900           if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
  2854         -          rc = SQLITE_CONSTRAINT;
         2901  +          rc = rtreeConstraintError(pRtree, ii+1);
  2855   2902             goto constraint;
  2856   2903           }
  2857   2904         }
  2858   2905       }else
  2859   2906   #endif
  2860   2907       {
  2861   2908         for(ii=0; ii<nData-4; ii+=2){
  2862   2909           cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
  2863   2910           cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
  2864   2911           if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
  2865         -          rc = SQLITE_CONSTRAINT;
         2912  +          rc = rtreeConstraintError(pRtree, ii+1);
  2866   2913             goto constraint;
  2867   2914           }
  2868   2915         }
  2869   2916       }
  2870   2917   
  2871   2918       /* If a rowid value was supplied, check if it is already present in 
  2872   2919       ** the table. If so, the constraint has failed. */
................................................................................
  2879   2926           sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
  2880   2927           steprc = sqlite3_step(pRtree->pReadRowid);
  2881   2928           rc = sqlite3_reset(pRtree->pReadRowid);
  2882   2929           if( SQLITE_ROW==steprc ){
  2883   2930             if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
  2884   2931               rc = rtreeDeleteRowid(pRtree, cell.iRowid);
  2885   2932             }else{
  2886         -            rc = SQLITE_CONSTRAINT;
         2933  +            rc = rtreeConstraintError(pRtree, 0);
  2887   2934               goto constraint;
  2888   2935             }
  2889   2936           }
  2890   2937         }
  2891   2938         bHaveRowid = 1;
  2892   2939       }
  2893   2940     }
................................................................................
  2962   3009   static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
  2963   3010     const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
  2964   3011     char *zSql;
  2965   3012     sqlite3_stmt *p;
  2966   3013     int rc;
  2967   3014     i64 nRow = 0;
  2968   3015   
         3016  +  if( sqlite3_table_column_metadata(db,pRtree->zDb,"sqlite_stat1",
         3017  +          0,0,0,0,0,0)==SQLITE_ERROR ){
         3018  +    pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
         3019  +    return SQLITE_OK;
         3020  +  }
  2969   3021     zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
  2970   3022     if( zSql==0 ){
  2971   3023       rc = SQLITE_NOMEM;
  2972   3024     }else{
  2973   3025       rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
  2974   3026       if( rc==SQLITE_OK ){
  2975   3027         if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);

Changes to ext/rtree/rtree1.test.

   190    190   do_test rtree-2.1.3 {
   191    191     execsql { INSERT INTO t1 VALUES(NULL, 1, 3, 2, 4) }
   192    192     execsql { SELECT ii FROM t1 ORDER BY ii }
   193    193   } {1 2 3}
   194    194   
   195    195   do_test rtree-2.2.1 {
   196    196     catchsql { INSERT INTO t1 VALUES(2, 1, 3, 2, 4) }
   197         -} {1 {constraint failed}}
          197  +} {1 {UNIQUE constraint failed: t1.ii}}
   198    198   do_test rtree-2.2.2 {
   199    199     catchsql { INSERT INTO t1 VALUES(4, 1, 3, 4, 2) }
   200         -} {1 {constraint failed}}
          200  +} {1 {rtree constraint failed: t1.(y1<=y2)}}
   201    201   do_test rtree-2.2.3 {
   202    202     catchsql { INSERT INTO t1 VALUES(4, 3, 1, 2, 4) }
   203         -} {1 {constraint failed}}
          203  +} {1 {rtree constraint failed: t1.(x1<=x2)}}
   204    204   do_test rtree-2.2.4 {
   205    205     execsql { SELECT ii FROM t1 ORDER BY ii }
   206    206   } {1 2 3}
   207    207   
   208    208   do_test rtree-2.X {
   209    209     execsql { DROP TABLE t1 }
   210    210   } {}
................................................................................
   232    232       SELECT * FROM t1;
   233    233     }
   234    234   } {5 1 3 2 4 6 2 6 4 8}
   235    235   
   236    236   # Test the constraint on the coordinates (c[i]<=c[i+1] where (i%2==0)):
   237    237   do_test rtree-3.2.1 {
   238    238     catchsql { INSERT INTO t1 VALUES(7, 2, 6, 4, 3) }
   239         -} {1 {constraint failed}}
          239  +} {1 {rtree constraint failed: t1.(y1<=y2)}}
   240    240   do_test rtree-3.2.2 {
   241    241     catchsql { INSERT INTO t1 VALUES(8, 2, 6, 3, 3) }
   242    242   } {0 {}}
   243    243   
   244    244   #----------------------------------------------------------------------------
   245    245   # Test cases rtree-5.* test DELETE operations.
   246    246   #
................................................................................
   486    486       ABORT    1 1 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
   487    487       IGNORE   1 0 {1 1 2 3 4   2 2 3 4 5               4 4 5 6 7   5 3 4 5 6}
   488    488       FAIL     1 1 {1 1 2 3 4   2 2 3 4 5               4 4 5 6 7   5 3 4 5 6}
   489    489       REPLACE  1 0 {1 4 5 6 7   2 2 3 4 5                           5 3 4 5 6}
   490    490     }
   491    491   
   492    492     4    "INSERT %CONF% INTO t1 VALUES(2, 7, 6, 7, 7)" {
   493         -    ROLLBACK 0 1 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6}
   494         -    ABORT    0 1 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
          493  +    ROLLBACK 0 2 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6}
          494  +    ABORT    0 2 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
   495    495       IGNORE   0 0 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
   496         -    FAIL     0 1 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
   497         -    REPLACE  0 1 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
          496  +    FAIL     0 2 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
          497  +    REPLACE  0 2 {1 1 2 3 4   2 2 3 4 5   3 3 4 5 6   4 4 5 6 7}
   498    498     }
   499    499   
   500    500   } {
   501    501     foreach {mode uses error data} $testdata {
   502    502       db_restore_and_reopen
   503    503   
   504    504       set sql [string map [list %CONF% "OR $mode"] $sql_template]
................................................................................
   506    506   
   507    507       execsql {
   508    508         BEGIN;
   509    509           INSERT INTO t1 VALUES(4,   4, 5, 6, 7);
   510    510       }
   511    511   
   512    512       set res(0) {0 {}}
   513         -    set res(1) {1 {constraint failed}}
          513  +    set res(1) {1 {UNIQUE constraint failed: t1.idx}}
          514  +    set res(2) {1 {rtree constraint failed: t1.(x1<=x2)}}
          515  +
   514    516       do_catchsql_test $testname.1 $sql $res($error)
   515    517       do_test $testname.2 [list sql_uses_stmt db $sql] $uses
   516    518       do_execsql_test $testname.3 { SELECT * FROM t1 ORDER BY idx } $data
   517    519   
   518    520       do_test $testname.4 { rtree_check db t1 } 0
   519    521       db close
   520    522     }

Changes to ext/rtree/rtree3.test.

    43     43   #
    44     44   #   rtree3-6: Test OOM while deleting all rows of a table, one at a time.
    45     45   #
    46     46   #   rtree3-7: OOM during an ALTER TABLE RENAME TABLE command.
    47     47   #
    48     48   #   rtree3-8: Test OOM while registering the r-tree module with sqlite.
    49     49   #
    50         -
           50  +#   rtree3-11: OOM following a constraint failure
           51  +#
    51     52   do_faultsim_test rtree3-1 -faults oom* -prep {
    52     53     faultsim_delete_and_reopen
    53     54   } -body {
    54     55     execsql {
    55     56       BEGIN TRANSACTION;
    56     57       CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2);
    57     58       INSERT INTO rt VALUES(NULL, 3, 5, 7, 9);
................................................................................
   230    231     execsql { SELECT * FROM rt }
   231    232   } -body {
   232    233     execsql { SELECT ii FROM rt WHERE ii MATCH cube(4.5, 5.5, 6.5, 1, 1, 1) }
   233    234   } -test {
   234    235     faultsim_test_result {0 2}
   235    236   }
   236    237   
          238  +
          239  +do_test rtree3-11.prep {
          240  +  faultsim_delete_and_reopen
          241  +  execsql { 
          242  +    CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2);
          243  +    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
          244  +  }
          245  +  faultsim_save_and_close
          246  +} {}
          247  +do_faultsim_test rtree3-10.1 -faults oom-* -prep {
          248  +  faultsim_restore_and_reopen
          249  +  execsql { SELECT * FROM rt }
          250  +} -body {
          251  +  execsql { INSERT INTO rt VALUES(1, 2, 3, 4, 5) }
          252  +} -test {
          253  +  faultsim_test_result {1 {UNIQUE constraint failed: rt.ii}} \
          254  +                       {1 {constraint failed}}
          255  +}
          256  +do_faultsim_test rtree3-10.2 -faults oom-* -prep {
          257  +  faultsim_restore_and_reopen
          258  +  execsql { SELECT * FROM rt }
          259  +} -body {
          260  +  execsql { INSERT INTO rt VALUES(2, 2, 3, 5, 4) }
          261  +} -test {
          262  +  faultsim_test_result {1 {rtree constraint failed: rt.(y1<=y2)}} \
          263  +                       {1 {constraint failed}}
          264  +}
          265  +
   237    266   finish_test

Changes to ext/rtree/rtreeC.test.

   344    344     WHERE (x1 BETWEEN xmin AND xmax);
   345    345   } {
   346    346     0 0 1 {SCAN TABLE xdir} 
   347    347     0 1 0 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:B0D1}
   348    348     0 2 2 {SCAN TABLE ydir} 
   349    349     2 4
   350    350   }
   351         -
   352         -finish_test
   353         -
   354         -
   355    351   
   356    352   finish_test

Added ext/rtree/rtreeG.test.

            1  +# 2016-05-32
            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  +# This file contains tests for the r-tree module.
           12  +#
           13  +# Verify that no invalid SQL is run during initialization
           14  +
           15  +if {![info exists testdir]} {
           16  +  set testdir [file join [file dirname [info script]] .. .. test]
           17  +} 
           18  +source $testdir/tester.tcl
           19  +ifcapable !rtree { finish_test ; return }
           20  +
           21  +db close
           22  +sqlite3_shutdown
           23  +test_sqlite3_log [list lappend ::log]
           24  +set ::log [list]
           25  +sqlite3 db test.db
           26  +
           27  +
           28  +set ::log {}
           29  +do_execsql_test rtreeG-1.1 {
           30  +  CREATE VIRTUAL TABLE t1 USING rtree(id,x0,x1,y0,y1);
           31  +} {}
           32  +do_test rtreeG-1.1log {
           33  +  set ::log
           34  +} {}
           35  +
           36  +do_execsql_test rtreeG-1.2 {
           37  +  INSERT INTO t1 VALUES(1,10,15,5,23),(2,20,21,5,23),(3,10,15,20,30);
           38  +  SELECT id from t1 WHERE x0>8 AND x1<16 AND y0>2 AND y1<25;
           39  +} {1}
           40  +do_test rtreeG-1.2log {
           41  +  set ::log
           42  +} {}
           43  +
           44  +db close
           45  +sqlite3 db test.db
           46  +do_execsql_test rtreeG-1.3 {
           47  +  SELECT id from t1 WHERE x0>8 AND x1<16 AND y0>2 AND y1<25;
           48  +} {1}
           49  +do_test rtreeG-1.3log {
           50  +  set ::log
           51  +} {}
           52  +
           53  +do_execsql_test rtreeG-1.4 {
           54  +  DROP TABLE t1;
           55  +} {}
           56  +do_test rtreeG-1.4log {
           57  +  set ::log
           58  +} {}
           59  +
           60  +db close
           61  +sqlite3_shutdown
           62  +test_sqlite3_log
           63  +sqlite3_initialize
           64  +sqlite3 db test.db
           65  +
           66  +finish_test

Changes to main.mk.

   324    324     $(TOP)/src/test_wsd.c
   325    325   
   326    326   # Extensions to be statically loaded.
   327    327   #
   328    328   TESTSRC += \
   329    329     $(TOP)/ext/misc/amatch.c \
   330    330     $(TOP)/ext/misc/closure.c \
          331  +  $(TOP)/ext/misc/csv.c \
   331    332     $(TOP)/ext/misc/eval.c \
   332    333     $(TOP)/ext/misc/fileio.c \
   333    334     $(TOP)/ext/misc/fuzzer.c \
   334    335     $(TOP)/ext/misc/ieee754.c \
   335    336     $(TOP)/ext/misc/nextchar.c \
   336    337     $(TOP)/ext/misc/percentile.c \
   337    338     $(TOP)/ext/misc/regexp.c \
................................................................................
   434    435   
   435    436   # executables needed for testing
   436    437   #
   437    438   TESTPROGS = \
   438    439     testfixture$(EXE) \
   439    440     sqlite3$(EXE) \
   440    441     sqlite3_analyzer$(EXE) \
   441         -  sqldiff$(EXE)
          442  +  sqldiff$(EXE) \
          443  +  dbhash$(EXE)
   442    444   
   443    445   # Databases containing fuzzer test cases
   444    446   #
   445    447   FUZZDATA = \
   446    448     $(TOP)/test/fuzzdata1.db \
   447    449     $(TOP)/test/fuzzdata2.db \
   448    450     $(TOP)/test/fuzzdata3.db \
................................................................................
   470    472   sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
   471    473   	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \
   472    474   		$(TOP)/src/shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
   473    475   
   474    476   sqldiff$(EXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
   475    477   	$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
   476    478   		$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
          479  +
          480  +dbhash$(EXE):	$(TOP)/tool/dbhash.c sqlite3.c sqlite3.h
          481  +	$(TCCX) -o dbhash$(EXE) -DSQLITE_THREADSAFE=0 \
          482  +		$(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) $(THREADLIB)
   477    483   
   478    484   scrub$(EXE):	$(TOP)/ext/misc/scrub.c sqlite3.o
   479    485   	$(TCC) -I. -DSCRUB_STANDALONE -o scrub$(EXE) $(TOP)/ext/misc/scrub.c sqlite3.o $(THREADLIB)
   480    486   
   481    487   srcck1$(EXE):	$(TOP)/tool/srcck1.c
   482    488   	$(BCC) -o srcck1$(EXE) $(TOP)/tool/srcck1.c
   483    489   

Changes to src/btree.c.

   452    452   **
   453    453   ** Verify that the cursor holds the mutex on its BtShared
   454    454   */
   455    455   #ifdef SQLITE_DEBUG
   456    456   static int cursorHoldsMutex(BtCursor *p){
   457    457     return sqlite3_mutex_held(p->pBt->mutex);
   458    458   }
          459  +
          460  +/* Verify that the cursor and the BtShared agree about what is the current
          461  +** database connetion. This is important in shared-cache mode. If the database 
          462  +** connection pointers get out-of-sync, it is possible for routines like
          463  +** btreeInitPage() to reference an stale connection pointer that references a
          464  +** a connection that has already closed.  This routine is used inside assert()
          465  +** statements only and for the purpose of double-checking that the btree code
          466  +** does keep the database connection pointers up-to-date.
          467  +*/
   459    468   static int cursorOwnsBtShared(BtCursor *p){
   460    469     assert( cursorHoldsMutex(p) );
   461    470     return (p->pBtree->db==p->pBt->db);
   462    471   }
   463    472   #endif
   464    473   
   465    474   /*
................................................................................
   611    620   ** If the cursor is open on an intkey table, then the integer key
   612    621   ** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to
   613    622   ** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is 
   614    623   ** set to point to a malloced buffer pCur->nKey bytes in size containing 
   615    624   ** the key.
   616    625   */
   617    626   static int saveCursorKey(BtCursor *pCur){
   618         -  int rc;
          627  +  int rc = SQLITE_OK;
   619    628     assert( CURSOR_VALID==pCur->eState );
   620    629     assert( 0==pCur->pKey );
   621    630     assert( cursorHoldsMutex(pCur) );
   622    631   
   623         -  rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
   624         -  assert( rc==SQLITE_OK );  /* KeySize() cannot fail */
   625         -
   626         -  /* If this is an intKey table, then the above call to BtreeKeySize()
   627         -  ** stores the integer key in pCur->nKey. In this case this value is
   628         -  ** all that is required. Otherwise, if pCur is not open on an intKey
   629         -  ** table, then malloc space for and store the pCur->nKey bytes of key 
   630         -  ** data.  */
   631         -  if( 0==pCur->curIntKey ){
   632         -    void *pKey = sqlite3Malloc( pCur->nKey );
          632  +  if( pCur->curIntKey ){
          633  +    /* Only the rowid is required for a table btree */
          634  +    pCur->nKey = sqlite3BtreeIntegerKey(pCur);
          635  +  }else{
          636  +    /* For an index btree, save the complete key content */
          637  +    void *pKey;
          638  +    pCur->nKey = sqlite3BtreePayloadSize(pCur);
          639  +    pKey = sqlite3Malloc( pCur->nKey );
   633    640       if( pKey ){
   634    641         rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
   635    642         if( rc==SQLITE_OK ){
   636    643           pCur->pKey = pKey;
   637    644         }else{
   638    645           sqlite3_free(pKey);
   639    646         }
................................................................................
  4264   4271   */
  4265   4272   int sqlite3BtreeCursorIsValid(BtCursor *pCur){
  4266   4273     return pCur && pCur->eState==CURSOR_VALID;
  4267   4274   }
  4268   4275   #endif /* NDEBUG */
  4269   4276   
  4270   4277   /*
  4271         -** Set *pSize to the size of the buffer needed to hold the value of
  4272         -** the key for the current entry.  If the cursor is not pointing
  4273         -** to a valid entry, *pSize is set to 0. 
  4274         -**
  4275         -** For a table with the INTKEY flag set, this routine returns the key
  4276         -** itself, not the number of bytes in the key.
  4277         -**
  4278         -** The caller must position the cursor prior to invoking this routine.
  4279         -** 
  4280         -** This routine cannot fail.  It always returns SQLITE_OK.  
         4278  +** Return the value of the integer key or "rowid" for a table btree.
         4279  +** This routine is only valid for a cursor that is pointing into a
         4280  +** ordinary table btree.  If the cursor points to an index btree or
         4281  +** is invalid, the result of this routine is undefined.
  4281   4282   */
  4282         -int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
         4283  +i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
  4283   4284     assert( cursorHoldsMutex(pCur) );
  4284   4285     assert( pCur->eState==CURSOR_VALID );
         4286  +  assert( pCur->curIntKey );
  4285   4287     getCellInfo(pCur);
  4286         -  *pSize = pCur->info.nKey;
  4287         -  return SQLITE_OK;
         4288  +  return pCur->info.nKey;
  4288   4289   }
  4289   4290   
  4290   4291   /*
  4291         -** Set *pSize to the number of bytes of data in the entry the
  4292         -** cursor currently points to.
         4292  +** Return the number of bytes of payload for the entry that pCur is
         4293  +** currently pointing to.  For table btrees, this will be the amount
         4294  +** of data.  For index btrees, this will be the size of the key.
  4293   4295   **
  4294   4296   ** The caller must guarantee that the cursor is pointing to a non-NULL
  4295   4297   ** valid entry.  In other words, the calling procedure must guarantee
  4296   4298   ** that the cursor has Cursor.eState==CURSOR_VALID.
  4297         -**
  4298         -** Failure is not possible.  This function always returns SQLITE_OK.
  4299         -** It might just as well be a procedure (returning void) but we continue
  4300         -** to return an integer result code for historical reasons.
  4301   4299   */
  4302         -int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  4303         -  assert( cursorOwnsBtShared(pCur) );
         4300  +u32 sqlite3BtreePayloadSize(BtCursor *pCur){
         4301  +  assert( cursorHoldsMutex(pCur) );
  4304   4302     assert( pCur->eState==CURSOR_VALID );
  4305         -  assert( pCur->iPage>=0 );
  4306         -  assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
  4307         -  assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
  4308   4303     getCellInfo(pCur);
  4309         -  *pSize = pCur->info.nPayload;
  4310         -  return SQLITE_OK;
         4304  +  return pCur->info.nPayload;
  4311   4305   }
  4312   4306   
  4313   4307   /*
  4314   4308   ** Given the page number of an overflow page in the database (parameter
  4315   4309   ** ovfl), this function finds the page number of the next page in the 
  4316   4310   ** linked list of overflow pages. If possible, it uses the auto-vacuum
  4317   4311   ** pointer-map data instead of reading the content of page ovfl to do so. 
................................................................................
  4745   4739   ** including calls from other threads against the same cache.
  4746   4740   ** Hence, a mutex on the BtShared should be held prior to calling
  4747   4741   ** this routine.
  4748   4742   **
  4749   4743   ** These routines is used to get quick access to key and data
  4750   4744   ** in the common case where no overflow pages are used.
  4751   4745   */
  4752         -const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){
  4753         -  return fetchPayload(pCur, pAmt);
  4754         -}
  4755         -const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
         4746  +const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){
  4756   4747     return fetchPayload(pCur, pAmt);
  4757   4748   }
  4758   4749   
  4759   4750   
  4760   4751   /*
  4761   4752   ** Move the cursor down to a new child page.  The newPgno argument is the
  4762   4753   ** page number of the child page to move to.
................................................................................
  5081   5072     int rc;
  5082   5073     RecordCompare xRecordCompare;
  5083   5074   
  5084   5075     assert( cursorOwnsBtShared(pCur) );
  5085   5076     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  5086   5077     assert( pRes );
  5087   5078     assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
         5079  +  assert( pCur->eState!=CURSOR_VALID || (pIdxKey==0)==(pCur->curIntKey!=0) );
  5088   5080   
  5089   5081     /* If the cursor is already positioned at the point we are trying
  5090   5082     ** to move to, then just return without doing any work */
  5091         -  if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
  5092         -   && pCur->curIntKey 
         5083  +  if( pIdxKey==0
         5084  +   && pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
  5093   5085     ){
  5094   5086       if( pCur->info.nKey==intKey ){
  5095   5087         *pRes = 0;
  5096   5088         return SQLITE_OK;
  5097   5089       }
  5098   5090       if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){
  5099   5091         *pRes = -1;

Changes to src/btree.h.

   280    280   int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
   281    281                          int bias, int seekResult);
   282    282   int sqlite3BtreeFirst(BtCursor*, int *pRes);
   283    283   int sqlite3BtreeLast(BtCursor*, int *pRes);
   284    284   int sqlite3BtreeNext(BtCursor*, int *pRes);
   285    285   int sqlite3BtreeEof(BtCursor*);
   286    286   int sqlite3BtreePrevious(BtCursor*, int *pRes);
   287         -int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
          287  +i64 sqlite3BtreeIntegerKey(BtCursor*);
   288    288   int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
   289         -const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt);
   290         -const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt);
   291         -int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
          289  +const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
          290  +u32 sqlite3BtreePayloadSize(BtCursor*);
   292    291   int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
   293    292   
   294    293   char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
   295    294   struct Pager *sqlite3BtreePager(Btree*);
   296    295   
   297    296   int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
   298    297   void sqlite3BtreeIncrblobCursor(BtCursor *);

Changes to src/build.c.

   334    334   **
   335    335   ** The difference between this routine and sqlite3FindTable() is that this
   336    336   ** routine leaves an error message in pParse->zErrMsg where
   337    337   ** sqlite3FindTable() does not.
   338    338   */
   339    339   Table *sqlite3LocateTable(
   340    340     Parse *pParse,         /* context in which to report errors */
   341         -  int isView,            /* True if looking for a VIEW rather than a TABLE */
          341  +  u32 flags,             /* LOCATE_VIEW or LOCATE_NOERR */
   342    342     const char *zName,     /* Name of the table we are looking for */
   343    343     const char *zDbase     /* Name of the database.  Might be NULL */
   344    344   ){
   345    345     Table *p;
   346    346   
   347    347     /* Read the database schema. If an error occurs, leave an error message
   348    348     ** and code in pParse and return NULL. */
   349    349     if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
   350    350       return 0;
   351    351     }
   352    352   
   353    353     p = sqlite3FindTable(pParse->db, zName, zDbase);
   354    354     if( p==0 ){
   355         -    const char *zMsg = isView ? "no such view" : "no such table";
          355  +    const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
   356    356   #ifndef SQLITE_OMIT_VIRTUALTABLE
   357    357       if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
   358    358         /* If zName is the not the name of a table in the schema created using
   359    359         ** CREATE, then check to see if it is the name of an virtual table that
   360    360         ** can be an eponymous virtual table. */
   361    361         Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
   362    362         if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
   363    363           return pMod->pEpoTab;
   364    364         }
   365    365       }
   366    366   #endif
   367         -    if( zDbase ){
   368         -      sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
   369         -    }else{
   370         -      sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
          367  +    if( (flags & LOCATE_NOERR)==0 ){
          368  +      if( zDbase ){
          369  +        sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
          370  +      }else{
          371  +        sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
          372  +      }
          373  +      pParse->checkSchema = 1;
   371    374       }
   372         -    pParse->checkSchema = 1;
   373    375     }
   374    376   
   375    377     return p;
   376    378   }
   377    379   
   378    380   /*
   379    381   ** Locate the table identified by *p.
................................................................................
   382    384   ** sqlite3LocateTable() and this function is that this function restricts
   383    385   ** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
   384    386   ** non-NULL if it is part of a view or trigger program definition. See
   385    387   ** sqlite3FixSrcList() for details.
   386    388   */
   387    389   Table *sqlite3LocateTableItem(
   388    390     Parse *pParse, 
   389         -  int isView, 
          391  +  u32 flags,
   390    392     struct SrcList_item *p
   391    393   ){
   392    394     const char *zDb;
   393    395     assert( p->pSchema==0 || p->zDatabase==0 );
   394    396     if( p->pSchema ){
   395    397       int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
   396    398       zDb = pParse->db->aDb[iDb].zName;
   397    399     }else{
   398    400       zDb = p->zDatabase;
   399    401     }
   400         -  return sqlite3LocateTable(pParse, isView, p->zName, zDb);
          402  +  return sqlite3LocateTable(pParse, flags, p->zName, zDb);
   401    403   }
   402    404   
   403    405   /*
   404    406   ** Locate the in-memory structure that describes 
   405    407   ** a particular index given the name of that index
   406    408   ** and the name of the database that contains the index.
   407    409   ** Return NULL if not found.
................................................................................
   601    603     ** lookaside, this number should not change. */
   602    604     TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ?
   603    605                            db->lookaside.nOut : 0 );
   604    606   
   605    607     /* Delete all indices associated with this table. */
   606    608     for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
   607    609       pNext = pIndex->pNext;
   608         -    assert( pIndex->pSchema==pTable->pSchema );
   609         -    if( !db || db->pnBytesFreed==0 ){
          610  +    assert( pIndex->pSchema==pTable->pSchema
          611  +         || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) );
          612  +    if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){
   610    613         char *zName = pIndex->zName; 
   611    614         TESTONLY ( Index *pOld = ) sqlite3HashInsert(
   612    615            &pIndex->pSchema->idxHash, zName, 0
   613    616         );
   614    617         assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
   615    618         assert( pOld==pIndex || pOld==0 );
   616    619       }
................................................................................
  1284   1287     int autoInc,      /* True if the AUTOINCREMENT keyword is present */
  1285   1288     int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
  1286   1289   ){
  1287   1290     Table *pTab = pParse->pNewTable;
  1288   1291     Column *pCol = 0;
  1289   1292     int iCol = -1, i;
  1290   1293     int nTerm;
  1291         -  if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
         1294  +  if( pTab==0 ) goto primary_key_exit;
  1292   1295     if( pTab->tabFlags & TF_HasPrimaryKey ){
  1293   1296       sqlite3ErrorMsg(pParse, 
  1294   1297         "table \"%s\" has more than one primary key", pTab->zName);
  1295   1298       goto primary_key_exit;
  1296   1299     }
  1297   1300     pTab->tabFlags |= TF_HasPrimaryKey;
  1298   1301     if( pList==0 ){
................................................................................
  1330   1333       if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
  1331   1334     }else if( autoInc ){
  1332   1335   #ifndef SQLITE_OMIT_AUTOINCREMENT
  1333   1336       sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
  1334   1337          "INTEGER PRIMARY KEY");
  1335   1338   #endif
  1336   1339     }else{
  1337         -    Index *p;
  1338         -    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
  1339         -                           0, sortOrder, 0);
  1340         -    if( p ){
  1341         -      p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
  1342         -    }
         1340  +    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
         1341  +                           0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY);
  1343   1342       pList = 0;
  1344   1343     }
  1345   1344   
  1346   1345   primary_key_exit:
  1347   1346     sqlite3ExprListDelete(pParse->db, pList);
  1348   1347     return;
  1349   1348   }
................................................................................
  1652   1651   /*
  1653   1652   ** This routine runs at the end of parsing a CREATE TABLE statement that
  1654   1653   ** has a WITHOUT ROWID clause.  The job of this routine is to convert both
  1655   1654   ** internal schema data structures and the generated VDBE code so that they
  1656   1655   ** are appropriate for a WITHOUT ROWID table instead of a rowid table.
  1657   1656   ** Changes include:
  1658   1657   **
  1659         -**     (1)  Convert the OP_CreateTable into an OP_CreateIndex.  There is
         1658  +**     (1)  Set all columns of the PRIMARY KEY schema object to be NOT NULL.
         1659  +**     (2)  Convert the OP_CreateTable into an OP_CreateIndex.  There is
  1660   1660   **          no rowid btree for a WITHOUT ROWID.  Instead, the canonical
  1661   1661   **          data storage is a covering index btree.
  1662         -**     (2)  Bypass the creation of the sqlite_master table entry
         1662  +**     (3)  Bypass the creation of the sqlite_master table entry
  1663   1663   **          for the PRIMARY KEY as the primary key index is now
  1664   1664   **          identified by the sqlite_master table entry of the table itself.
  1665         -**     (3)  Set the Index.tnum of the PRIMARY KEY Index object in the
         1665  +**     (4)  Set the Index.tnum of the PRIMARY KEY Index object in the
  1666   1666   **          schema to the rootpage from the main table.
  1667         -**     (4)  Set all columns of the PRIMARY KEY schema object to be NOT NULL.
  1668   1667   **     (5)  Add all table columns to the PRIMARY KEY Index object
  1669   1668   **          so that the PRIMARY KEY is a covering index.  The surplus
  1670   1669   **          columns are part of KeyInfo.nXField and are not used for
  1671   1670   **          sorting or lookup or uniqueness checks.
  1672   1671   **     (6)  Replace the rowid tail on all automatically generated UNIQUE
  1673   1672   **          indices with the PRIMARY KEY columns.
         1673  +**
         1674  +** For virtual tables, only (1) is performed.
  1674   1675   */
  1675   1676   static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
  1676   1677     Index *pIdx;
  1677   1678     Index *pPk;
  1678   1679     int nPk;
  1679   1680     int i, j;
  1680   1681     sqlite3 *db = pParse->db;
  1681   1682     Vdbe *v = pParse->pVdbe;
         1683  +
         1684  +  /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
         1685  +  */
         1686  +  if( !db->init.imposterTable ){
         1687  +    for(i=0; i<pTab->nCol; i++){
         1688  +      if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){
         1689  +        pTab->aCol[i].notNull = OE_Abort;
         1690  +      }
         1691  +    }
         1692  +  }
         1693  +
         1694  +  /* The remaining transformations only apply to b-tree tables, not to
         1695  +  ** virtual tables */
         1696  +  if( IN_DECLARE_VTAB ) return;
  1682   1697   
  1683   1698     /* Convert the OP_CreateTable opcode that would normally create the
  1684   1699     ** root-page for the table into an OP_CreateIndex opcode.  The index
  1685   1700     ** created will become the PRIMARY KEY index.
  1686   1701     */
  1687   1702     if( pParse->addrCrTab ){
  1688   1703       assert( v );
................................................................................
  1697   1712       Token ipkToken;
  1698   1713       sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
  1699   1714       pList = sqlite3ExprListAppend(pParse, 0, 
  1700   1715                     sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
  1701   1716       if( pList==0 ) return;
  1702   1717       pList->a[0].sortOrder = pParse->iPkSortOrder;
  1703   1718       assert( pParse->pNewTable==pTab );
  1704         -    pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
  1705         -    if( pPk==0 ) return;
  1706         -    pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
         1719  +    sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
         1720  +                       SQLITE_IDXTYPE_PRIMARYKEY);
         1721  +    if( db->mallocFailed ) return;
         1722  +    pPk = sqlite3PrimaryKeyIndex(pTab);
  1707   1723       pTab->iPKey = -1;
  1708   1724     }else{
  1709   1725       pPk = sqlite3PrimaryKeyIndex(pTab);
  1710   1726   
  1711   1727       /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
  1712   1728       ** table entry. This is only required if currently generating VDBE
  1713   1729       ** code for a CREATE TABLE (not when parsing one as part of reading
................................................................................
  1727   1743           pPk->nColumn--;
  1728   1744         }else{
  1729   1745           pPk->aiColumn[j++] = pPk->aiColumn[i];
  1730   1746         }
  1731   1747       }
  1732   1748       pPk->nKeyCol = j;
  1733   1749     }
  1734         -  pPk->isCovering = 1;
  1735   1750     assert( pPk!=0 );
         1751  +  pPk->isCovering = 1;
         1752  +  if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
  1736   1753     nPk = pPk->nKeyCol;
  1737   1754   
  1738         -  /* Make sure every column of the PRIMARY KEY is NOT NULL.  (Except,
  1739         -  ** do not enforce this for imposter tables.) */
  1740         -  if( !db->init.imposterTable ){
  1741         -    for(i=0; i<nPk; i++){
  1742         -      pTab->aCol[pPk->aiColumn[i]].notNull = OE_Abort;
  1743         -    }
  1744         -    pPk->uniqNotNull = 1;
  1745         -  }
  1746         -
  1747   1755     /* The root page of the PRIMARY KEY is the table root page */
  1748   1756     pPk->tnum = pTab->tnum;
  1749   1757   
  1750   1758     /* Update the in-memory representation of all UNIQUE indices by converting
  1751   1759     ** the final rowid column into one or more columns of the PRIMARY KEY.
  1752   1760     */
  1753   1761     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
................................................................................
  2494   2502     if( db->mallocFailed ){
  2495   2503       goto exit_drop_table;
  2496   2504     }
  2497   2505     assert( pParse->nErr==0 );
  2498   2506     assert( pName->nSrc==1 );
  2499   2507     if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
  2500   2508     if( noErr ) db->suppressErr++;
         2509  +  assert( isView==0 || isView==LOCATE_VIEW );
  2501   2510     pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
  2502   2511     if( noErr ) db->suppressErr--;
  2503   2512   
  2504   2513     if( pTab==0 ){
  2505   2514       if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
  2506   2515       goto exit_drop_table;
  2507   2516     }
................................................................................
  2864   2873   ** UNIQUE constraint.  If pTable and pIndex are NULL, use pParse->pNewTable
  2865   2874   ** as the table to be indexed.  pParse->pNewTable is a table that is
  2866   2875   ** currently being constructed by a CREATE TABLE statement.
  2867   2876   **
  2868   2877   ** pList is a list of columns to be indexed.  pList will be NULL if this
  2869   2878   ** is a primary key or unique-constraint on the most recent column added
  2870   2879   ** to the table currently under construction.  
  2871         -**
  2872         -** If the index is created successfully, return a pointer to the new Index
  2873         -** structure. This is used by sqlite3AddPrimaryKey() to mark the index
  2874         -** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY)
  2875   2880   */
  2876         -Index *sqlite3CreateIndex(
         2881  +void sqlite3CreateIndex(
  2877   2882     Parse *pParse,     /* All information about this parse */
  2878   2883     Token *pName1,     /* First part of index name. May be NULL */
  2879   2884     Token *pName2,     /* Second part of index name. May be NULL */
  2880   2885     SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  2881   2886     ExprList *pList,   /* A list of columns to be indexed */
  2882   2887     int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  2883   2888     Token *pStart,     /* The CREATE token that begins this statement */
  2884   2889     Expr *pPIWhere,    /* WHERE clause for partial indices */
  2885   2890     int sortOrder,     /* Sort order of primary key when pList==NULL */
  2886         -  int ifNotExist     /* Omit error if index already exists */
         2891  +  int ifNotExist,    /* Omit error if index already exists */
         2892  +  u8 idxType         /* The index type */
  2887   2893   ){
  2888         -  Index *pRet = 0;     /* Pointer to return */
  2889   2894     Table *pTab = 0;     /* Table to be indexed */
  2890   2895     Index *pIndex = 0;   /* The index to be created */
  2891   2896     char *zName = 0;     /* Name of the index */
  2892   2897     int nName;           /* Number of characters in zName */
  2893   2898     int i, j;
  2894   2899     DbFixer sFix;        /* For assigning database names to pTable */
  2895   2900     int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
................................................................................
  2899   2904     Token *pName = 0;    /* Unqualified name of the index to create */
  2900   2905     struct ExprList_item *pListItem; /* For looping over pList */
  2901   2906     int nExtra = 0;                  /* Space allocated for zExtra[] */
  2902   2907     int nExtraCol;                   /* Number of extra columns needed */
  2903   2908     char *zExtra = 0;                /* Extra space after the Index object */
  2904   2909     Index *pPk = 0;      /* PRIMARY KEY index for WITHOUT ROWID tables */
  2905   2910   
  2906         -  if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
         2911  +  if( db->mallocFailed || pParse->nErr>0 ){
         2912  +    goto exit_create_index;
         2913  +  }
         2914  +  if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
  2907   2915       goto exit_create_index;
  2908   2916     }
  2909   2917     if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
  2910   2918       goto exit_create_index;
  2911   2919     }
  2912   2920   
  2913   2921     /*
................................................................................
  3088   3096     assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
  3089   3097     pIndex->zName = zExtra;
  3090   3098     zExtra += nName + 1;
  3091   3099     memcpy(pIndex->zName, zName, nName+1);
  3092   3100     pIndex->pTable = pTab;
  3093   3101     pIndex->onError = (u8)onError;
  3094   3102     pIndex->uniqNotNull = onError!=OE_None;
  3095         -  pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE;
         3103  +  pIndex->idxType = idxType;
  3096   3104     pIndex->pSchema = db->aDb[iDb].pSchema;
  3097   3105     pIndex->nKeyCol = pList->nExpr;
  3098   3106     if( pPIWhere ){
  3099   3107       sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
  3100   3108       pIndex->pPartIdxWhere = pPIWhere;
  3101   3109       pPIWhere = 0;
  3102   3110     }
................................................................................
  3268   3276               sqlite3ErrorMsg(pParse, 
  3269   3277                   "conflicting ON CONFLICT clauses specified", 0);
  3270   3278             }
  3271   3279             if( pIdx->onError==OE_Default ){
  3272   3280               pIdx->onError = pIndex->onError;
  3273   3281             }
  3274   3282           }
  3275         -        pRet = pIdx;
         3283  +        if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
  3276   3284           goto exit_create_index;
  3277   3285         }
  3278   3286       }
  3279   3287     }
  3280   3288   
  3281   3289     /* Link the new Index structure to its table and to the other
  3282   3290     ** in-memory database structures. 
  3283   3291     */
  3284   3292     assert( pParse->nErr==0 );
  3285   3293     if( db->init.busy ){
  3286   3294       Index *p;
         3295  +    assert( !IN_DECLARE_VTAB );
  3287   3296       assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
  3288   3297       p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
  3289   3298                             pIndex->zName, pIndex);
  3290   3299       if( p ){
  3291   3300         assert( p==pIndex );  /* Malloc must have failed */
  3292   3301         sqlite3OomFault(db);
  3293   3302         goto exit_create_index;
................................................................................
  3386   3395         Index *pOther = pTab->pIndex;
  3387   3396         while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
  3388   3397           pOther = pOther->pNext;
  3389   3398         }
  3390   3399         pIndex->pNext = pOther->pNext;
  3391   3400         pOther->pNext = pIndex;
  3392   3401       }
  3393         -    pRet = pIndex;
  3394   3402       pIndex = 0;
  3395   3403     }
  3396   3404   
  3397   3405     /* Clean up before exiting */
  3398   3406   exit_create_index:
  3399   3407     if( pIndex ) freeIndex(db, pIndex);
  3400   3408     sqlite3ExprDelete(db, pPIWhere);
  3401   3409     sqlite3ExprListDelete(db, pList);
  3402   3410     sqlite3SrcListDelete(db, pTblName);
  3403   3411     sqlite3DbFree(db, zName);
  3404         -  return pRet;
  3405   3412   }
  3406   3413   
  3407   3414   /*
  3408   3415   ** Fill the Index.aiRowEst[] array with default information - information
  3409   3416   ** to be used when we have not run the ANALYZE command.
  3410   3417   **
  3411   3418   ** aiRowEst[0] is supposed to contain the number of elements in the index.
................................................................................
  3426   3433     /*                10,  9,  8,  7,  6 */
  3427   3434     LogEst aVal[] = { 33, 32, 30, 28, 26 };
  3428   3435     LogEst *a = pIdx->aiRowLogEst;
  3429   3436     int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
  3430   3437     int i;
  3431   3438   
  3432   3439     /* Set the first entry (number of rows in the index) to the estimated 
  3433         -  ** number of rows in the table. Or 10, if the estimated number of rows 
  3434         -  ** in the table is less than that.  */
         3440  +  ** number of rows in the table, or half the number of rows in the table
         3441  +  ** for a partial index.   But do not let the estimate drop below 10. */
  3435   3442     a[0] = pIdx->pTable->nRowLogEst;
  3436         -  if( a[0]<33 ) a[0] = 33;        assert( 33==sqlite3LogEst(10) );
         3443  +  if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10;  assert( 10==sqlite3LogEst(2) );
         3444  +  if( a[0]<33 ) a[0] = 33;                  assert( 33==sqlite3LogEst(10) );
  3437   3445   
  3438   3446     /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
  3439   3447     ** 6 and each subsequent value (if any) is 5.  */
  3440   3448     memcpy(&a[1], aVal, nCopy*sizeof(LogEst));
  3441   3449     for(i=nCopy+1; i<=pIdx->nKeyCol; i++){
  3442   3450       a[i] = 23;                    assert( 23==sqlite3LogEst(5) );
  3443   3451     }
................................................................................
  4311   4319     sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
  4312   4320   }
  4313   4321   #endif
  4314   4322   
  4315   4323   /*
  4316   4324   ** Return a KeyInfo structure that is appropriate for the given Index.
  4317   4325   **
  4318         -** The KeyInfo structure for an index is cached in the Index object.
  4319         -** So there might be multiple references to the returned pointer.  The
  4320         -** caller should not try to modify the KeyInfo object.
  4321         -**
  4322   4326   ** The caller should invoke sqlite3KeyInfoUnref() on the returned object
  4323   4327   ** when it has finished using it.
  4324   4328   */
  4325   4329   KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
  4326   4330     int i;
  4327   4331     int nCol = pIdx->nColumn;
  4328   4332     int nKey = pIdx->nKeyCol;

Changes to src/ctime.c.

    41     41   #endif
    42     42   #if SQLITE_CASE_SENSITIVE_LIKE
    43     43     "CASE_SENSITIVE_LIKE",
    44     44   #endif
    45     45   #if SQLITE_CHECK_PAGES
    46     46     "CHECK_PAGES",
    47     47   #endif
           48  +#if defined(__clang__) && defined(__clang_version__)
           49  +  "COMPILER=clang-" __clang_version__,
           50  +#elif defined(_MSC_VER)
           51  +  "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER),
           52  +#elif defined(__GNUC__) && defined(__VERSION__)
           53  +  "COMPILER=gcc-" __VERSION__,
           54  +#endif
    48     55   #if SQLITE_COVERAGE_TEST
    49     56     "COVERAGE_TEST",
    50     57   #endif
    51     58   #if SQLITE_DEBUG
    52     59     "DEBUG",
    53     60   #endif
    54     61   #if SQLITE_DEFAULT_LOCKING_MODE
................................................................................
    60     67   #if SQLITE_DISABLE_DIRSYNC
    61     68     "DISABLE_DIRSYNC",
    62     69   #endif
    63     70   #if SQLITE_DISABLE_LFS
    64     71     "DISABLE_LFS",
    65     72   #endif
    66     73   #if SQLITE_ENABLE_8_3_NAMES
    67         -  "ENABLE_8_3_NAMES",
           74  +  "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES),
    68     75   #endif
    69     76   #if SQLITE_ENABLE_API_ARMOR
    70     77     "ENABLE_API_ARMOR",
    71     78   #endif
    72     79   #if SQLITE_ENABLE_ATOMIC_WRITE
    73     80     "ENABLE_ATOMIC_WRITE",
    74     81   #endif

Changes to src/dbstat.c.

    54     54   **   the overflow pages associated with a cell will appear earlier in the
    55     55   **   sort-order than its child page:
    56     56   **
    57     57   **      '/1c2/000/'               // Left-most child of 451st child of root
    58     58   */
    59     59   #define VTAB_SCHEMA                                                         \
    60     60     "CREATE TABLE xx( "                                                       \
    61         -  "  name       STRING,           /* Name of table or index */"             \
    62         -  "  path       INTEGER,          /* Path to page from root */"             \
           61  +  "  name       TEXT,             /* Name of table or index */"             \
           62  +  "  path       TEXT,             /* Path to page from root */"             \
    63     63     "  pageno     INTEGER,          /* Page number */"                        \
    64         -  "  pagetype   STRING,           /* 'internal', 'leaf' or 'overflow' */"   \
           64  +  "  pagetype   TEXT,             /* 'internal', 'leaf' or 'overflow' */"   \
    65     65     "  ncell      INTEGER,          /* Cells on page (0 for overflow) */"     \
    66     66     "  payload    INTEGER,          /* Bytes of payload on this page */"      \
    67     67     "  unused     INTEGER,          /* Bytes of unused space on this page */" \
    68     68     "  mx_payload INTEGER,          /* Largest payload size of all cells */"  \
    69     69     "  pgoffset   INTEGER,          /* Offset of page in file */"             \
    70     70     "  pgsize     INTEGER,          /* Size of the page */"                   \
    71     71     "  schema     TEXT HIDDEN       /* Database schema being analyzed */"     \

Changes to src/expr.c.

  2218   2218           sqlite3VdbeJumpHere(v, addr1);
  2219   2219         }
  2220   2220       }
  2221   2221     
  2222   2222       if( eType==IN_INDEX_ROWID ){
  2223   2223         /* In this case, the RHS is the ROWID of table b-tree
  2224   2224         */
  2225         -      sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
  2226         -      sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
         2225  +      sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, r1);
  2227   2226         VdbeCoverage(v);
  2228   2227       }else{
  2229   2228         /* In this case, the RHS is an index b-tree.
  2230   2229         */
  2231   2230         sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);
  2232   2231     
  2233   2232         /* If the set membership test fails, then the result of the 
................................................................................
  2532   2531     int regOut      /* Extract the value into this register */
  2533   2532   ){
  2534   2533     if( iCol<0 || iCol==pTab->iPKey ){
  2535   2534       sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
  2536   2535     }else{
  2537   2536       int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
  2538   2537       int x = iCol;
  2539         -    if( !HasRowid(pTab) ){
         2538  +    if( !HasRowid(pTab) && !IsVirtual(pTab) ){
  2540   2539         x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
  2541   2540       }
  2542   2541       sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
  2543   2542     }
  2544   2543     if( iCol>=0 ){
  2545   2544       sqlite3ColumnDefault(v, pTab, iCol, regOut);
  2546   2545     }

Changes to src/fkey.c.

  1368   1368   ** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
  1369   1369   ** hash table.
  1370   1370   */
  1371   1371   void sqlite3FkDelete(sqlite3 *db, Table *pTab){
  1372   1372     FKey *pFKey;                    /* Iterator variable */
  1373   1373     FKey *pNext;                    /* Copy of pFKey->pNextFrom */
  1374   1374   
  1375         -  assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
         1375  +  assert( db==0 || IsVirtual(pTab)
         1376  +         || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
  1376   1377     for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){
  1377   1378   
  1378   1379       /* Remove the FK from the fkeyHash hash table. */
  1379   1380       if( !db || db->pnBytesFreed==0 ){
  1380   1381         if( pFKey->pPrevTo ){
  1381   1382           pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
  1382   1383         }else{

Changes to src/func.c.

   736    736             return 0;
   737    737           }
   738    738           continue;
   739    739         }
   740    740       }
   741    741       c2 = Utf8Read(zString);
   742    742       if( c==c2 ) continue;
   743         -    if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
          743  +    if( noCase  && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){
   744    744         continue;
   745    745       }
   746    746       if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
   747    747       return 0;
   748    748     }
   749    749     return *zString==0;
   750    750   }

Changes to src/loadext.c.

   442    442     int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   443    443     char *zErrmsg = 0;
   444    444     const char *zEntry;
   445    445     char *zAltEntry = 0;
   446    446     void **aHandle;
   447    447     u64 nMsg = 300 + sqlite3Strlen30(zFile);
   448    448     int ii;
          449  +  int rc;
   449    450   
   450    451     /* Shared library endings to try if zFile cannot be loaded as written */
   451    452     static const char *azEndings[] = {
   452    453   #if SQLITE_OS_WIN
   453    454        "dll"   
   454    455   #elif defined(__APPLE__)
   455    456        "dylib"
................................................................................
   544    545         }
   545    546       }
   546    547       sqlite3OsDlClose(pVfs, handle);
   547    548       sqlite3_free(zAltEntry);
   548    549       return SQLITE_ERROR;
   549    550     }
   550    551     sqlite3_free(zAltEntry);
   551         -  if( xInit(db, &zErrmsg, &sqlite3Apis) ){
          552  +  rc = xInit(db, &zErrmsg, &sqlite3Apis);
          553  +  if( rc ){
          554  +    if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK;
   552    555       if( pzErrMsg ){
   553    556         *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
   554    557       }
   555    558       sqlite3_free(zErrmsg);
   556    559       sqlite3OsDlClose(pVfs, handle);
   557    560       return SQLITE_ERROR;
   558    561     }

Changes to src/os_win.c.

  5274   5274   */
  5275   5275   static int winFullPathname(
  5276   5276     sqlite3_vfs *pVfs,            /* Pointer to vfs object */
  5277   5277     const char *zRelative,        /* Possibly relative input path */
  5278   5278     int nFull,                    /* Size of output buffer in bytes */
  5279   5279     char *zFull                   /* Output buffer */
  5280   5280   ){
         5281  +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
         5282  +  DWORD nByte;
         5283  +  void *zConverted;
         5284  +  char *zOut;
         5285  +#endif
         5286  +
         5287  +  /* If this path name begins with "/X:", where "X" is any alphabetic
         5288  +  ** character, discard the initial "/" from the pathname.
         5289  +  */
         5290  +  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
         5291  +    zRelative++;
         5292  +  }
  5281   5293   
  5282   5294   #if defined(__CYGWIN__)
  5283   5295     SimulateIOError( return SQLITE_ERROR );
  5284   5296     UNUSED_PARAMETER(nFull);
  5285   5297     assert( nFull>=pVfs->mxPathname );
  5286   5298     if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
  5287   5299       /*
................................................................................
  5352   5364     }else{
  5353   5365       sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
  5354   5366     }
  5355   5367     return SQLITE_OK;
  5356   5368   #endif
  5357   5369   
  5358   5370   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  5359         -  DWORD nByte;
  5360         -  void *zConverted;
  5361         -  char *zOut;
  5362         -
  5363         -  /* If this path name begins with "/X:", where "X" is any alphabetic
  5364         -  ** character, discard the initial "/" from the pathname.
  5365         -  */
  5366         -  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
  5367         -    zRelative++;
  5368         -  }
  5369         -
  5370   5371     /* It's odd to simulate an io-error here, but really this is just
  5371   5372     ** using the io-error infrastructure to test that SQLite handles this
  5372   5373     ** function failing. This function could fail if, for example, the
  5373   5374     ** current working directory has been unlinked.
  5374   5375     */
  5375   5376     SimulateIOError( return SQLITE_ERROR );
  5376   5377     if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){

Changes to src/parse.y.

   296    296   // In addition to the type name, we also care about the primary key and
   297    297   // UNIQUE constraints.
   298    298   //
   299    299   ccons ::= NULL onconf.
   300    300   ccons ::= NOT NULL onconf(R).    {sqlite3AddNotNull(pParse, R);}
   301    301   ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
   302    302                                    {sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
   303         -ccons ::= UNIQUE onconf(R).      {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0);}
          303  +ccons ::= UNIQUE onconf(R).      {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0,
          304  +                                   SQLITE_IDXTYPE_UNIQUE);}
   304    305   ccons ::= CHECK LP expr(X) RP.   {sqlite3AddCheckConstraint(pParse,X.pExpr);}
   305    306   ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
   306    307                                    {sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
   307    308   ccons ::= defer_subclause(D).    {sqlite3DeferForeignKey(pParse,D);}
   308    309   ccons ::= COLLATE ids(C).        {sqlite3AddCollateType(pParse, &C);}
   309    310   
   310    311   // The optional AUTOINCREMENT keyword
................................................................................
   345    346   conslist ::= tcons.
   346    347   tconscomma ::= COMMA.            {pParse->constraintName.n = 0;}
   347    348   tconscomma ::= .
   348    349   tcons ::= CONSTRAINT nm(X).      {pParse->constraintName = X;}
   349    350   tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
   350    351                                    {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
   351    352   tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
   352         -                                 {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);}
          353  +                                 {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,
          354  +                                       SQLITE_IDXTYPE_UNIQUE);}
   353    355   tcons ::= CHECK LP expr(E) RP onconf.
   354    356                                    {sqlite3AddCheckConstraint(pParse,E.pExpr);}
   355    357   tcons ::= FOREIGN KEY LP eidlist(FA) RP
   356    358             REFERENCES nm(T) eidlist_opt(TA) refargs(R) defer_subclause_opt(D). {
   357    359       sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
   358    360       sqlite3DeferForeignKey(pParse, D);
   359    361   }
................................................................................
  1194   1196   
  1195   1197   ///////////////////////////// The CREATE INDEX command ///////////////////////
  1196   1198   //
  1197   1199   cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
  1198   1200           ON nm(Y) LP sortlist(Z) RP where_opt(W). {
  1199   1201     sqlite3CreateIndex(pParse, &X, &D, 
  1200   1202                        sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U,
  1201         -                      &S, W, SQLITE_SO_ASC, NE);
         1203  +                      &S, W, SQLITE_SO_ASC, NE, SQLITE_IDXTYPE_APPDEF);
  1202   1204   }
  1203   1205   
  1204   1206   %type uniqueflag {int}
  1205   1207   uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
  1206   1208   uniqueflag(A) ::= .        {A = OE_None;}
  1207   1209   
  1208   1210   

Changes to src/pragma.c.

  1048   1048     ** name:       Column name
  1049   1049     ** type:       Column declaration type.
  1050   1050     ** notnull:    True if 'NOT NULL' is part of column declaration
  1051   1051     ** dflt_value: The default value for the column, if any.
  1052   1052     */
  1053   1053     case PragTyp_TABLE_INFO: if( zRight ){
  1054   1054       Table *pTab;
  1055         -    pTab = sqlite3FindTable(db, zRight, zDb);
         1055  +    pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
  1056   1056       if( pTab ){
  1057   1057         static const char *azCol[] = {
  1058   1058            "cid", "name", "type", "notnull", "dflt_value", "pk"
  1059   1059         };
  1060   1060         int i, k;
  1061   1061         int nHidden = 0;
  1062   1062         Column *pCol;
................................................................................
  1330   1330           if( pParent && pIdx==0 ){
  1331   1331             int iKey = pFK->aCol[0].iFrom;
  1332   1332             assert( iKey>=0 && iKey<pTab->nCol );
  1333   1333             if( iKey!=pTab->iPKey ){
  1334   1334               sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
  1335   1335               sqlite3ColumnDefault(v, pTab, iKey, regRow);
  1336   1336               sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
  1337         -            sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow, 
  1338         -               sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
  1339   1337             }else{
  1340   1338               sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
  1341   1339             }
  1342         -          sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
         1340  +          sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v);
  1343   1341             sqlite3VdbeGoto(v, addrOk);
  1344   1342             sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
  1345   1343           }else{
  1346   1344             for(j=0; j<pFK->nCol; j++){
  1347   1345               sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
  1348   1346                               aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
  1349   1347               sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);

Changes to src/select.c.

  1024   1024   
  1025   1025   /*
  1026   1026   ** Allocate a KeyInfo object sufficient for an index of N key columns and
  1027   1027   ** X extra columns.
  1028   1028   */
  1029   1029   KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
  1030   1030     int nExtra = (N+X)*(sizeof(CollSeq*)+1);
  1031         -  KeyInfo *p = sqlite3Malloc(sizeof(KeyInfo) + nExtra);
         1031  +  KeyInfo *p = sqlite3DbMallocRaw(db, sizeof(KeyInfo) + nExtra);
  1032   1032     if( p ){
  1033   1033       p->aSortOrder = (u8*)&p->aColl[N+X];
  1034   1034       p->nField = (u16)N;
  1035   1035       p->nXField = (u16)X;
  1036   1036       p->enc = ENC(db);
  1037   1037       p->db = db;
  1038   1038       p->nRef = 1;
................................................................................
  1046   1046   /*
  1047   1047   ** Deallocate a KeyInfo object
  1048   1048   */
  1049   1049   void sqlite3KeyInfoUnref(KeyInfo *p){
  1050   1050     if( p ){
  1051   1051       assert( p->nRef>0 );
  1052   1052       p->nRef--;
  1053         -    if( p->nRef==0 ) sqlite3DbFree(0, p);
         1053  +    if( p->nRef==0 ) sqlite3DbFree(p->db, p);
  1054   1054     }
  1055   1055   }
  1056   1056   
  1057   1057   /*
  1058   1058   ** Make a new pointer to a KeyInfo object
  1059   1059   */
  1060   1060   KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){

Changes to src/sqlite.h.in.

   502    502   #define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
   503    503   #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
   504    504   #define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
   505    505   #define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
   506    506   #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
   507    507   #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
   508    508   #define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
          509  +#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
   509    510   
   510    511   /*
   511    512   ** CAPI3REF: Flags For File Open Operations
   512    513   **
   513    514   ** These bit values are intended for use in the
   514    515   ** 3rd parameter to the [sqlite3_open_v2()] interface and
   515    516   ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.

Changes to src/sqliteInt.h.

  3613   3613   void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
  3614   3614   int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
  3615   3615   void sqlite3SrcListShiftJoinType(SrcList*);
  3616   3616   void sqlite3SrcListAssignCursors(Parse*, SrcList*);
  3617   3617   void sqlite3IdListDelete(sqlite3*, IdList*);
  3618   3618   void sqlite3SrcListDelete(sqlite3*, SrcList*);
  3619   3619   Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
  3620         -Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
  3621         -                          Expr*, int, int);
         3620  +void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
         3621  +                          Expr*, int, int, u8);
  3622   3622   void sqlite3DropIndex(Parse*, SrcList*, int);
  3623   3623   int sqlite3Select(Parse*, Select*, SelectDest*);
  3624   3624   Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
  3625   3625                            Expr*,ExprList*,u32,Expr*,Expr*);
  3626   3626   void sqlite3SelectDelete(sqlite3*, Select*);
  3627   3627   Table *sqlite3SrcListLookup(Parse*, SrcList*);
  3628   3628   int sqlite3IsReadOnly(Parse*, Table*, int);
................................................................................
  3667   3667   #define SQLITE_ECEL_DUP      0x01  /* Deep, not shallow copies */
  3668   3668   #define SQLITE_ECEL_FACTOR   0x02  /* Factor out constant terms */
  3669   3669   #define SQLITE_ECEL_REF      0x04  /* Use ExprList.u.x.iOrderByCol */
  3670   3670   void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
  3671   3671   void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
  3672   3672   void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
  3673   3673   Table *sqlite3FindTable(sqlite3*,const char*, const char*);
  3674         -Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
  3675         -Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
         3674  +#define LOCATE_VIEW    0x01
         3675  +#define LOCATE_NOERR   0x02
         3676  +Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
         3677  +Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *);
  3676   3678   Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
  3677   3679   void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
  3678   3680   void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
  3679   3681   void sqlite3Vacuum(Parse*);
  3680   3682   int sqlite3RunVacuum(char**, sqlite3*);
  3681   3683   char *sqlite3NameFromToken(sqlite3*, Token*);
  3682   3684   int sqlite3ExprCompare(Expr*, Expr*, int);

Changes to src/tclsqlite.c.

  2321   2321     **    $db onecolumn $sql
  2322   2322     **
  2323   2323     ** The onecolumn method is the equivalent of:
  2324   2324     **     lindex [$db eval $sql] 0
  2325   2325     */
  2326   2326     case DB_EXISTS: 
  2327   2327     case DB_ONECOLUMN: {
         2328  +    Tcl_Obj *pResult = 0;
  2328   2329       DbEvalContext sEval;
  2329   2330       if( objc!=3 ){
  2330   2331         Tcl_WrongNumArgs(interp, 2, objv, "SQL");
  2331   2332         return TCL_ERROR;
  2332   2333       }
  2333   2334   
  2334   2335       dbEvalInit(&sEval, pDb, objv[2], 0);
  2335   2336       rc = dbEvalStep(&sEval);
  2336   2337       if( choice==DB_ONECOLUMN ){
  2337   2338         if( rc==TCL_OK ){
  2338         -        Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0));
         2339  +        pResult = dbEvalColumnValue(&sEval, 0);
  2339   2340         }else if( rc==TCL_BREAK ){
  2340   2341           Tcl_ResetResult(interp);
  2341   2342         }
  2342   2343       }else if( rc==TCL_BREAK || rc==TCL_OK ){
  2343         -      Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK));
         2344  +      pResult = Tcl_NewBooleanObj(rc==TCL_OK);
  2344   2345       }
  2345   2346       dbEvalFinalize(&sEval);
         2347  +    if( pResult ) Tcl_SetObjResult(interp, pResult);
  2346   2348   
  2347   2349       if( rc==TCL_BREAK ){
  2348   2350         rc = TCL_OK;
  2349   2351       }
  2350   2352       break;
  2351   2353     }
  2352   2354      

Changes to src/test1.c.

  6771   6771     void * clientData,
  6772   6772     Tcl_Interp *interp,
  6773   6773     int objc,
  6774   6774     Tcl_Obj *CONST objv[]
  6775   6775   ){
  6776   6776     extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
  6777   6777     extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
         6778  +  extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
  6778   6779     extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
  6779   6780     extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
  6780   6781     extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
  6781   6782     extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
  6782   6783     extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*);
  6783   6784     extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
  6784   6785     extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*);
................................................................................
  6788   6789     extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*);
  6789   6790     static const struct {
  6790   6791       const char *zExtName;
  6791   6792       int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
  6792   6793     } aExtension[] = {
  6793   6794       { "amatch",                sqlite3_amatch_init               },
  6794   6795       { "closure",               sqlite3_closure_init              },
         6796  +    { "csv",                   sqlite3_csv_init                  },
  6795   6797       { "eval",                  sqlite3_eval_init                 },
  6796   6798       { "fileio",                sqlite3_fileio_init               },
  6797   6799       { "fuzzer",                sqlite3_fuzzer_init               },
  6798   6800       { "ieee754",               sqlite3_ieee_init                 },
  6799   6801       { "nextchar",              sqlite3_nextchar_init             },
  6800   6802       { "percentile",            sqlite3_percentile_init           },
  6801   6803       { "regexp",                sqlite3_regexp_init               },

Changes to src/test3.c.

   381    381   static int btree_payload_size(
   382    382     void *NotUsed,
   383    383     Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   384    384     int argc,              /* Number of arguments */
   385    385     const char **argv      /* Text of each argument */
   386    386   ){
   387    387     BtCursor *pCur;
   388         -  int n2;
   389         -  u64 n1;
          388  +  u32 n;
   390    389     char zBuf[50];
   391    390   
   392    391     if( argc!=2 ){
   393    392       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   394    393          " ID\"", 0);
   395    394       return TCL_ERROR;
   396    395     }
   397    396     pCur = sqlite3TestTextToPtr(argv[1]);
   398    397     sqlite3BtreeEnter(pCur->pBtree);
   399         -
   400         -  /* The cursor may be in "require-seek" state. If this is the case, the
   401         -  ** call to BtreeDataSize() will fix it. */
   402         -  sqlite3BtreeDataSize(pCur, (u32*)&n2);
   403         -  if( pCur->apPage[pCur->iPage]->intKey ){
   404         -    n1 = 0;
   405         -  }else{
   406         -    sqlite3BtreeKeySize(pCur, (i64*)&n1);
   407         -  }
          398  +  n = sqlite3BtreePayloadSize(pCur);
   408    399     sqlite3BtreeLeave(pCur->pBtree);
   409         -  sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", (int)(n1+n2));
          400  +  sqlite3_snprintf(sizeof(zBuf),zBuf, "%u", n);
   410    401     Tcl_AppendResult(interp, zBuf, 0);
   411    402     return SQLITE_OK;
   412    403   }
   413    404   
   414    405   /*
   415    406   ** usage:   varint_test  START  MULTIPLIER  COUNT  INCREMENT
   416    407   **

Changes to src/test6.c.

   211    211       sqlite3_randomness(sizeof(int), &iFinal);
   212    212       iFinal = ((iFinal<0)?-1*iFinal:iFinal)%nWrite;
   213    213       for(pWrite=g.pWriteList; iFinal>0; pWrite=pWrite->pNext) iFinal--;
   214    214       pFinal = pWrite;
   215    215     }
   216    216   
   217    217   #ifdef TRACE_CRASHTEST
   218         -  printf("Sync %s (is %s crash)\n", pFile->zName, (isCrash?"a":"not a"));
          218  +  if( pFile ){
          219  +    printf("Sync %s (is %s crash)\n", pFile->zName, (isCrash?"a":"not a"));
          220  +  }
   219    221   #endif
   220    222   
   221    223     ppPtr = &g.pWriteList;
   222    224     for(pWrite=*ppPtr; rc==SQLITE_OK && pWrite; pWrite=*ppPtr){
   223    225       sqlite3_file *pRealFile = pWrite->pFile->pRealFile;
   224    226   
   225    227       /* (eAction==1)      -> write block out normally,
................................................................................
   794    796     }
   795    797     if( setSectorsize ){
   796    798       *piSectorSize = iSectorSize;
   797    799     }
   798    800   
   799    801     return TCL_OK;
   800    802   }
          803  +
          804  +/*
          805  +** tclcmd:   sqlite3_crash_now
          806  +**
          807  +** Simulate a crash immediately. This function does not return 
          808  +** (writeListSync() calls exit(-1)).
          809  +*/
          810  +static int crashNowCmd(
          811  +  void * clientData,
          812  +  Tcl_Interp *interp,
          813  +  int objc,
          814  +  Tcl_Obj *CONST objv[]
          815  +){
          816  +  if( objc!=1 ){
          817  +    Tcl_WrongNumArgs(interp, 1, objv, "");
          818  +    return TCL_ERROR;
          819  +  }
          820  +  writeListSync(0, 1);
          821  +  assert( 0 );
          822  +  return TCL_OK;
          823  +}
   801    824   
   802    825   /*
   803    826   ** tclcmd:   sqlite_crash_enable ENABLE
   804    827   **
   805    828   ** Parameter ENABLE must be a boolean value. If true, then the "crash"
   806    829   ** vfs is added to the system. If false, it is removed.
   807    830   */
................................................................................
  1030   1053   /*
  1031   1054   ** This procedure registers the TCL procedures defined in this file.
  1032   1055   */
  1033   1056   int Sqlitetest6_Init(Tcl_Interp *interp){
  1034   1057   #ifndef SQLITE_OMIT_DISKIO
  1035   1058     Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
  1036   1059     Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
         1060  +  Tcl_CreateObjCommand(interp, "sqlite3_crash_now", crashNowCmd, 0, 0);
  1037   1061     Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
  1038   1062     Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0);
  1039   1063     Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
  1040   1064     Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
  1041   1065   #endif
  1042   1066     return TCL_OK;
  1043   1067   }
  1044   1068   
  1045   1069   #endif /* SQLITE_TEST */

Changes to src/treeview.c.

   441    441           case OE_Fail:       zType = "fail";      break;
   442    442           case OE_Ignore:     zType = "ignore";    break;
   443    443         }
   444    444         sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
   445    445         break;
   446    446       }
   447    447   #endif
          448  +    case TK_MATCH: {
          449  +      sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s",
          450  +                          pExpr->iTable, pExpr->iColumn, zFlgs);
          451  +      sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
          452  +      break;
          453  +    }
   448    454       default: {
   449    455         sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
   450    456         break;
   451    457       }
   452    458     }
   453    459     if( zBinOp ){
   454    460       sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs);

Changes to src/vdbe.c.

  2377   2377   **
  2378   2378   ** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
  2379   2379   ** the result is guaranteed to only be used as the argument of a length()
  2380   2380   ** or typeof() function, respectively.  The loading of large blobs can be
  2381   2381   ** skipped for length() and all content loading can be skipped for typeof().
  2382   2382   */
  2383   2383   case OP_Column: {
  2384         -  i64 payloadSize64; /* Number of bytes in the record */
  2385   2384     int p2;            /* column number to retrieve */
  2386   2385     VdbeCursor *pC;    /* The VDBE cursor */
  2387   2386     BtCursor *pCrsr;   /* The BTree cursor */
  2388   2387     u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  2389   2388     int len;           /* The length of the serialized data for the column */
  2390   2389     int i;             /* Loop counter */
  2391   2390     Mem *pDest;        /* Where to write the extracted value */
................................................................................
  2430   2429         }else{
  2431   2430           sqlite3VdbeMemSetNull(pDest);
  2432   2431           goto op_column_out;
  2433   2432         }
  2434   2433       }else{
  2435   2434         assert( pC->eCurType==CURTYPE_BTREE );
  2436   2435         assert( pCrsr );
  2437         -      if( pC->isTable==0 ){
  2438         -        assert( sqlite3BtreeCursorIsValid(pCrsr) );
  2439         -        VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
  2440         -        assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
  2441         -        /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
  2442         -        ** payload size, so it is impossible for payloadSize64 to be
  2443         -        ** larger than 32 bits. */
  2444         -        assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 );
  2445         -        pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail);
  2446         -        pC->payloadSize = (u32)payloadSize64;
  2447         -      }else{
  2448         -        assert( sqlite3BtreeCursorIsValid(pCrsr) );
  2449         -        VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize);
  2450         -        assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
  2451         -        pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail);
  2452         -      }
         2436  +      assert( sqlite3BtreeCursorIsValid(pCrsr) );
         2437  +      pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
         2438  +      pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail);
  2453   2439         assert( avail<=65536 );  /* Maximum page size is 64KiB */
  2454   2440         if( pC->payloadSize <= (u32)avail ){
  2455   2441           pC->szRow = pC->payloadSize;
  2456   2442         }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
  2457   2443           goto too_big;
  2458   2444         }else{
  2459   2445           pC->szRow = avail;
................................................................................
  4020   4006     }else{
  4021   4007       VdbeBranchTaken(takeJump||alreadyExists==0,2);
  4022   4008       if( takeJump || !alreadyExists ) goto jump_to_p2;
  4023   4009     }
  4024   4010     break;
  4025   4011   }
  4026   4012   
         4013  +/* Opcode: SeekRowid P1 P2 P3 * *
         4014  +** Synopsis: intkey=r[P3]
         4015  +**
         4016  +** P1 is the index of a cursor open on an SQL table btree (with integer
         4017  +** keys).  If register P3 does not contain an integer or if P1 does not
         4018  +** contain a record with rowid P3 then jump immediately to P2.  
         4019  +** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain
         4020  +** a record with rowid P3 then 
         4021  +** leave the cursor pointing at that record and fall through to the next
         4022  +** instruction.
         4023  +**
         4024  +** The OP_NotExists opcode performs the same operation, but with OP_NotExists
         4025  +** the P3 register must be guaranteed to contain an integer value.  With this
         4026  +** opcode, register P3 might not contain an integer.
         4027  +**
         4028  +** The OP_NotFound opcode performs the same operation on index btrees
         4029  +** (with arbitrary multi-value keys).
         4030  +**
         4031  +** This opcode leaves the cursor in a state where it cannot be advanced
         4032  +** in either direction.  In other words, the Next and Prev opcodes will
         4033  +** not work following this opcode.
         4034  +**
         4035  +** See also: Found, NotFound, NoConflict, SeekRowid
         4036  +*/
  4027   4037   /* Opcode: NotExists P1 P2 P3 * *
  4028   4038   ** Synopsis: intkey=r[P3]
  4029   4039   **
  4030   4040   ** P1 is the index of a cursor open on an SQL table btree (with integer
  4031   4041   ** keys).  P3 is an integer rowid.  If P1 does not contain a record with
  4032   4042   ** rowid P3 then jump immediately to P2.  Or, if P2 is 0, raise an
  4033   4043   ** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then 
  4034   4044   ** leave the cursor pointing at that record and fall through to the next
  4035   4045   ** instruction.
  4036   4046   **
         4047  +** The OP_SeekRowid opcode performs the same operation but also allows the
         4048  +** P3 register to contain a non-integer value, in which case the jump is
         4049  +** always taken.  This opcode requires that P3 always contain an integer.
         4050  +**
  4037   4051   ** The OP_NotFound opcode performs the same operation on index btrees
  4038   4052   ** (with arbitrary multi-value keys).
  4039   4053   **
  4040   4054   ** This opcode leaves the cursor in a state where it cannot be advanced
  4041   4055   ** in either direction.  In other words, the Next and Prev opcodes will
  4042   4056   ** not work following this opcode.
  4043   4057   **
  4044         -** See also: Found, NotFound, NoConflict
         4058  +** See also: Found, NotFound, NoConflict, SeekRowid
  4045   4059   */
  4046         -case OP_NotExists: {        /* jump, in3 */
         4060  +case OP_SeekRowid: {        /* jump, in3 */
  4047   4061     VdbeCursor *pC;
  4048   4062     BtCursor *pCrsr;
  4049   4063     int res;
  4050   4064     u64 iKey;
  4051   4065   
  4052   4066     pIn3 = &aMem[pOp->p3];
         4067  +  if( (pIn3->flags & MEM_Int)==0 ){
         4068  +    applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
         4069  +    if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2;
         4070  +  }
         4071  +  /* Fall through into OP_NotExists */
         4072  +case OP_NotExists:          /* jump, in3 */
         4073  +  pIn3 = &aMem[pOp->p3];
  4053   4074     assert( pIn3->flags & MEM_Int );
  4054   4075     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4055   4076     pC = p->apCsr[pOp->p1];
  4056   4077     assert( pC!=0 );
  4057   4078   #ifdef SQLITE_DEBUG
  4058   4079     pC->seekOp = 0;
  4059   4080   #endif
................................................................................
  4163   4184         if( rc!=SQLITE_OK ){
  4164   4185           goto abort_due_to_error;
  4165   4186         }
  4166   4187         if( res ){
  4167   4188           v = 1;   /* IMP: R-61914-48074 */
  4168   4189         }else{
  4169   4190           assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) );
  4170         -        rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v);
  4171         -        assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */
         4191  +        v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
  4172   4192           if( v>=MAX_ROWID ){
  4173   4193             pC->useRandomRowid = 1;
  4174   4194           }else{
  4175   4195             v++;   /* IMP: R-29538-34987 */
  4176   4196           }
  4177   4197         }
  4178   4198       }
................................................................................
  4247   4267   **
  4248   4268   ** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
  4249   4269   ** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P5 is set,
  4250   4270   ** then rowid is stored for subsequent return by the
  4251   4271   ** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
  4252   4272   **
  4253   4273   ** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
  4254         -** the last seek operation (OP_NotExists) was a success, then this
         4274  +** the last seek operation (OP_NotExists or OP_SeekRowid) was a success,
         4275  +** then this
  4255   4276   ** operation will not attempt to find the appropriate row before doing
  4256   4277   ** the insert but will instead overwrite the row that the cursor is
  4257         -** currently pointing to.  Presumably, the prior OP_NotExists opcode
         4278  +** currently pointing to.  Presumably, the prior OP_NotExists or
         4279  +** OP_SeekRowid opcode
  4258   4280   ** has already positioned the cursor correctly.  This is an optimization
  4259   4281   ** that boosts performance by avoiding redundant seeks.
  4260   4282   **
  4261   4283   ** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
  4262   4284   ** UPDATE operation.  Otherwise (if the flag is clear) then this opcode
  4263   4285   ** is part of an INSERT operation.  The difference is only important to
  4264   4286   ** the update hook.
................................................................................
  4419   4441     assert( pC->deferredMoveto==0 );
  4420   4442   
  4421   4443   #ifdef SQLITE_DEBUG
  4422   4444     if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
  4423   4445       /* If p5 is zero, the seek operation that positioned the cursor prior to
  4424   4446       ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
  4425   4447       ** the row that is being deleted */
  4426         -    i64 iKey = 0;
  4427         -    sqlite3BtreeKeySize(pC->uc.pCursor, &iKey);
         4448  +    i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
  4428   4449       assert( pC->movetoTarget==iKey );
  4429   4450     }
  4430   4451   #endif
  4431   4452   
  4432   4453     /* If the update-hook or pre-update-hook will be invoked, set zDb to
  4433   4454     ** the name of the db to pass as to it. Also set local pTab to a copy
  4434   4455     ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
................................................................................
  4436   4457     ** VdbeCursor.movetoTarget to the current rowid.  */
  4437   4458     if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
  4438   4459       assert( pC->iDb>=0 );
  4439   4460       assert( pOp->p4.pTab!=0 );
  4440   4461       zDb = db->aDb[pC->iDb].zName;
  4441   4462       pTab = pOp->p4.pTab;
  4442   4463       if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
  4443         -      sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
         4464  +      pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
  4444   4465       }
  4445   4466     }else{
  4446   4467       zDb = 0;   /* Not needed.  Silence a compiler warning. */
  4447   4468       pTab = 0;  /* Not needed.  Silence a compiler warning. */
  4448   4469     }
  4449   4470   
  4450   4471   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
................................................................................
  4590   4611   ** of a real table, not a pseudo-table.
  4591   4612   */
  4592   4613   case OP_RowKey:
  4593   4614   case OP_RowData: {
  4594   4615     VdbeCursor *pC;
  4595   4616     BtCursor *pCrsr;
  4596   4617     u32 n;
  4597         -  i64 n64;
  4598   4618   
  4599   4619     pOut = &aMem[pOp->p2];
  4600   4620     memAboutToChange(p, pOut);
  4601   4621   
  4602   4622     /* Note that RowKey and RowData are really exactly the same instruction */
  4603   4623     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4604   4624     pC = p->apCsr[pOp->p1];
................................................................................
  4608   4628     assert( pC->isTable || pOp->opcode!=OP_RowData );
  4609   4629     assert( pC->isTable==0 || pOp->opcode==OP_RowData );
  4610   4630     assert( pC->nullRow==0 );
  4611   4631     assert( pC->uc.pCursor!=0 );
  4612   4632     pCrsr = pC->uc.pCursor;
  4613   4633   
  4614   4634     /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
  4615         -  ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
  4616         -  ** the cursor.  If this where not the case, on of the following assert()s
         4635  +  ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions
         4636  +  ** that might invalidate the cursor.
         4637  +  ** If this where not the case, on of the following assert()s
  4617   4638     ** would fail.  Should this ever change (because of changes in the code
  4618   4639     ** generator) then the fix would be to insert a call to
  4619   4640     ** sqlite3VdbeCursorMoveto().
  4620   4641     */
  4621   4642     assert( pC->deferredMoveto==0 );
  4622   4643     assert( sqlite3BtreeCursorIsValid(pCrsr) );
  4623   4644   #if 0  /* Not required due to the previous to assert() statements */
  4624   4645     rc = sqlite3VdbeCursorMoveto(pC);
  4625   4646     if( rc!=SQLITE_OK ) goto abort_due_to_error;
  4626   4647   #endif
  4627   4648   
  4628         -  if( pC->isTable==0 ){
  4629         -    assert( !pC->isTable );
  4630         -    VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
  4631         -    assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
  4632         -    if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  4633         -      goto too_big;
  4634         -    }
  4635         -    n = (u32)n64;
  4636         -  }else{
  4637         -    VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
  4638         -    assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
  4639         -    if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
  4640         -      goto too_big;
  4641         -    }
         4649  +  n = sqlite3BtreePayloadSize(pCrsr);
         4650  +  if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
         4651  +    goto too_big;
  4642   4652     }
  4643   4653     testcase( n==0 );
  4644   4654     if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
  4645   4655       goto no_mem;
  4646   4656     }
  4647   4657     pOut->n = n;
  4648   4658     MemSetTypeFlag(pOut, MEM_Blob);
................................................................................
  4699   4709       assert( pC->uc.pCursor!=0 );
  4700   4710       rc = sqlite3VdbeCursorRestore(pC);
  4701   4711       if( rc ) goto abort_due_to_error;
  4702   4712       if( pC->nullRow ){
  4703   4713         pOut->flags = MEM_Null;
  4704   4714         break;
  4705   4715       }
  4706         -    rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v);
  4707         -    assert( rc==SQLITE_OK );  /* Always so because of CursorRestore() above */
         4716  +    v = sqlite3BtreeIntegerKey(pC->uc.pCursor);
  4708   4717     }
  4709   4718     pOut->u.i = v;
  4710   4719     break;
  4711   4720   }
  4712   4721   
  4713   4722   /* Opcode: NullRow P1 * * * *
  4714   4723   **

Changes to src/vdbeapi.c.

  1689   1689     }
  1690   1690   
  1691   1691     /* If the old.* record has not yet been loaded into memory, do so now. */
  1692   1692     if( p->pUnpacked==0 ){
  1693   1693       u32 nRec;
  1694   1694       u8 *aRec;
  1695   1695   
  1696         -    rc = sqlite3BtreeDataSize(p->pCsr->uc.pCursor, &nRec);
  1697         -    if( rc!=SQLITE_OK ) goto preupdate_old_out;
         1696  +    nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
  1698   1697       aRec = sqlite3DbMallocRaw(db, nRec);
  1699   1698       if( !aRec ) goto preupdate_old_out;
  1700   1699       rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec);
  1701   1700       if( rc==SQLITE_OK ){
  1702   1701         p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
  1703   1702         if( !p->pUnpacked ) rc = SQLITE_NOMEM;
  1704   1703       }

Changes to src/vdbeaux.c.

  4311   4311   
  4312   4312     /* Get the size of the index entry.  Only indices entries of less
  4313   4313     ** than 2GiB are support - anything large must be database corruption.
  4314   4314     ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
  4315   4315     ** this code can safely assume that nCellKey is 32-bits  
  4316   4316     */
  4317   4317     assert( sqlite3BtreeCursorIsValid(pCur) );
  4318         -  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
  4319         -  assert( rc==SQLITE_OK );     /* pCur is always valid so KeySize cannot fail */
         4318  +  nCellKey = sqlite3BtreePayloadSize(pCur);
  4320   4319     assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
  4321   4320   
  4322   4321     /* Read in the complete content of the index entry */
  4323   4322     sqlite3VdbeMemInit(&m, db, 0);
  4324   4323     rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
  4325   4324     if( rc ){
  4326   4325       return rc;
................................................................................
  4389   4388     int rc;
  4390   4389     BtCursor *pCur;
  4391   4390     Mem m;
  4392   4391   
  4393   4392     assert( pC->eCurType==CURTYPE_BTREE );
  4394   4393     pCur = pC->uc.pCursor;
  4395   4394     assert( sqlite3BtreeCursorIsValid(pCur) );
  4396         -  VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
  4397         -  assert( rc==SQLITE_OK );    /* pCur is always valid so KeySize cannot fail */
         4395  +  nCellKey = sqlite3BtreePayloadSize(pCur);
  4398   4396     /* nCellKey will always be between 0 and 0xffffffff because of the way
  4399   4397     ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
  4400   4398     if( nCellKey<=0 || nCellKey>0x7fffffff ){
  4401   4399       *res = 0;
  4402   4400       return SQLITE_CORRUPT_BKPT;
  4403   4401     }
  4404   4402     sqlite3VdbeMemInit(&m, db, 0);

Changes to src/vdbeblob.c.

   411    411         ** SQLITE_UPDATE where the PK columns do not change is handled in the 
   412    412         ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
   413    413         ** slightly more efficient). Since you cannot write to a PK column
   414    414         ** using the incremental-blob API, this works. For the sessions module
   415    415         ** anyhow.
   416    416         */
   417    417         sqlite3_int64 iKey;
   418         -      sqlite3BtreeKeySize(p->pCsr, &iKey);
          418  +      iKey = sqlite3BtreeIntegerKey(p->pCsr);
   419    419         sqlite3VdbePreUpdateHook(
   420    420             v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1
   421    421         );
   422    422       }
   423    423   #endif
   424    424   
   425    425       rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);

Changes to src/vdbemem.c.

   987    987   
   988    988     assert( sqlite3BtreeCursorIsValid(pCur) );
   989    989     assert( !VdbeMemDynamic(pMem) );
   990    990   
   991    991     /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
   992    992     ** that both the BtShared and database handle mutexes are held. */
   993    993     assert( (pMem->flags & MEM_RowSet)==0 );
   994         -  if( key ){
   995         -    zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
   996         -  }else{
   997         -    zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
   998         -  }
          994  +  zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
   999    995     assert( zData!=0 );
  1000    996   
  1001    997     if( offset+amt<=available ){
  1002    998       pMem->z = &zData[offset];
  1003    999       pMem->flags = MEM_Blob|MEM_Ephem;
  1004   1000       pMem->n = (int)amt;
  1005   1001     }else{

Changes to src/vtab.c.

   750    750       if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) 
   751    751        && pParse->pNewTable
   752    752        && !db->mallocFailed
   753    753        && !pParse->pNewTable->pSelect
   754    754        && (pParse->pNewTable->tabFlags & TF_Virtual)==0
   755    755       ){
   756    756         if( !pTab->aCol ){
   757         -        pTab->aCol = pParse->pNewTable->aCol;
   758         -        pTab->nCol = pParse->pNewTable->nCol;
   759         -        pParse->pNewTable->nCol = 0;
   760         -        pParse->pNewTable->aCol = 0;
          757  +        Table *pNew = pParse->pNewTable;
          758  +        Index *pIdx;
          759  +        pTab->aCol = pNew->aCol;
          760  +        pTab->nCol = pNew->nCol;
          761  +        pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
          762  +        pNew->nCol = 0;
          763  +        pNew->aCol = 0;
          764  +        assert( pTab->pIndex==0 );
          765  +        if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){
          766  +          rc = SQLITE_ERROR;
          767  +        }
          768  +        pIdx = pNew->pIndex;
          769  +        if( pIdx ){
          770  +          assert( pIdx->pNext==0 );
          771  +          pTab->pIndex = pIdx;
          772  +          pNew->pIndex = 0;
          773  +          pIdx->pTable = pTab;
          774  +        }
   761    775         }
   762    776         pCtx->bDeclared = 1;
   763    777       }else{
   764    778         sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
   765    779         sqlite3DbFree(db, zErr);
   766    780         rc = SQLITE_ERROR;
   767    781       }
................................................................................
  1083   1097       pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
  1084   1098     }else{
  1085   1099       sqlite3OomFault(pToplevel->db);
  1086   1100     }
  1087   1101   }
  1088   1102   
  1089   1103   /*
  1090         -** Check to see if virtual tale module pMod can be have an eponymous
         1104  +** Check to see if virtual table module pMod can be have an eponymous
  1091   1105   ** virtual table instance.  If it can, create one if one does not already
  1092   1106   ** exist. Return non-zero if the eponymous virtual table instance exists
  1093   1107   ** when this routine returns, and return zero if it does not exist.
  1094   1108   **
  1095   1109   ** An eponymous virtual table instance is one that is named after its
  1096   1110   ** module, and more importantly, does not require a CREATE VIRTUAL TABLE
  1097   1111   ** statement in order to come into existance.  Eponymous virtual table
................................................................................
  1100   1114   ** Any virtual table module for which xConnect and xCreate are the same
  1101   1115   ** method can have an eponymous virtual table instance.
  1102   1116   */
  1103   1117   int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
  1104   1118     const sqlite3_module *pModule = pMod->pModule;
  1105   1119     Table *pTab;
  1106   1120     char *zErr = 0;
  1107         -  int nName;
  1108   1121     int rc;
  1109   1122     sqlite3 *db = pParse->db;
  1110   1123     if( pMod->pEpoTab ) return 1;
  1111   1124     if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0;
  1112         -  nName = sqlite3Strlen30(pMod->zName) + 1;
  1113         -  pTab = sqlite3DbMallocZero(db, sizeof(Table) + nName);
         1125  +  pTab = sqlite3DbMallocZero(db, sizeof(Table));
  1114   1126     if( pTab==0 ) return 0;
         1127  +  pTab->zName = sqlite3DbStrDup(db, pMod->zName);
         1128  +  if( pTab->zName==0 ){
         1129  +    sqlite3DbFree(db, pTab);
         1130  +    return 0;
         1131  +  }
  1115   1132     pMod->pEpoTab = pTab;
  1116         -  pTab->zName = (char*)&pTab[1];
  1117         -  memcpy(pTab->zName, pMod->zName, nName);
  1118   1133     pTab->nRef = 1;
  1119   1134     pTab->pSchema = db->aDb[0].pSchema;
  1120   1135     pTab->tabFlags |= TF_Virtual;
  1121   1136     pTab->nModuleArg = 0;
  1122   1137     pTab->iPKey = -1;
  1123   1138     addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
  1124   1139     addModuleArgument(db, pTab, 0);
................................................................................
  1136   1151   /*
  1137   1152   ** Erase the eponymous virtual table instance associated with
  1138   1153   ** virtual table module pMod, if it exists.
  1139   1154   */
  1140   1155   void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
  1141   1156     Table *pTab = pMod->pEpoTab;
  1142   1157     if( pTab!=0 ){
  1143         -    sqlite3DeleteColumnNames(db, pTab);
  1144         -    sqlite3VtabClear(db, pTab);
  1145         -    sqlite3DbFree(db, pTab);
         1158  +    /* Mark the table as Ephemeral prior to deleting it, so that the
         1159  +    ** sqlite3DeleteTable() routine will know that it is not stored in 
         1160  +    ** the schema. */
         1161  +    pTab->tabFlags |= TF_Ephemeral;
         1162  +    sqlite3DeleteTable(db, pTab);
  1146   1163       pMod->pEpoTab = 0;
  1147   1164     }
  1148   1165   }
  1149   1166   
  1150   1167   /*
  1151   1168   ** Return the ON CONFLICT resolution mode in effect for the virtual
  1152   1169   ** table update operation currently in progress.

Changes to src/wal.c.

  3140   3140     ** needed and only the sync is done.  If padding is needed, then the
  3141   3141     ** final frame is repeated (with its commit mark) until the next sector
  3142   3142     ** boundary is crossed.  Only the part of the WAL prior to the last
  3143   3143     ** sector boundary is synced; the part of the last frame that extends
  3144   3144     ** past the sector boundary is written after the sync.
  3145   3145     */
  3146   3146     if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
         3147  +    int bSync = 1;
  3147   3148       if( pWal->padToSectorBoundary ){
  3148   3149         int sectorSize = sqlite3SectorSize(pWal->pWalFd);
  3149   3150         w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
         3151  +      bSync = (w.iSyncPoint==iOffset);
         3152  +      testcase( bSync );
  3150   3153         while( iOffset<w.iSyncPoint ){
  3151   3154           rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
  3152   3155           if( rc ) {
  3153   3156   #if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
  3154   3157             free(w.aFrameBuf);
  3155   3158   #endif
  3156   3159             return rc;
  3157   3160           }
  3158   3161           iOffset += szFrame;
  3159   3162           nExtra++;
  3160   3163         }
  3161         -    }else{
         3164  +    }
         3165  +    if( bSync ){
         3166  +      assert( rc==SQLITE_OK );
  3162   3167         rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
  3163   3168       }
  3164   3169     }
  3165   3170   
  3166   3171   #if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
  3167   3172     free(w.aFrameBuf);
  3168   3173   #endif

Changes to src/where.c.

  1644   1644   ** Print the content of a WhereTerm object
  1645   1645   */
  1646   1646   static void whereTermPrint(WhereTerm *pTerm, int iTerm){
  1647   1647     if( pTerm==0 ){
  1648   1648       sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
  1649   1649     }else{
  1650   1650       char zType[4];
         1651  +    char zLeft[50];
  1651   1652       memcpy(zType, "...", 4);
  1652   1653       if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
  1653   1654       if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
  1654   1655       if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
         1656  +    if( pTerm->eOperator & WO_SINGLE ){
         1657  +      sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
         1658  +                       pTerm->leftCursor, pTerm->u.leftColumn);
         1659  +    }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
         1660  +      sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", 
         1661  +                       pTerm->u.pOrInfo->indexable);
         1662  +    }else{
         1663  +      sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
         1664  +    }
  1655   1665       sqlite3DebugPrintf(
  1656         -       "TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x wtFlags=0x%04x\n",
  1657         -       iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
         1666  +       "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x\n",
         1667  +       iTerm, pTerm, zType, zLeft, pTerm->truthProb,
  1658   1668          pTerm->eOperator, pTerm->wtFlags);
  1659   1669       sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
  1660   1670     }
         1671  +}
         1672  +#endif
         1673  +
         1674  +#ifdef WHERETRACE_ENABLED
         1675  +/*
         1676  +** Show the complete content of a WhereClause
         1677  +*/
         1678  +void sqlite3WhereClausePrint(WhereClause *pWC){
         1679  +  int i;
         1680  +  for(i=0; i<pWC->nTerm; i++){
         1681  +    whereTermPrint(&pWC->a[i], i);
         1682  +  }
  1661   1683   }
  1662   1684   #endif
  1663   1685   
  1664   1686   #ifdef WHERETRACE_ENABLED
  1665   1687   /*
  1666   1688   ** Print a WhereLoop object for debugging purposes
  1667   1689   */
................................................................................
  2735   2757           m = pSrc->colUsed & ~columnsInIndex(pProbe);
  2736   2758           pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
  2737   2759         }
  2738   2760   
  2739   2761         /* Full scan via index */
  2740   2762         if( b
  2741   2763          || !HasRowid(pTab)
         2764  +       || pProbe->pPartIdxWhere!=0
  2742   2765          || ( m==0
  2743   2766            && pProbe->bUnordered==0
  2744   2767            && (pProbe->szIdxRow<pTab->szTabRow)
  2745   2768            && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
  2746   2769            && sqlite3GlobalConfig.bUseCis
  2747   2770            && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
  2748   2771             )
................................................................................
  3120   3143             continue;
  3121   3144           }
  3122   3145           sCur.n = 0;
  3123   3146   #ifdef WHERETRACE_ENABLED
  3124   3147           WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", 
  3125   3148                      (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
  3126   3149           if( sqlite3WhereTrace & 0x400 ){
  3127         -          for(i=0; i<sSubBuild.pWC->nTerm; i++){
  3128         -            whereTermPrint(&sSubBuild.pWC->a[i], i);
  3129         -          }
         3150  +          sqlite3WhereClausePrint(sSubBuild.pWC);
  3130   3151           }
  3131   3152   #endif
  3132   3153   #ifndef SQLITE_OMIT_VIRTUALTABLE
  3133   3154           if( IsVirtual(pItem->pTab) ){
  3134   3155             rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
  3135   3156           }else
  3136   3157   #endif
................................................................................
  4306   4327       sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
  4307   4328       if( wctrlFlags & WHERE_USE_LIMIT ){
  4308   4329         sqlite3DebugPrintf(", limit: %d", iAuxArg);
  4309   4330       }
  4310   4331       sqlite3DebugPrintf(")\n");
  4311   4332     }
  4312   4333     if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
  4313         -    int i;
  4314         -    for(i=0; i<sWLB.pWC->nTerm; i++){
  4315         -      whereTermPrint(&sWLB.pWC->a[i], i);
  4316         -    }
         4334  +    sqlite3WhereClausePrint(sWLB.pWC);
  4317   4335     }
  4318   4336   #endif
  4319   4337   
  4320   4338     if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
  4321   4339       rc = whereLoopAddAll(&sWLB);
  4322   4340       if( rc ) goto whereBeginError;
  4323   4341     

Changes to src/whereInt.h.

   433    433   
   434    434   /*
   435    435   ** Private interfaces - callable only by other where.c routines.
   436    436   **
   437    437   ** where.c:
   438    438   */
   439    439   Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
          440  +#ifdef WHERETRACE_ENABLED
          441  +void sqlite3WhereClausePrint(WhereClause *pWC);
          442  +#endif
   440    443   WhereTerm *sqlite3WhereFindTerm(
   441    444     WhereClause *pWC,     /* The WHERE clause to be searched */
   442    445     int iCur,             /* Cursor number of LHS */
   443    446     int iColumn,          /* Column number of LHS */
   444    447     Bitmask notReady,     /* RHS must not overlap with this mask */
   445    448     u32 op,               /* Mask of WO_xx values describing operator */
   446    449     Index *pIdx           /* Must be compatible with this index, if not NULL */

Changes to src/wherecode.c.

   967    967       assert( pTerm->pExpr!=0 );
   968    968       assert( omitTable==0 );
   969    969       testcase( pTerm->wtFlags & TERM_VIRTUAL );
   970    970       iReleaseReg = ++pParse->nMem;
   971    971       iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
   972    972       if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
   973    973       addrNxt = pLevel->addrNxt;
   974         -    sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
   975         -    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
          974  +    sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
   976    975       VdbeCoverage(v);
   977    976       sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
   978    977       sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
   979    978       VdbeComment((v, "pk"));
   980    979       pLevel->op = OP_Noop;
   981    980     }else if( (pLoop->wsFlags & WHERE_IPK)!=0
   982    981            && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0

Changes to src/whereexpr.c.

   564    564           sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
   565    565           sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
   566    566           sqlite3WhereExprAnalyze(pSrc, pAndWC);
   567    567           pAndWC->pOuter = pWC;
   568    568           if( !db->mallocFailed ){
   569    569             for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
   570    570               assert( pAndTerm->pExpr );
   571         -            if( allowedOp(pAndTerm->pExpr->op) ){
          571  +            if( allowedOp(pAndTerm->pExpr->op) 
          572  +             || pAndTerm->eOperator==WO_MATCH 
          573  +            ){
   572    574                 b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
   573    575               }
   574    576             }
   575    577           }
   576    578           indexable &= b;
   577    579         }
   578    580       }else if( pOrTerm->wtFlags & TERM_COPIED ){
................................................................................
  1118   1120   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1119   1121     /* Add a WO_MATCH auxiliary term to the constraint set if the
  1120   1122     ** current expression is of the form:  column MATCH expr.
  1121   1123     ** This information is used by the xBestIndex methods of
  1122   1124     ** virtual tables.  The native query optimizer does not attempt
  1123   1125     ** to do anything with MATCH functions.
  1124   1126     */
  1125         -  if( isMatchOfColumn(pExpr, &eOp2) ){
         1127  +  if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){
  1126   1128       int idxNew;
  1127   1129       Expr *pRight, *pLeft;
  1128   1130       WhereTerm *pNewTerm;
  1129   1131       Bitmask prereqColumn, prereqExpr;
  1130   1132   
  1131   1133       pRight = pExpr->x.pList->a[0].pExpr;
  1132   1134       pLeft = pExpr->x.pList->a[1].pExpr;

Added test/bestindex3.test.

            1  +# 2016 May 29
            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  +set testdir [file dirname $argv0]
           13  +source $testdir/tester.tcl
           14  +set testprefix bestindex3
           15  +
           16  +ifcapable !vtab {
           17  +  finish_test
           18  +  return
           19  +}
           20  +
           21  +#-------------------------------------------------------------------------
           22  +# Virtual table callback for a virtual table named $tbl.
           23  +#
           24  +# The table created is:
           25  +#
           26  +#      "CREATE TABLE t1 (a, b, c)"
           27  +#
           28  +# This virtual table supports both LIKE and = operators on all columns.
           29  +#  
           30  +proc vtab_cmd {bOmit method args} {
           31  +  switch -- $method {
           32  +    xConnect {
           33  +      return "CREATE TABLE t1(a, b, c)"
           34  +    }
           35  +
           36  +    xBestIndex {
           37  +      foreach {clist orderby mask} $args {}
           38  +
           39  +      set ret [list]
           40  +      set use use
           41  +      if {$bOmit} {set use omit}
           42  +
           43  +      for {set i 0} {$i < [llength $clist]} {incr i} {
           44  +        array unset C
           45  +        array set C [lindex $clist $i]
           46  +        if {$C(usable) && ($C(op)=="like" || $C(op)=="eq")} {
           47  +          lappend ret $use $i
           48  +          lappend ret idxstr 
           49  +          lappend ret "[lindex {a b c} $C(column)] [string toupper $C(op)] ?"
           50  +          break
           51  +        }
           52  +      }
           53  +
           54  +      if {$ret==""} {
           55  +        lappend ret cost 1000000 rows 1000000
           56  +      } else {
           57  +        lappend ret cost 100 rows 10
           58  +      }
           59  +      return $ret
           60  +    }
           61  +
           62  +    xFilter {
           63  +      foreach {idxnum idxstr param} $args {}
           64  +      set where ""
           65  +      if {$bOmit && $idxstr != ""} {
           66  +        set where " WHERE [string map [list ? '$param' EQ =] $idxstr]"
           67  +      }
           68  +      return [list sql "SELECT rowid, * FROM ttt$where"]
           69  +    }
           70  +  }
           71  +  return ""
           72  +}
           73  +
           74  +register_tcl_module db
           75  +
           76  +do_execsql_test 1.0 {
           77  +  CREATE VIRTUAL TABLE t1 USING tcl("vtab_cmd 0");
           78  +}
           79  +
           80  +do_eqp_test 1.1 {
           81  +  SELECT * FROM t1 WHERE a LIKE 'abc';
           82  +} {
           83  +  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?}
           84  +}
           85  +
           86  +do_eqp_test 1.2 {
           87  +  SELECT * FROM t1 WHERE a = 'abc';
           88  +} {
           89  +  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}
           90  +}
           91  +
           92  +do_eqp_test 1.3 {
           93  +  SELECT * FROM t1 WHERE a = 'abc' OR b = 'def';
           94  +} {
           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 ?}
           97  +}
           98  +
           99  +do_eqp_test 1.4 {
          100  +  SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def';
          101  +} {
          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 ?}
          104  +}
          105  +
          106  +do_execsql_test 1.5 {
          107  +  CREATE TABLE ttt(a, b, c);
          108  +
          109  +  INSERT INTO ttt VALUES(1, 'two',   'three');
          110  +  INSERT INTO ttt VALUES(2, 'one',   'two');
          111  +  INSERT INTO ttt VALUES(3, 'three', 'one');
          112  +  INSERT INTO ttt VALUES(4, 'y',     'one');
          113  +  INSERT INTO ttt VALUES(5, 'x',     'two');
          114  +  INSERT INTO ttt VALUES(6, 'y',     'three');
          115  +}
          116  +
          117  +foreach omit {0 1} {
          118  +  do_execsql_test 1.6.$omit.0 "
          119  +    DROP TABLE t1;
          120  +    CREATE VIRTUAL TABLE t1 USING tcl('vtab_cmd $omit');
          121  +  "
          122  +  do_execsql_test 1.6.$omit.1 { 
          123  +    SELECT rowid FROM t1 WHERE c LIKE 'o%'
          124  +  } {3 4}
          125  +
          126  +  do_execsql_test 1.6.$omit.2 { 
          127  +    SELECT rowid FROM t1 WHERE c LIKE 'o%' OR b='y'
          128  +  } {3 4 6}
          129  +
          130  +  do_execsql_test 1.6.$omit.3 { 
          131  +    SELECT rowid FROM t1 WHERE c = 'three' OR c LIKE 'o%'
          132  +  } {1 6 3 4}
          133  +}
          134  +
          135  +#-------------------------------------------------------------------------
          136  +# Test the same pattern works with ordinary tables.
          137  +#
          138  +do_execsql_test 2.1 {
          139  +  CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT);
          140  +  CREATE INDEX t2x ON t2(x COLLATE nocase);
          141  +  CREATE INDEX t2y ON t2(y);
          142  +}
          143  +
          144  +do_eqp_test 2.2 {
          145  +  SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def'
          146  +} {
          147  +  0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)}
          148  +  0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)}
          149  +}
          150  +
          151  +#-------------------------------------------------------------------------
          152  +# Test that any PRIMARY KEY within a sqlite3_decl_vtab() CREATE TABLE 
          153  +# statement is currently ignored.
          154  +#
          155  +proc vvv_command {method args} {
          156  +  switch -- $method {
          157  +    xConnect { return "CREATE TABLE t1(a PRIMARY KEY, b, c)" }
          158  +  }
          159  +}
          160  +proc yyy_command {method args} {
          161  +  switch -- $method {
          162  +    xConnect { return "CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b))" }
          163  +  }
          164  +}
          165  +
          166  +do_execsql_test 3.1 { CREATE VIRTUAL TABLE t3 USING tcl('vvv_command') }
          167  +do_execsql_test 3.2 { CREATE VIRTUAL TABLE t4 USING tcl('yyy_command') }
          168  +
          169  +finish_test
          170  +

Added test/csv01.test.

            1  +# 2016-06-02
            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  +# Test cases for CSV virtual table.
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +set testprefix closure01
           17  +
           18  +ifcapable !vtab||!cte { finish_test ; return }
           19  +
           20  +load_static_extension db csv
           21  +
           22  +do_execsql_test 1.0 {
           23  +  CREATE VIRTUAL TABLE temp.t1 USING csv(
           24  +    data=
           25  +'1,2,3,4
           26  +5,6,7,8
           27  +9,10,11,12
           28  +13,14,15,16
           29  +',
           30  +    columns=4
           31  +  );
           32  +  SELECT * FROM t1 WHERE c1=10;
           33  +} {9 10 11 12}
           34  +do_execsql_test 1.1 {
           35  +  SELECT * FROM t1 WHERE c1='10';
           36  +} {9 10 11 12}
           37  +do_execsql_test 1.2 {
           38  +  SELECT rowid FROM t1;
           39  +} {1 2 3 4}
           40  +
           41  +do_execsql_test 2.0 {
           42  +  DROP TABLE t1;
           43  +  CREATE VIRTUAL TABLE temp.t2 USING csv(
           44  +    data=
           45  +'1,2,3,4
           46  +5,6,7,8
           47  +9,10,11,12
           48  +13,14,15,16
           49  +',
           50  +    columns=4,
           51  +    schema='CREATE TABLE t2(a INT, b TEXT, c REAL, d BLOB)'
           52  +  );
           53  +  SELECT * FROM t2 WHERE a=9;
           54  +} {9 10 11 12}
           55  +do_execsql_test 2.1 {
           56  +  SELECT * FROM t2 WHERE b=10;
           57  +} {9 10 11 12}
           58  +do_execsql_test 2.2 {
           59  +  SELECT * FROM t2 WHERE c=11;
           60  +} {9 10 11 12}
           61  +do_execsql_test 2.3 {
           62  +  SELECT * FROM t2 WHERE d=12;
           63  +} {}
           64  +do_execsql_test 2.4 {
           65  +  SELECT * FROM t2 WHERE d='12';
           66  +} {9 10 11 12}
           67  +do_execsql_test 2.5 {
           68  +  SELECT * FROM t2 WHERE a='9';
           69  +} {9 10 11 12}
           70  +
           71  +do_execsql_test 3.0 {
           72  +  DROP TABLE t2;
           73  +  CREATE VIRTUAL TABLE temp.t3 USING csv(
           74  +    data=
           75  +'1,2,3,4
           76  +5,6,7,8
           77  +9,10,11,12
           78  +13,14,15,16
           79  +',
           80  +    columns=4,
           81  +    schema=
           82  +      'CREATE TABLE t3(a PRIMARY KEY,b TEXT,c TEXT,d TEXT) WITHOUT ROWID',
           83  +    testflags=1
           84  +  );
           85  +  SELECT a FROM t3 WHERE b=6 OR c=7 OR d=12 ORDER BY +a;
           86  +} {5 9}
           87  +do_execsql_test 3.1 {
           88  +  SELECT a FROM t3 WHERE +b=6 OR c=7 OR d=12 ORDER BY +a;
           89  +} {5 9}
           90  +
           91  +# The rowid column is not visible on a WITHOUT ROWID virtual table
           92  +do_catchsql_test 3.2 {
           93  +  SELECT rowid, a FROM t3;
           94  +} {1 {no such column: rowid}}
           95  +
           96  +do_catchsql_test 4.0 {
           97  +  DROP TABLE t3;
           98  +  CREATE VIRTUAL TABLE temp.t4 USING csv_wr(
           99  +    data=
          100  +'1,2,3,4
          101  +5,6,7,8
          102  +9,10,11,12
          103  +13,14,15,16
          104  +',
          105  +    columns=4,
          106  +    schema=
          107  +      'CREATE TABLE t3(a PRIMARY KEY,b TEXT,c TEXT,d TEXT) WITHOUT ROWID',
          108  +    testflags=1
          109  +  );
          110  +} {1 {vtable constructor failed: t4}}
          111  +
          112  +finish_test

Changes to test/ctime.test.

   198    198       set N [ expr {$tc-1} ]
   199    199       set ans1 [ catchsql {
   200    200         SELECT sqlite_compileoption_get($N);
   201    201       } ]
   202    202       set ans2 [ catchsql {
   203    203         SELECT sqlite_compileoption_used($opt);
   204    204       } ]
   205         -    list [ lindex $ans1 0 ] [ expr { [lindex $ans1 1]==$opt } ] \
          205  +    list [ lindex $ans1 0 ] [ expr { [lindex [lindex $ans1 1] 0]==$opt } ] \
   206    206            [ expr { $ans2 } ]
   207    207     } {0 1 {0 1}}
   208    208     incr tc 1
   209    209   }
   210    210   # test 1 past array bounds
   211    211   do_test ctime-2.5.$tc {
   212    212     set N [ expr {$tc-1} ]

Changes to test/index6.test.

   371    371   do_execsql_test index6-10.3 {
   372    372     SELECT e FROM t10 WHERE a=1 AND b=2 ORDER BY d DESC;
   373    373   } {9 5}
   374    374   do_execsql_test index6-10.3eqp {
   375    375     EXPLAIN QUERY PLAN
   376    376     SELECT e FROM t10 WHERE a=1 AND b=2 ORDER BY d DESC;
   377    377   } {~/USING INDEX t10x/}
          378  +
          379  +# A partial index will be used for a full table scan, where possible
          380  +do_execsql_test index6-11.1 {
          381  +  CREATE TABLE t11(a,b,c);
          382  +  CREATE INDEX t11x ON t11(a) WHERE b<>99;
          383  +  EXPLAIN QUERY PLAN SELECT a FROM t11 WHERE b<>99;
          384  +} {/USING INDEX t11x/}
          385  +do_execsql_test index6-11.2 {
          386  +  EXPLAIN QUERY PLAN SELECT a FROM t11 WHERE b<>99 AND c<>98;
          387  +} {/USING INDEX t11x/}
          388  +  
   378    389   
   379    390   finish_test

Changes to test/misc5.test.

   566    566         LIMIT (SELECT lmt FROM logs_base) ;
   567    567       }
   568    568     } {1 {no such table: logs_base}}
   569    569   }
   570    570   
   571    571   # Overflow the lemon parser stack by providing an overly complex
   572    572   # expression.  Make sure that the overflow is detected and reported.
          573  +#
          574  +# This test fails when building with -DYYSTACKDEPTH=0
   573    575   #
   574    576   do_test misc5-7.1 {
   575    577     execsql {CREATE TABLE t1(x)}
   576    578     set sql "INSERT INTO t1 VALUES("
   577    579     set tail ""
   578    580     for {set i 0} {$i<200} {incr i} {
   579    581       append sql "(1+"

Changes to test/speedtest1.c.

  1211   1211           break;
  1212   1212         }
  1213   1213       }
  1214   1214     }
  1215   1215     fclose(in);
  1216   1216   }   
  1217   1217   #endif
         1218  +
         1219  +#if SQLITE_VERSION_NUMBER<3006018
         1220  +#  define sqlite3_sourceid(X) "(before 3.6.18)"
         1221  +#endif
  1218   1222   
  1219   1223   int main(int argc, char **argv){
  1220   1224     int doAutovac = 0;            /* True for --autovacuum */
  1221   1225     int cacheSize = 0;            /* Desired cache size.  0 means default */
  1222   1226     int doExclusive = 0;          /* True for --exclusive */
  1223   1227     int nHeap = 0, mnHeap = 0;    /* Heap size from --heap */
  1224   1228     int doIncrvac = 0;            /* True for --incrvacuum */

Changes to test/stat.test.

    28     28   
    29     29   set ::asc 1
    30     30   proc a_string {n} { string range [string repeat [incr ::asc]. $n] 1 $n }
    31     31   db func a_string a_string
    32     32   
    33     33   register_dbstat_vtab db
    34     34   do_execsql_test stat-0.0 {
           35  +  PRAGMA table_info(dbstat);
           36  +} {/0 name TEXT .* 1 path TEXT .* 9 pgsize INTEGER/}
           37  +do_execsql_test stat-0.1 {
    35     38     PRAGMA auto_vacuum = OFF;
    36     39     CREATE VIRTUAL TABLE temp.stat USING dbstat;
    37     40     SELECT * FROM stat;
    38     41   } {}
    39     42   
    40     43   if {[wal_is_capable]} {
    41     44     do_execsql_test stat-0.1 {

Changes to test/tclsqlite.test.

   630    630   do_execsql_test tcl-14.1 {
   631    631     CREATE TABLE t6(x);
   632    632     INSERT INTO t6 VALUES(1);
   633    633   }
   634    634   do_test tcl-14.2 {
   635    635     db one {SELECT x FROM t6 WHERE xCall()!='value'}
   636    636   } {}
          637  +
          638  +# Verify that the "exists" and "onecolumn" methods work when
          639  +# a "profile" is registered.
          640  +#
          641  +catch {db close}
          642  +sqlite3 db :memory:
          643  +proc noop-profile {args} {
          644  +  return
          645  +}
          646  +do_test tcl-15.0 {
          647  +  db eval {CREATE TABLE t1(a); INSERT INTO t1 VALUES(1),(2),(3);}
          648  +  db onecolumn {SELECT a FROM t1 WHERE a>2}
          649  +} {3}
          650  +do_test tcl-15.1 {
          651  +  db exists {SELECT a FROM t1 WHERE a>2}
          652  +} {1}
          653  +do_test tcl-15.2 {
          654  +  db exists {SELECT a FROM t1 WHERE a>3}
          655  +} {0}
          656  +db profile noop-profile
          657  +do_test tcl-15.3 {
          658  +  db onecolumn {SELECT a FROM t1 WHERE a>2}
          659  +} {3}
          660  +do_test tcl-15.4 {
          661  +  db exists {SELECT a FROM t1 WHERE a>2}
          662  +} {1}
          663  +do_test tcl-15.5 {
          664  +  db exists {SELECT a FROM t1 WHERE a>3}
          665  +} {0}
          666  +
          667  +
          668  +
          669  +
   637    670   
   638    671   
   639    672   
   640    673   finish_test

Added test/walcrash4.test.

            1  +# 2010 May 25
            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  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +source $testdir/lock_common.tcl
           17  +source $testdir/wal_common.tcl
           18  +ifcapable !wal {finish_test ; return }
           19  +set testprefix walcrash4
           20  +
           21  +#-------------------------------------------------------------------------
           22  +# At one point, if "PRAGMA synchronous=full" is set and the platform
           23  +# does not support POWERSAFE_OVERWRITE, and the last frame written to 
           24  +# the wal file in a transaction is aligned with a sector boundary, the
           25  +# xSync() call was omitted. 
           26  +#
           27  +# The following test verifies that this has been fixed.
           28  +#
           29  +do_execsql_test 1.0 {
           30  +  PRAGMA autovacuum = 0;
           31  +  PRAGMA page_size = 1024;
           32  +  PRAGMA journal_mode = wal;
           33  +  PRAGMA main.synchronous = full;
           34  +} {wal}
           35  +
           36  +faultsim_save_and_close
           37  +
           38  +# The error message is different on unix and windows
           39  +#
           40  +if {$::tcl_platform(platform)=="windows"} {
           41  + set msg "child killed: unknown signal"
           42  +} else {
           43  + set msg "child process exited abnormally"
           44  +}
           45  +
           46  +for {set nExtra 0} {$nExtra < 10} {incr nExtra} {
           47  +  for {set i 0} {$i < 10} {incr i} {
           48  +    do_test 1.nExtra=$nExtra.i=$i.1 {
           49  +      faultsim_restore_and_reopen
           50  +    
           51  +      set fd [open crash.tcl w]
           52  +      puts $fd [subst -nocommands {
           53  +        sqlite3_crash_enable 1
           54  +        sqlite3_test_control_pending_byte $::sqlite_pending_byte
           55  +        sqlite3 db test.db -vfs crash
           56  +        db eval {
           57  +          PRAGMA main.synchronous=FULL;
           58  +          BEGIN;
           59  +          CREATE TABLE t1(x UNIQUE);
           60  +        }
           61  +        for {set e 2} {[set e] < ($nExtra+2)} {incr e} {
           62  +          db eval "CREATE TABLE t[set e] (x)"
           63  +        }
           64  +        db eval {
           65  +          INSERT INTO t1 VALUES( randomblob(170000) );
           66  +          COMMIT;
           67  +        }
           68  +        sqlite3_crash_now
           69  +      }]
           70  +      close $fd
           71  +    
           72  +      set r [catch { exec [info nameofexec] crash.tcl >@stdout } msg]
           73  +      list $r $msg
           74  +    } "1 {$msg}"
           75  +  
           76  +    do_execsql_test 1.nExtra=$nExtra.i=$i.2 { 
           77  +      SELECT count(*) FROM t1;
           78  +      PRAGMA integrity_check;
           79  +    } {1 ok}
           80  +  } 
           81  +}
           82  +
           83  +
           84  +finish_test

Added tool/dbhash.c.

            1  +/*
            2  +** 2016-06-07
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This is a utility program that computes an SHA1 hash on the content
           14  +** of an SQLite database.
           15  +**
           16  +** The hash is computed over just the content of the database.  Free
           17  +** space inside of the database file, and alternative on-disk representations
           18  +** of the same content (ex: UTF8 vs UTF16) do not affect the hash.  So,
           19  +** for example, the database file page size, encoding, and auto_vacuum setting
           20  +** can all be changed without changing the hash.
           21  +*/
           22  +#include <stdio.h>
           23  +#include <stdlib.h>
           24  +#include <stdarg.h>
           25  +#include <ctype.h>
           26  +#include <string.h>
           27  +#include <assert.h>
           28  +#include "sqlite3.h"
           29  +
           30  +/* Context for the SHA1 hash */
           31  +typedef struct SHA1Context SHA1Context;
           32  +struct SHA1Context {
           33  +  unsigned int state[5];
           34  +  unsigned int count[2];
           35  +  unsigned char buffer[64];
           36  +};
           37  +
           38  +/*
           39  +** All global variables are gathered into the "g" singleton.
           40  +*/
           41  +struct GlobalVars {
           42  +  const char *zArgv0;       /* Name of program */
           43  +  unsigned fDebug;          /* Debug flags */
           44  +  sqlite3 *db;              /* The database connection */
           45  +  SHA1Context cx;           /* SHA1 hash context */
           46  +} g;
           47  +
           48  +/*
           49  +** Debugging flags
           50  +*/
           51  +#define DEBUG_FULLTRACE   0x00000001   /* Trace hash to stderr */
           52  +
           53  +/******************************************************************************
           54  +** The Hash Engine
           55  +**
           56  +** Modify these routines (and appropriate state fields in global variable 'g')
           57  +** in order to compute a different (better?) hash of the database.
           58  +*/
           59  +/*
           60  + * blk0() and blk() perform the initial expand.
           61  + * I got the idea of expanding during the round function from SSLeay
           62  + *
           63  + * blk0le() for little-endian and blk0be() for big-endian.
           64  + */
           65  +#if __GNUC__ && (defined(__i386__) || defined(__x86_64__))
           66  +/*
           67  + * GCC by itself only generates left rotates.  Use right rotates if
           68  + * possible to be kinder to dinky implementations with iterative rotate
           69  + * instructions.
           70  + */
           71  +#define SHA_ROT(op, x, k) \
           72  +        ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; })
           73  +#define rol(x,k) SHA_ROT("roll", x, k)
           74  +#define ror(x,k) SHA_ROT("rorl", x, k)
           75  +
           76  +#else
           77  +/* Generic C equivalent */
           78  +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
           79  +#define rol(x,k) SHA_ROT(x,k,32-(k))
           80  +#define ror(x,k) SHA_ROT(x,32-(k),k)
           81  +#endif
           82  +
           83  +
           84  +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
           85  +    |(rol(block[i],8)&0x00FF00FF))
           86  +#define blk0be(i) block[i]
           87  +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
           88  +    ^block[(i+2)&15]^block[i&15],1))
           89  +
           90  +/*
           91  + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
           92  + *
           93  + * Rl0() for little-endian and Rb0() for big-endian.  Endianness is
           94  + * determined at run-time.
           95  + */
           96  +#define Rl0(v,w,x,y,z,i) \
           97  +    z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2);
           98  +#define Rb0(v,w,x,y,z,i) \
           99  +    z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2);
          100  +#define R1(v,w,x,y,z,i) \
          101  +    z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2);
          102  +#define R2(v,w,x,y,z,i) \
          103  +    z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2);
          104  +#define R3(v,w,x,y,z,i) \
          105  +    z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2);
          106  +#define R4(v,w,x,y,z,i) \
          107  +    z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2);
          108  +
          109  +/*
          110  + * Hash a single 512-bit block. This is the core of the algorithm.
          111  + */
          112  +#define a qq[0]
          113  +#define b qq[1]
          114  +#define c qq[2]
          115  +#define d qq[3]
          116  +#define e qq[4]
          117  +
          118  +void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
          119  +  unsigned int qq[5]; /* a, b, c, d, e; */
          120  +  static int one = 1;
          121  +  unsigned int block[16];
          122  +  memcpy(block, buffer, 64);
          123  +  memcpy(qq,state,5*sizeof(unsigned int));
          124  +
          125  +  /* Copy g.cx.state[] to working vars */
          126  +  /*
          127  +  a = state[0];
          128  +  b = state[1];
          129  +  c = state[2];
          130  +  d = state[3];
          131  +  e = state[4];
          132  +  */
          133  +
          134  +  /* 4 rounds of 20 operations each. Loop unrolled. */
          135  +  if( 1 == *(unsigned char*)&one ){
          136  +    Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3);
          137  +    Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7);
          138  +    Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11);
          139  +    Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15);
          140  +  }else{
          141  +    Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3);
          142  +    Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7);
          143  +    Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11);
          144  +    Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15);
          145  +  }
          146  +  R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
          147  +  R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
          148  +  R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
          149  +  R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
          150  +  R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
          151  +  R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
          152  +  R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
          153  +  R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
          154  +  R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
          155  +  R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
          156  +  R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
          157  +  R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
          158  +  R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
          159  +  R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
          160  +  R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
          161  +  R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
          162  +
          163  +  /* Add the working vars back into context.state[] */
          164  +  state[0] += a;
          165  +  state[1] += b;
          166  +  state[2] += c;
          167  +  state[3] += d;
          168  +  state[4] += e;
          169  +}
          170  +
          171  +
          172  +/* Initialize the SHA1 hash */
          173  +static void hash_init(void){
          174  +  /* SHA1 initialization constants */
          175  +  g.cx.state[0] = 0x67452301;
          176  +  g.cx.state[1] = 0xEFCDAB89;
          177  +  g.cx.state[2] = 0x98BADCFE;
          178  +  g.cx.state[3] = 0x10325476;
          179  +  g.cx.state[4] = 0xC3D2E1F0;
          180  +  g.cx.count[0] = g.cx.count[1] = 0;
          181  +}
          182  +
          183  +/* Add new content to the SHA1 hash */
          184  +static void hash_step(const unsigned char *data,  unsigned int len){
          185  +  unsigned int i, j;
          186  +
          187  +  j = g.cx.count[0];
          188  +  if( (g.cx.count[0] += len << 3) < j ){
          189  +    g.cx.count[1] += (len>>29)+1;
          190  +  }
          191  +  j = (j >> 3) & 63;
          192  +  if( (j + len) > 63 ){
          193  +    (void)memcpy(&g.cx.buffer[j], data, (i = 64-j));
          194  +    SHA1Transform(g.cx.state, g.cx.buffer);
          195  +    for(; i + 63 < len; i += 64){
          196  +      SHA1Transform(g.cx.state, &data[i]);
          197  +    }
          198  +    j = 0;
          199  +  }else{
          200  +    i = 0;
          201  +  }
          202  +  (void)memcpy(&g.cx.buffer[j], &data[i], len - i);
          203  +}
          204  +
          205  +
          206  +/* Add padding and compute and output the message digest. */
          207  +static void hash_finish(const char *zName){
          208  +  unsigned int i;
          209  +  unsigned char finalcount[8];
          210  +  unsigned char digest[20];
          211  +  static const char zEncode[] = "0123456789abcdef";
          212  +  char zOut[41];
          213  +
          214  +  for (i = 0; i < 8; i++){
          215  +    finalcount[i] = (unsigned char)((g.cx.count[(i >= 4 ? 0 : 1)]
          216  +       >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
          217  +  }
          218  +  hash_step((const unsigned char *)"\200", 1);
          219  +  while ((g.cx.count[0] & 504) != 448){
          220  +    hash_step((const unsigned char *)"\0", 1);
          221  +  }
          222  +  hash_step(finalcount, 8);  /* Should cause a SHA1Transform() */
          223  +  for (i = 0; i < 20; i++){
          224  +    digest[i] = (unsigned char)((g.cx.state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
          225  +  }
          226  +  for(i=0; i<20; i++){
          227  +    zOut[i*2] = zEncode[(digest[i]>>4)&0xf];
          228  +    zOut[i*2+1] = zEncode[digest[i] & 0xf];
          229  +  }
          230  +  zOut[i*2]= 0;
          231  +  printf("%s %s\n", zOut, zName);
          232  +}
          233  +/* End of the hashing logic
          234  +*******************************************************************************/
          235  +  
          236  +/*
          237  +** Print an error resulting from faulting command-line arguments and
          238  +** abort the program.
          239  +*/
          240  +static void cmdlineError(const char *zFormat, ...){
          241  +  va_list ap;
          242  +  fprintf(stderr, "%s: ", g.zArgv0);
          243  +  va_start(ap, zFormat);
          244  +  vfprintf(stderr, zFormat, ap);
          245  +  va_end(ap);
          246  +  fprintf(stderr, "\n\"%s --help\" for more help\n", g.zArgv0);
          247  +  exit(1);
          248  +}
          249  +
          250  +/*
          251  +** Print an error message for an error that occurs at runtime, then
          252  +** abort the program.
          253  +*/
          254  +static void runtimeError(const char *zFormat, ...){
          255  +  va_list ap;
          256  +  fprintf(stderr, "%s: ", g.zArgv0);
          257  +  va_start(ap, zFormat);
          258  +  vfprintf(stderr, zFormat, ap);
          259  +  va_end(ap);
          260  +  fprintf(stderr, "\n");
          261  +  exit(1);
          262  +}
          263  +
          264  +/*
          265  +** Prepare a new SQL statement.  Print an error and abort if anything
          266  +** goes wrong.
          267  +*/
          268  +static sqlite3_stmt *db_vprepare(const char *zFormat, va_list ap){
          269  +  char *zSql;
          270  +  int rc;
          271  +  sqlite3_stmt *pStmt;
          272  +
          273  +  zSql = sqlite3_vmprintf(zFormat, ap);
          274  +  if( zSql==0 ) runtimeError("out of memory");
          275  +  rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
          276  +  if( rc ){
          277  +    runtimeError("SQL statement error: %s\n\"%s\"", sqlite3_errmsg(g.db),
          278  +                 zSql);
          279  +  }
          280  +  sqlite3_free(zSql);
          281  +  return pStmt;
          282  +}
          283  +static sqlite3_stmt *db_prepare(const char *zFormat, ...){
          284  +  va_list ap;
          285  +  sqlite3_stmt *pStmt;
          286  +  va_start(ap, zFormat);
          287  +  pStmt = db_vprepare(zFormat, ap);
          288  +  va_end(ap);
          289  +  return pStmt;
          290  +}
          291  +
          292  +/*
          293  +** Compute the hash for all rows of the query formed from the printf-style
          294  +** zFormat and its argument.
          295  +*/
          296  +static void hash_one_query(const char *zFormat, ...){
          297  +  va_list ap;
          298  +  sqlite3_stmt *pStmt;        /* The query defined by zFormat and "..." */
          299  +  int nCol;                   /* Number of columns in the result set */
          300  +  int i;                      /* Loop counter */
          301  +
          302  +  /* Prepare the query defined by zFormat and "..." */
          303  +  va_start(ap, zFormat);
          304  +  pStmt = db_vprepare(zFormat, ap);
          305  +  va_end(ap);
          306  +  nCol = sqlite3_column_count(pStmt);
          307  +
          308  +  /* Compute a hash over the result of the query */
          309  +  while( SQLITE_ROW==sqlite3_step(pStmt) ){
          310  +    for(i=0; i<nCol; i++){
          311  +      switch( sqlite3_column_type(pStmt,i) ){
          312  +        case SQLITE_NULL: {
          313  +          hash_step((const unsigned char*)"0",1);
          314  +          if( g.fDebug & DEBUG_FULLTRACE ) fprintf(stderr, "NULL\n");
          315  +          break;
          316  +        }
          317  +        case SQLITE_INTEGER: {
          318  +          sqlite3_uint64 u;
          319  +          int j;
          320  +          unsigned char x[8];
          321  +          sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
          322  +          memcpy(&u, &v, 8);
          323  +          for(j=7; j>=0; j--){
          324  +            x[j] = u & 0xff;
          325  +            u >>= 8;
          326  +          }
          327  +          hash_step((const unsigned char*)"1",1);
          328  +          hash_step(x,8);
          329  +          if( g.fDebug & DEBUG_FULLTRACE ){
          330  +            fprintf(stderr, "INT %s\n", sqlite3_column_text(pStmt,i));
          331  +          }
          332  +          break;
          333  +        }
          334  +        case SQLITE_FLOAT: {
          335  +          sqlite3_uint64 u;
          336  +          int j;
          337  +          unsigned char x[8];
          338  +          double r = sqlite3_column_double(pStmt,i);
          339  +          memcpy(&u, &r, 8);
          340  +          for(j=7; j>=0; j--){
          341  +            x[j] = u & 0xff;
          342  +            u >>= 8;
          343  +          }
          344  +          hash_step((const unsigned char*)"2",1);
          345  +          hash_step(x,8);
          346  +          if( g.fDebug & DEBUG_FULLTRACE ){
          347  +            fprintf(stderr, "FLOAT %s\n", sqlite3_column_text(pStmt,i));
          348  +          }
          349  +          break;
          350  +        }
          351  +        case SQLITE_TEXT: {
          352  +          int n = sqlite3_column_bytes(pStmt, i);
          353  +          const unsigned char *z = sqlite3_column_text(pStmt, i);
          354  +          hash_step((const unsigned char*)"3", 1);
          355  +          hash_step(z, n);
          356  +          if( g.fDebug & DEBUG_FULLTRACE ){
          357  +            fprintf(stderr, "TEXT '%s'\n", sqlite3_column_text(pStmt,i));
          358  +          }
          359  +          break;
          360  +        }
          361  +        case SQLITE_BLOB: {
          362  +          int n = sqlite3_column_bytes(pStmt, i);
          363  +          const unsigned char *z = sqlite3_column_blob(pStmt, i);
          364  +          hash_step((const unsigned char*)"4", 1);
          365  +          hash_step(z, n);
          366  +          if( g.fDebug & DEBUG_FULLTRACE ){
          367  +            fprintf(stderr, "BLOB (%d bytes)\n", n);
          368  +          }
          369  +          break;
          370  +        }
          371  +      }
          372  +    }
          373  +  }
          374  +  sqlite3_finalize(pStmt);
          375  +}
          376  +
          377  +
          378  +/*
          379  +** Print sketchy documentation for this utility program
          380  +*/
          381  +static void showHelp(void){
          382  +  printf("Usage: %s [options] FILE ...\n", g.zArgv0);
          383  +  printf(
          384  +"Compute a SHA1 hash on the content of database FILE.  System tables such as\n"
          385  +"sqlite_stat1, sqlite_stat4, and sqlite_sequence are omitted from the hash.\n"
          386  +"Options:\n"
          387  +"   --debug N           Set debugging flags to N (experts only)\n"
          388  +"   --like PATTERN      Only hash tables whose name is LIKE the pattern\n"
          389  +"   --schema-only       Only hash the schema - omit table content\n"
          390  +"   --without-schema    Only hash table content - omit the schema\n"
          391  +  );
          392  +}
          393  +
          394  +int main(int argc, char **argv){
          395  +  const char *zDb = 0;         /* Name of the database currently being hashed */
          396  +  int i;                       /* Loop counter */
          397  +  int rc;                      /* Subroutine return code */
          398  +  char *zErrMsg;               /* Error message when opening database */
          399  +  sqlite3_stmt *pStmt;         /* An SQLite query */
          400  +  const char *zLike = 0;       /* LIKE pattern of tables to hash */
          401  +  int omitSchema = 0;          /* True to compute hash on content only */
          402  +  int omitContent = 0;         /* True to compute hash on schema only */
          403  +  int nFile = 0;               /* Number of input filenames seen */
          404  +
          405  +  g.zArgv0 = argv[0];
          406  +  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
          407  +  for(i=1; i<argc; i++){
          408  +    const char *z = argv[i];
          409  +    if( z[0]=='-' ){
          410  +      z++;
          411  +      if( z[0]=='-' ) z++;
          412  +      if( strcmp(z,"debug")==0 ){
          413  +        if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
          414  +        g.fDebug = strtol(argv[++i], 0, 0);
          415  +      }else
          416  +      if( strcmp(z,"help")==0 ){
          417  +        showHelp();
          418  +        return 0;
          419  +      }else
          420  +      if( strcmp(z,"like")==0 ){
          421  +        if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
          422  +        if( zLike!=0 ) cmdlineError("only one --like allowed");
          423  +        zLike = argv[++i];
          424  +      }else
          425  +      if( strcmp(z,"schema-only")==0 ){
          426  +        omitContent = 1;
          427  +      }else
          428  +      if( strcmp(z,"without-schema")==0 ){
          429  +        omitSchema = 1;
          430  +      }else
          431  +      {
          432  +        cmdlineError("unknown option: %s", argv[i]);
          433  +      }
          434  +    }else{
          435  +      nFile++;
          436  +      if( nFile<i ) argv[nFile] = argv[i];
          437  +    }
          438  +  }
          439  +  if( nFile==0 ){
          440  +    cmdlineError("no input files specified - nothing to do");
          441  +  }
          442  +  if( omitSchema && omitContent ){
          443  +    cmdlineError("only one of --without-schema and --omit-schema allowed");
          444  +  }
          445  +  if( zLike==0 ) zLike = "%";
          446  +
          447  +  for(i=1; i<=nFile; i++){
          448  +    static const int openFlags = 
          449  +       SQLITE_OPEN_READWRITE |     /* Read/write so hot journals can recover */
          450  +       SQLITE_OPEN_URI
          451  +    ;
          452  +    zDb = argv[i];
          453  +    rc = sqlite3_open_v2(zDb, &g.db, openFlags, 0);
          454  +    if( rc ){
          455  +      fprintf(stderr, "cannot open database file '%s'\n", zDb);
          456  +      continue;
          457  +    }
          458  +    rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
          459  +    if( rc || zErrMsg ){
          460  +      sqlite3_close(g.db);
          461  +      g.db = 0;
          462  +      fprintf(stderr, "'%s' is not a valid SQLite database\n", zDb);
          463  +      continue;
          464  +    }
          465  +
          466  +    /* Start the hash */
          467  +    hash_init();
          468  +  
          469  +    /* Hash table content */
          470  +    if( !omitContent ){
          471  +      pStmt = db_prepare(
          472  +        "SELECT name FROM sqlite_master\n"
          473  +        " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
          474  +        "   AND name NOT LIKE 'sqlite_%%'\n"
          475  +        "   AND name LIKE '%q'\n"
          476  +        " ORDER BY name COLLATE nocase;\n",
          477  +        zLike
          478  +      );
          479  +      while( SQLITE_ROW==sqlite3_step(pStmt) ){
          480  +        /* We want rows of the table to be hashed in PRIMARY KEY order.
          481  +        ** Technically, an ORDER BY clause is required to guarantee that
          482  +        ** order.  However, though not guaranteed by the documentation, every
          483  +        ** historical version of SQLite has always output rows in PRIMARY KEY
          484  +        ** order when there is no WHERE or GROUP BY clause, so the ORDER BY
          485  +        ** can be safely omitted. */
          486  +        hash_one_query("SELECT * FROM \"%w\"", sqlite3_column_text(pStmt,0));
          487  +      }
          488  +      sqlite3_finalize(pStmt);
          489  +    }
          490  +  
          491  +    /* Hash the database schema */
          492  +    if( !omitSchema ){
          493  +      hash_one_query(
          494  +         "SELECT type, name, tbl_name, sql FROM sqlite_master\n"
          495  +         " WHERE tbl_name LIKE '%q'\n"
          496  +         " ORDER BY name COLLATE nocase;\n",
          497  +         zLike
          498  +      );
          499  +    }
          500  +  
          501  +    /* Finish and output the hash and close the database connection. */
          502  +    hash_finish(zDb);
          503  +    sqlite3_close(g.db);
          504  +  }
          505  +  return 0;
          506  +}

Changes to tool/lemon.c.

   284    284     int nrhs;                /* Number of RHS symbols */
   285    285     struct symbol **rhs;     /* The RHS symbols */
   286    286     const char **rhsalias;   /* An alias for each RHS symbol (NULL if none) */
   287    287     int line;                /* Line number at which code begins */
   288    288     const char *code;        /* The code executed when this rule is reduced */
   289    289     const char *codePrefix;  /* Setup code before code[] above */
   290    290     const char *codeSuffix;  /* Breakdown code after code[] above */
          291  +  int noCode;              /* True if this rule has no associated C code */
          292  +  int codeEmitted;         /* True if the code has been emitted already */
   291    293     struct symbol *precsym;  /* Precedence symbol for this rule */
   292    294     int index;               /* An index number for this rule */
   293    295     int iRule;               /* Rule number as used in the generated tables */
   294    296     Boolean canReduce;       /* True if this rule is ever reduced */
          297  +  Boolean doesReduce;      /* Reduce actions occur after optimization */
   295    298     struct rule *nextlhs;    /* Next rule with the same LHS */
   296    299     struct rule *next;       /* Next rule in the global list */
   297    300   };
   298    301   
   299    302   /* A configuration is a production rule of the grammar together with
   300    303   ** a mark (dot) showing how much of that rule has been processed so far.
   301    304   ** Configurations also contain a follow-set which is a list of terminal
................................................................................
   335    338   struct action {
   336    339     struct symbol *sp;       /* The look-ahead symbol */
   337    340     enum e_action type;
   338    341     union {
   339    342       struct state *stp;     /* The new state, if a shift */
   340    343       struct rule *rp;       /* The rule, if a reduce */
   341    344     } x;
          345  +  struct symbol *spOpt;    /* SHIFTREDUCE optimization to this symbol */
   342    346     struct action *next;     /* Next action for this state */
   343    347     struct action *collide;  /* Next action with the same hash */
   344    348   };
   345    349   
   346    350   /* Each state of the generated parser's finite state machine
   347    351   ** is encoded as an instance of the following structure. */
   348    352   struct state {
   349    353     struct config *bp;       /* The basis configurations for this state */
   350    354     struct config *cfp;      /* All configurations in this set */
   351    355     int statenum;            /* Sequential number for this state */
   352         -  struct action *ap;       /* Array of actions for this state */
          356  +  struct action *ap;       /* List of actions for this state */
   353    357     int nTknAct, nNtAct;     /* Number of actions on terminals and nonterminals */
   354    358     int iTknOfst, iNtOfst;   /* yy_action[] offset for terminals and nonterms */
   355    359     int iDfltReduce;         /* Default action is to REDUCE by this rule */
   356    360     struct rule *pDfltReduce;/* The default REDUCE rule. */
   357    361     int autoReduce;          /* True if this is an auto-reduce state */
   358    362   };
   359    363   #define NO_OFFSET (-2147483647)
................................................................................
   526    530   ){
   527    531     struct action *newaction;
   528    532     newaction = Action_new();
   529    533     newaction->next = *app;
   530    534     *app = newaction;
   531    535     newaction->type = type;
   532    536     newaction->sp = sp;
          537  +  newaction->spOpt = 0;
   533    538     if( type==SHIFT ){
   534    539       newaction->x.stp = (struct state *)arg;
   535    540     }else{
   536    541       newaction->x.rp = (struct rule *)arg;
   537    542     }
   538    543   }
   539    544   /********************** New code to implement the "acttab" module ***********/
................................................................................
  1495   1500     user_templatename = (char *) malloc( lemonStrlen(z)+1 );
  1496   1501     if( user_templatename==0 ){
  1497   1502       memory_error();
  1498   1503     }
  1499   1504     lemon_strcpy(user_templatename, z);
  1500   1505   }
  1501   1506   
  1502         -/* Merge together to lists of rules order by rule.iRule */
         1507  +/* Merge together to lists of rules ordered by rule.iRule */
  1503   1508   static struct rule *Rule_merge(struct rule *pA, struct rule *pB){
  1504   1509     struct rule *pFirst = 0;
  1505   1510     struct rule **ppPrev = &pFirst;
  1506   1511     while( pA && pB ){
  1507   1512       if( pA->iRule<pB->iRule ){
  1508   1513         *ppPrev = pA;
  1509   1514         ppPrev = &pA->next;
................................................................................
  1638   1643     for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
  1639   1644     while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; }
  1640   1645     assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 );
  1641   1646     lem.nsymbol = i - 1;
  1642   1647     for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++);
  1643   1648     lem.nterminal = i;
  1644   1649   
  1645         -  /* Assign sequential rule numbers */
         1650  +  /* Assign sequential rule numbers.  Start with 0.  Put rules that have no
         1651  +  ** reduce action C-code associated with them last, so that the switch()
         1652  +  ** statement that selects reduction actions will have a smaller jump table.
         1653  +  */
  1646   1654     for(i=0, rp=lem.rule; rp; rp=rp->next){
  1647   1655       rp->iRule = rp->code ? i++ : -1;
  1648   1656     }
  1649   1657     for(rp=lem.rule; rp; rp=rp->next){
  1650   1658       if( rp->iRule<0 ) rp->iRule = i++;
  1651   1659     }
  1652   1660     lem.startRule = lem.rule;
................................................................................
  2207   2215             ErrorMsg(psp->filename,psp->tokenlineno,
  2208   2216   "Code fragment beginning on this line is not the first \
  2209   2217   to follow the previous rule.");
  2210   2218             psp->errorcnt++;
  2211   2219           }else{
  2212   2220             psp->prevrule->line = psp->tokenlineno;
  2213   2221             psp->prevrule->code = &x[1];
         2222  +          psp->prevrule->noCode = 0;
  2214   2223           }
  2215   2224         }else if( x[0]=='[' ){
  2216   2225           psp->state = PRECEDENCE_MARK_1;
  2217   2226         }else{
  2218   2227           ErrorMsg(psp->filename,psp->tokenlineno,
  2219   2228             "Token \"%s\" should be either \"%%\" or a nonterminal name.",
  2220   2229             x);
................................................................................
  2313   2322               rp->rhs[i] = psp->rhs[i];
  2314   2323               rp->rhsalias[i] = psp->alias[i];
  2315   2324             }
  2316   2325             rp->lhs = psp->lhs;
  2317   2326             rp->lhsalias = psp->lhsalias;
  2318   2327             rp->nrhs = psp->nrhs;
  2319   2328             rp->code = 0;
         2329  +          rp->noCode = 1;
  2320   2330             rp->precsym = 0;
  2321   2331             rp->index = psp->gp->nrule++;
  2322   2332             rp->nextlhs = rp->lhs->rule;
  2323   2333             rp->lhs->rule = rp;
  2324   2334             rp->next = 0;
  2325   2335             if( psp->firstrule==0 ){
  2326   2336               psp->firstrule = psp->lastrule = rp;
................................................................................
  3156   3166           result = 0;
  3157   3167         }
  3158   3168         break;
  3159   3169       case NOT_USED:
  3160   3170         result = 0;
  3161   3171         break;
  3162   3172     }
         3173  +  if( result && ap->spOpt ){
         3174  +    fprintf(fp,"  /* because %s==%s */", ap->sp->name, ap->spOpt->name);
         3175  +  }
  3163   3176     return result;
  3164   3177   }
  3165   3178   
  3166   3179   /* Generate the "*.out" log file */
  3167   3180   void ReportOutput(struct lemon *lemp)
  3168   3181   {
  3169   3182     int i;
................................................................................
  3523   3536       }
  3524   3537     }
  3525   3538     z[used] = 0;
  3526   3539     return z;
  3527   3540   }
  3528   3541   
  3529   3542   /*
  3530         -** zCode is a string that is the action associated with a rule.  Expand
  3531         -** the symbols in this string so that the refer to elements of the parser
  3532         -** stack.
         3543  +** Write and transform the rp->code string so that symbols are expanded.
         3544  +** Populate the rp->codePrefix and rp->codeSuffix strings, as appropriate.
  3533   3545   **
  3534   3546   ** Return 1 if the expanded code requires that "yylhsminor" local variable
  3535   3547   ** to be defined.
  3536   3548   */
  3537   3549   PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
  3538   3550     char *cp, *xp;
  3539   3551     int i;
................................................................................
  3549   3561     for(i=0; i<rp->nrhs; i++) used[i] = 0;
  3550   3562     lhsused = 0;
  3551   3563   
  3552   3564     if( rp->code==0 ){
  3553   3565       static char newlinestr[2] = { '\n', '\0' };
  3554   3566       rp->code = newlinestr;
  3555   3567       rp->line = rp->ruleline;
         3568  +    rp->noCode = 1;
         3569  +  }else{
         3570  +    rp->noCode = 0;
  3556   3571     }
  3557   3572   
  3558   3573   
  3559   3574     if( rp->nrhs==0 ){
  3560   3575       /* If there are no RHS symbols, then writing directly to the LHS is ok */
  3561   3576       lhsdirect = 1;
  3562   3577     }else if( rp->rhsalias[0]==0 ){
................................................................................
  3564   3579       ** we have to call the distructor on the RHS symbol first. */
  3565   3580       lhsdirect = 1;
  3566   3581       if( has_destructor(rp->rhs[0],lemp) ){
  3567   3582         append_str(0,0,0,0);
  3568   3583         append_str("  yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
  3569   3584                    rp->rhs[0]->index,1-rp->nrhs);
  3570   3585         rp->codePrefix = Strsafe(append_str(0,0,0,0));
         3586  +      rp->noCode = 0;
  3571   3587       }
  3572   3588     }else if( rp->lhsalias==0 ){
  3573   3589       /* There is no LHS value symbol. */
  3574   3590       lhsdirect = 1;
  3575   3591     }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
  3576   3592       /* The LHS symbol and the left-most RHS symbol are the same, so 
  3577   3593       ** direct writing is allowed */
................................................................................
  3711   3727       append_str("  yymsp[%d].minor.yy%d = ", 0, 1-rp->nrhs, rp->lhs->dtnum);
  3712   3728       append_str(zLhs, 0, 0, 0);
  3713   3729       append_str(";\n", 0, 0, 0);
  3714   3730     }
  3715   3731   
  3716   3732     /* Suffix code generation complete */
  3717   3733     cp = append_str(0,0,0,0);
  3718         -  if( cp && cp[0] ) rp->codeSuffix = Strsafe(cp);
         3734  +  if( cp && cp[0] ){
         3735  +    rp->codeSuffix = Strsafe(cp);
         3736  +    rp->noCode = 0;
         3737  +  }
  3719   3738   
  3720   3739     return rc;
  3721   3740   }
  3722   3741   
  3723   3742   /* 
  3724   3743   ** Generate code which executes when the rule "rp" is reduced.  Write
  3725   3744   ** the code to "out".  Make sure lineno stays up-to-date.
................................................................................
  4129   4148         printf("%4d: State %3d %s n: %2d size: %5d freespace: %d\n",
  4130   4149                i, stp->statenum, ax[i].isTkn ? "Token" : "Var  ",
  4131   4150                ax[i].nAction, pActtab->nAction, nn);
  4132   4151       }
  4133   4152   #endif
  4134   4153     }
  4135   4154     free(ax);
         4155  +
         4156  +  /* Mark rules that are actually used for reduce actions after all
         4157  +  ** optimizations have been applied
         4158  +  */
         4159  +  for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE;
         4160  +  for(i=0; i<lemp->nxstate; i++){
         4161  +    struct action *ap;
         4162  +    for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
         4163  +      if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){
         4164  +        ap->x.rp->doesReduce = i;
         4165  +      }
         4166  +    }
         4167  +  }
  4136   4168   
  4137   4169     /* Finish rendering the constants now that the action table has
  4138   4170     ** been computed */
  4139   4171     fprintf(out,"#define YYNSTATE             %d\n",lemp->nxstate);  lineno++;
  4140   4172     fprintf(out,"#define YYNRULE              %d\n",lemp->nrule);  lineno++;
  4141   4173     fprintf(out,"#define YY_MAX_SHIFT         %d\n",lemp->nxstate-1); lineno++;
  4142   4174     fprintf(out,"#define YY_MIN_SHIFTREDUCE   %d\n",lemp->nstate); lineno++;
................................................................................
  4392   4424     }
  4393   4425     if( i ){
  4394   4426       fprintf(out,"        YYMINORTYPE yylhsminor;\n"); lineno++;
  4395   4427     }
  4396   4428     /* First output rules other than the default: rule */
  4397   4429     for(rp=lemp->rule; rp; rp=rp->next){
  4398   4430       struct rule *rp2;               /* Other rules with the same action */
  4399         -    if( rp->code==0 ) continue;
  4400         -    if( rp->code[0]=='\n'
  4401         -     && rp->code[1]==0
  4402         -     && rp->codePrefix==0
  4403         -     && rp->codeSuffix==0
  4404         -    ){
  4405         -      /* No actions, so this will be part of the "default:" rule */
         4431  +    if( rp->codeEmitted ) continue;
         4432  +    if( rp->noCode ){
         4433  +      /* No C code actions, so this will be part of the "default:" rule */
  4406   4434         continue;
  4407   4435       }
  4408   4436       fprintf(out,"      case %d: /* ", rp->iRule);
  4409   4437       writeRuleText(out, rp);
  4410   4438       fprintf(out, " */\n"); lineno++;
  4411   4439       for(rp2=rp->next; rp2; rp2=rp2->next){
  4412   4440         if( rp2->code==rp->code && rp2->codePrefix==rp->codePrefix
  4413   4441                && rp2->codeSuffix==rp->codeSuffix ){
  4414   4442           fprintf(out,"      case %d: /* ", rp2->iRule);
  4415   4443           writeRuleText(out, rp2);
  4416   4444           fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++;
  4417         -        rp2->code = 0;
         4445  +        rp2->codeEmitted = 1;
  4418   4446         }
  4419   4447       }
  4420   4448       emit_code(out,rp,lemp,&lineno);
  4421   4449       fprintf(out,"        break;\n"); lineno++;
  4422         -    rp->code = 0;
         4450  +    rp->codeEmitted = 1;
  4423   4451     }
  4424   4452     /* Finally, output the default: rule.  We choose as the default: all
  4425   4453     ** empty actions. */
  4426   4454     fprintf(out,"      default:\n"); lineno++;
  4427   4455     for(rp=lemp->rule; rp; rp=rp->next){
  4428         -    if( rp->code==0 ) continue;
  4429         -    assert( rp->code[0]=='\n' && rp->code[1]==0 );
  4430         -    assert( rp->codePrefix==0 );
  4431         -    assert( rp->codeSuffix==0 );
         4456  +    if( rp->codeEmitted ) continue;
         4457  +    assert( rp->noCode );
  4432   4458       fprintf(out,"      /* (%d) ", rp->iRule);
  4433   4459       writeRuleText(out, rp);
  4434         -    fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++;
         4460  +    if( rp->doesReduce ){
         4461  +      fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++;
         4462  +    }else{
         4463  +      fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n",
         4464  +              rp->iRule); lineno++;
         4465  +    }
  4435   4466     }
  4436   4467     fprintf(out,"        break;\n"); lineno++;
  4437   4468     tplt_xfer(lemp->name,in,out,&lineno);
  4438   4469   
  4439   4470     /* Generate code which executes if a parse fails */
  4440   4471     tplt_print(out,lemp,lemp->failure,&lineno);
  4441   4472     tplt_xfer(lemp->name,in,out,&lineno);
................................................................................
  4498   4529   ** In this version, we take the most frequent REDUCE action and make
  4499   4530   ** it the default.  Except, there is no default if the wildcard token
  4500   4531   ** is a possible look-ahead.
  4501   4532   */
  4502   4533   void CompressTables(struct lemon *lemp)
  4503   4534   {
  4504   4535     struct state *stp;
  4505         -  struct action *ap, *ap2;
         4536  +  struct action *ap, *ap2, *nextap;
  4506   4537     struct rule *rp, *rp2, *rbest;
  4507   4538     int nbest, n;
  4508   4539     int i;
  4509   4540     int usesWildcard;
  4510   4541   
  4511   4542     for(i=0; i<lemp->nstate; i++){
  4512   4543       stp = lemp->sorted[i];
................................................................................
  4575   4606         pNextState = ap->x.stp;
  4576   4607         if( pNextState->autoReduce && pNextState->pDfltReduce!=0 ){
  4577   4608           ap->type = SHIFTREDUCE;
  4578   4609           ap->x.rp = pNextState->pDfltReduce;
  4579   4610         }
  4580   4611       }
  4581   4612     }
         4613  +
         4614  +  /* If a SHIFTREDUCE action specifies a rule that has a single RHS term
         4615  +  ** (meaning that the SHIFTREDUCE will land back in the state where it
         4616  +  ** started) and if there is no C-code associated with the reduce action,
         4617  +  ** then we can go ahead and convert the action to be the same as the
         4618  +  ** action for the RHS of the rule.
         4619  +  */
         4620  +  for(i=0; i<lemp->nstate; i++){
         4621  +    stp = lemp->sorted[i];
         4622  +    for(ap=stp->ap; ap; ap=nextap){
         4623  +      nextap = ap->next;
         4624  +      if( ap->type!=SHIFTREDUCE ) continue;
         4625  +      rp = ap->x.rp;
         4626  +      if( rp->noCode==0 ) continue;
         4627  +      if( rp->nrhs!=1 ) continue;
         4628  +#if 1
         4629  +      /* Only apply this optimization to non-terminals.  It would be OK to
         4630  +      ** apply it to terminal symbols too, but that makes the parser tables
         4631  +      ** larger. */
         4632  +      if( ap->sp->index<lemp->nterminal ) continue;
         4633  +#endif
         4634  +      /* If we reach this point, it means the optimization can be applied */
         4635  +      nextap = ap;
         4636  +      for(ap2=stp->ap; ap2 && (ap2==ap || ap2->sp!=rp->lhs); ap2=ap2->next){}
         4637  +      assert( ap2!=0 );
         4638  +      ap->spOpt = ap2->sp;
         4639  +      ap->type = ap2->type;
         4640  +      ap->x = ap2->x;
         4641  +    }
         4642  +  }
  4582   4643   }
  4583   4644   
  4584   4645   
  4585   4646   /*
  4586   4647   ** Compare two states for sorting purposes.  The smaller state is the
  4587   4648   ** one with the most non-terminal actions.  If they have the same number
  4588   4649   ** of non-terminal actions, then the smaller is the one with the most

Changes to tool/lempar.c.

   199    199                            ** is the value of the token  */
   200    200   };
   201    201   typedef struct yyStackEntry yyStackEntry;
   202    202   
   203    203   /* The state of the parser is completely contained in an instance of
   204    204   ** the following structure */
   205    205   struct yyParser {
   206         -  int yyidx;                    /* Index of top element in stack */
          206  +  yyStackEntry *yytos;          /* Pointer to top element of the stack */
   207    207   #ifdef YYTRACKMAXSTACKDEPTH
   208         -  int yyidxMax;                 /* Maximum value of yyidx */
          208  +  int yyhwm;                    /* High-water mark of the stack */
   209    209   #endif
   210    210   #ifndef YYNOERRORRECOVERY
   211    211     int yyerrcnt;                 /* Shifts left before out of the error */
   212    212   #endif
   213    213     ParseARG_SDECL                /* A place to hold %extra_argument */
   214    214   #if YYSTACKDEPTH<=0
   215    215     int yystksz;                  /* Current side of the stack */
   216    216     yyStackEntry *yystack;        /* The parser's stack */
          217  +  yyStackEntry yystk0;          /* First stack entry */
   217    218   #else
   218    219     yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
   219    220   #endif
   220    221   };
   221    222   typedef struct yyParser yyParser;
   222    223   
   223    224   #ifndef NDEBUG
................................................................................
   267    268   %%
   268    269   };
   269    270   #endif /* NDEBUG */
   270    271   
   271    272   
   272    273   #if YYSTACKDEPTH<=0
   273    274   /*
   274         -** Try to increase the size of the parser stack.
          275  +** Try to increase the size of the parser stack.  Return the number
          276  +** of errors.  Return 0 on success.
   275    277   */
   276         -static void yyGrowStack(yyParser *p){
          278  +static int yyGrowStack(yyParser *p){
   277    279     int newSize;
          280  +  int idx;
   278    281     yyStackEntry *pNew;
   279    282   
   280    283     newSize = p->yystksz*2 + 100;
   281         -  pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
          284  +  idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
          285  +  if( p->yystack==&p->yystk0 ){
          286  +    pNew = malloc(newSize*sizeof(pNew[0]));
          287  +    if( pNew ) pNew[0] = p->yystk0;
          288  +  }else{
          289  +    pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
          290  +  }
   282    291     if( pNew ){
   283    292       p->yystack = pNew;
          293  +    p->yytos = &p->yystack[idx];
          294  +#ifndef NDEBUG
          295  +    if( yyTraceFILE ){
          296  +      fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
          297  +              yyTracePrompt, p->yystksz, newSize);
          298  +    }
          299  +#endif
   284    300       p->yystksz = newSize;
   285         -#ifndef NDEBUG
   286         -    if( yyTraceFILE ){
   287         -      fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
   288         -              yyTracePrompt, p->yystksz);
   289         -    }
   290         -#endif
   291    301     }
          302  +  return pNew==0; 
   292    303   }
   293    304   #endif
   294    305   
   295    306   /* Datatype of the argument to the memory allocated passed as the
   296    307   ** second argument to ParseAlloc() below.  This can be changed by
   297    308   ** putting an appropriate #define in the %include section of the input
   298    309   ** grammar.
................................................................................
   313    324   ** A pointer to a parser.  This pointer is used in subsequent calls
   314    325   ** to Parse and ParseFree.
   315    326   */
   316    327   void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
   317    328     yyParser *pParser;
   318    329     pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
   319    330     if( pParser ){
   320         -    pParser->yyidx = -1;
   321    331   #ifdef YYTRACKMAXSTACKDEPTH
   322         -    pParser->yyidxMax = 0;
          332  +    pParser->yyhwm = 0;
   323    333   #endif
   324    334   #if YYSTACKDEPTH<=0
          335  +    pParser->yytos = NULL;
   325    336       pParser->yystack = NULL;
   326    337       pParser->yystksz = 0;
   327         -    yyGrowStack(pParser);
          338  +    if( yyGrowStack(pParser) ){
          339  +      pParser->yystack = &pParser->yystk0;
          340  +      pParser->yystksz = 1;
          341  +    }
   328    342   #endif
          343  +#ifndef YYNOERRORRECOVERY
          344  +    pParser->yyerrcnt = -1;
          345  +#endif
          346  +    pParser->yytos = pParser->yystack;
          347  +    pParser->yystack[0].stateno = 0;
          348  +    pParser->yystack[0].major = 0;
   329    349     }
   330    350     return pParser;
   331    351   }
   332    352   
   333    353   /* The following function deletes the "minor type" or semantic value
   334    354   ** associated with a symbol.  The symbol can be either a terminal
   335    355   ** or nonterminal. "yymajor" is the symbol code, and "yypminor" is
................................................................................
   365    385   ** Pop the parser's stack once.
   366    386   **
   367    387   ** If there is a destructor routine associated with the token which
   368    388   ** is popped from the stack, then call it.
   369    389   */
   370    390   static void yy_pop_parser_stack(yyParser *pParser){
   371    391     yyStackEntry *yytos;
   372         -  assert( pParser->yyidx>=0 );
   373         -  yytos = &pParser->yystack[pParser->yyidx--];
          392  +  assert( pParser->yytos!=0 );
          393  +  yytos = pParser->yytos--;
   374    394   #ifndef NDEBUG
   375    395     if( yyTraceFILE ){
   376    396       fprintf(yyTraceFILE,"%sPopping %s\n",
   377    397         yyTracePrompt,
   378    398         yyTokenName[yytos->major]);
   379    399     }
   380    400   #endif
................................................................................
   393    413     void *p,                    /* The parser to be deleted */
   394    414     void (*freeProc)(void*)     /* Function used to reclaim memory */
   395    415   ){
   396    416     yyParser *pParser = (yyParser*)p;
   397    417   #ifndef YYPARSEFREENEVERNULL
   398    418     if( pParser==0 ) return;
   399    419   #endif
   400         -  while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
          420  +  while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
   401    421   #if YYSTACKDEPTH<=0
   402         -  free(pParser->yystack);
          422  +  if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
   403    423   #endif
   404    424     (*freeProc)((void*)pParser);
   405    425   }
   406    426   
   407    427   /*
   408    428   ** Return the peak depth of the stack for a parser.
   409    429   */
   410    430   #ifdef YYTRACKMAXSTACKDEPTH
   411    431   int ParseStackPeak(void *p){
   412    432     yyParser *pParser = (yyParser*)p;
   413         -  return pParser->yyidxMax;
          433  +  return pParser->yyhwm;
   414    434   }
   415    435   #endif
   416    436   
   417    437   /*
   418    438   ** Find the appropriate action for a parser given the terminal
   419    439   ** look-ahead token iLookAhead.
   420    440   */
   421    441   static unsigned int yy_find_shift_action(
   422    442     yyParser *pParser,        /* The parser */
   423    443     YYCODETYPE iLookAhead     /* The look-ahead token */
   424    444   ){
   425    445     int i;
   426         -  int stateno = pParser->yystack[pParser->yyidx].stateno;
          446  +  int stateno = pParser->yytos->stateno;
   427    447    
   428    448     if( stateno>=YY_MIN_REDUCE ) return stateno;
   429    449     assert( stateno <= YY_SHIFT_COUNT );
   430    450     do{
   431    451       i = yy_shift_ofst[stateno];
   432    452       if( i==YY_SHIFT_USE_DFLT ) return yy_default[stateno];
   433    453       assert( iLookAhead!=YYNOCODE );
................................................................................
   512    532   }
   513    533   
   514    534   /*
   515    535   ** The following routine is called if the stack overflows.
   516    536   */
   517    537   static void yyStackOverflow(yyParser *yypParser){
   518    538      ParseARG_FETCH;
   519         -   yypParser->yyidx--;
          539  +   yypParser->yytos--;
   520    540   #ifndef NDEBUG
   521    541      if( yyTraceFILE ){
   522    542        fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
   523    543      }
   524    544   #endif
   525         -   while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
          545  +   while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
   526    546      /* Here code is inserted which will execute if the parser
   527    547      ** stack every overflows */
   528    548   /******** Begin %stack_overflow code ******************************************/
   529    549   %%
   530    550   /******** End %stack_overflow code ********************************************/
   531    551      ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
   532    552   }
................................................................................
   535    555   ** Print tracing information for a SHIFT action
   536    556   */
   537    557   #ifndef NDEBUG
   538    558   static void yyTraceShift(yyParser *yypParser, int yyNewState){
   539    559     if( yyTraceFILE ){
   540    560       if( yyNewState<YYNSTATE ){
   541    561         fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
   542         -         yyTracePrompt,yyTokenName[yypParser->yystack[yypParser->yyidx].major],
          562  +         yyTracePrompt,yyTokenName[yypParser->yytos->major],
   543    563            yyNewState);
   544    564       }else{
   545    565         fprintf(yyTraceFILE,"%sShift '%s'\n",
   546         -         yyTracePrompt,yyTokenName[yypParser->yystack[yypParser->yyidx].major]);
          566  +         yyTracePrompt,yyTokenName[yypParser->yytos->major]);
   547    567       }
   548    568     }
   549    569   }
   550    570   #else
   551    571   # define yyTraceShift(X,Y)
   552    572   #endif
   553    573   
................................................................................
   557    577   static void yy_shift(
   558    578     yyParser *yypParser,          /* The parser to be shifted */
   559    579     int yyNewState,               /* The new state to shift in */
   560    580     int yyMajor,                  /* The major token to shift in */
   561    581     ParseTOKENTYPE yyMinor        /* The minor token to shift in */
   562    582   ){
   563    583     yyStackEntry *yytos;
   564         -  yypParser->yyidx++;
          584  +  yypParser->yytos++;
   565    585   #ifdef YYTRACKMAXSTACKDEPTH
   566         -  if( yypParser->yyidx>yypParser->yyidxMax ){
   567         -    yypParser->yyidxMax = yypParser->yyidx;
          586  +  if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
          587  +    yypParser->yyhwm++;
          588  +    assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
   568    589     }
   569    590   #endif
   570    591   #if YYSTACKDEPTH>0 
   571         -  if( yypParser->yyidx>=YYSTACKDEPTH ){
          592  +  if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){
   572    593       yyStackOverflow(yypParser);
   573    594       return;
   574    595     }
   575    596   #else
   576         -  if( yypParser->yyidx>=yypParser->yystksz ){
   577         -    yyGrowStack(yypParser);
   578         -    if( yypParser->yyidx>=yypParser->yystksz ){
          597  +  if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
          598  +    if( yyGrowStack(yypParser) ){
   579    599         yyStackOverflow(yypParser);
   580    600         return;
   581    601       }
   582    602     }
   583    603   #endif
   584         -  yytos = &yypParser->yystack[yypParser->yyidx];
          604  +  if( yyNewState > YY_MAX_SHIFT ){
          605  +    yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
          606  +  }
          607  +  yytos = yypParser->yytos;
   585    608     yytos->stateno = (YYACTIONTYPE)yyNewState;
   586    609     yytos->major = (YYCODETYPE)yyMajor;
   587    610     yytos->minor.yy0 = yyMinor;
   588    611     yyTraceShift(yypParser, yyNewState);
   589    612   }
   590    613   
   591    614   /* The following table contains information about every rule that
................................................................................
   609    632     unsigned int yyruleno        /* Number of the rule by which to reduce */
   610    633   ){
   611    634     int yygoto;                     /* The next state */
   612    635     int yyact;                      /* The next action */
   613    636     yyStackEntry *yymsp;            /* The top of the parser's stack */
   614    637     int yysize;                     /* Amount to pop the stack */
   615    638     ParseARG_FETCH;
   616         -  yymsp = &yypParser->yystack[yypParser->yyidx];
          639  +  yymsp = yypParser->yytos;
   617    640   #ifndef NDEBUG
   618    641     if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
   619    642       yysize = yyRuleInfo[yyruleno].nrhs;
   620    643       fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
   621    644         yyRuleName[yyruleno], yymsp[-yysize].stateno);
   622    645     }
   623    646   #endif /* NDEBUG */
   624    647   
   625    648     /* Check that the stack is large enough to grow by a single entry
   626    649     ** if the RHS of the rule is empty.  This ensures that there is room
   627    650     ** enough on the stack to push the LHS value */
   628    651     if( yyRuleInfo[yyruleno].nrhs==0 ){
   629    652   #ifdef YYTRACKMAXSTACKDEPTH
   630         -    if( yypParser->yyidx>yypParser->yyidxMax ){
   631         -      yypParser->yyidxMax = yypParser->yyidx;
          653  +    if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
          654  +      yypParser->yyhwm++;
          655  +      assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack));
   632    656       }
   633    657   #endif
   634    658   #if YYSTACKDEPTH>0 
   635         -    if( yypParser->yyidx>=YYSTACKDEPTH-1 ){
          659  +    if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH-1] ){
   636    660         yyStackOverflow(yypParser);
   637    661         return;
   638    662       }
   639    663   #else
   640         -    if( yypParser->yyidx>=yypParser->yystksz-1 ){
   641         -      yyGrowStack(yypParser);
   642         -      if( yypParser->yyidx>=yypParser->yystksz-1 ){
          664  +    if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
          665  +      if( yyGrowStack(yypParser) ){
   643    666           yyStackOverflow(yypParser);
   644    667           return;
   645    668         }
          669  +      yymsp = yypParser->yytos;
   646    670       }
   647    671   #endif
   648    672     }
   649    673   
   650    674     switch( yyruleno ){
   651    675     /* Beginning here are the reduction cases.  A typical example
   652    676     ** follows:
................................................................................
   661    685   /********** End reduce actions ************************************************/
   662    686     };
   663    687     assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
   664    688     yygoto = yyRuleInfo[yyruleno].lhs;
   665    689     yysize = yyRuleInfo[yyruleno].nrhs;
   666    690     yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
   667    691     if( yyact <= YY_MAX_SHIFTREDUCE ){
   668         -    if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
   669         -    yypParser->yyidx -= yysize - 1;
          692  +    if( yyact>YY_MAX_SHIFT ){
          693  +      yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
          694  +    }
   670    695       yymsp -= yysize-1;
          696  +    yypParser->yytos = yymsp;
   671    697       yymsp->stateno = (YYACTIONTYPE)yyact;
   672    698       yymsp->major = (YYCODETYPE)yygoto;
   673    699       yyTraceShift(yypParser, yyact);
   674    700     }else{
   675    701       assert( yyact == YY_ACCEPT_ACTION );
   676         -    yypParser->yyidx -= yysize;
          702  +    yypParser->yytos -= yysize;
   677    703       yy_accept(yypParser);
   678    704     }
   679    705   }
   680    706   
   681    707   /*
   682    708   ** The following code executes when the parse fails
   683    709   */
................................................................................
   687    713   ){
   688    714     ParseARG_FETCH;
   689    715   #ifndef NDEBUG
   690    716     if( yyTraceFILE ){
   691    717       fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
   692    718     }
   693    719   #endif
   694         -  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
          720  +  while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
   695    721     /* Here code is inserted which will be executed whenever the
   696    722     ** parser fails */
   697    723   /************ Begin %parse_failure code ***************************************/
   698    724   %%
   699    725   /************ End %parse_failure code *****************************************/
   700    726     ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
   701    727   }
................................................................................
   725    751   ){
   726    752     ParseARG_FETCH;
   727    753   #ifndef NDEBUG
   728    754     if( yyTraceFILE ){
   729    755       fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
   730    756     }
   731    757   #endif
   732         -  while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
          758  +  assert( yypParser->yytos==yypParser->yystack );
   733    759     /* Here code is inserted which will be executed whenever the
   734    760     ** parser accepts */
   735    761   /*********** Begin %parse_accept code *****************************************/
   736    762   %%
   737    763   /*********** End %parse_accept code *******************************************/
   738    764     ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
   739    765   }
................................................................................
   771    797   #ifdef YYERRORSYMBOL
   772    798     int yyerrorhit = 0;   /* True if yymajor has invoked an error */
   773    799   #endif
   774    800     yyParser *yypParser;  /* The parser */
   775    801   
   776    802     /* (re)initialize the parser, if necessary */
   777    803     yypParser = (yyParser*)yyp;
   778         -  if( yypParser->yyidx<0 ){
   779         -#if YYSTACKDEPTH<=0
   780         -    if( yypParser->yystksz <=0 ){
   781         -      yyStackOverflow(yypParser);
   782         -      return;
   783         -    }
   784         -#endif
   785         -    yypParser->yyidx = 0;
   786         -#ifndef YYNOERRORRECOVERY
   787         -    yypParser->yyerrcnt = -1;
   788         -#endif
   789         -    yypParser->yystack[0].stateno = 0;
   790         -    yypParser->yystack[0].major = 0;
   791         -#ifndef NDEBUG
   792         -    if( yyTraceFILE ){
   793         -      fprintf(yyTraceFILE,"%sInitialize. Empty stack. State 0\n",
   794         -              yyTracePrompt);
   795         -    }
   796         -#endif
   797         -  }
          804  +  assert( yypParser->yytos!=0 );
   798    805   #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
   799    806     yyendofinput = (yymajor==0);
   800    807   #endif
   801    808     ParseARG_STORE;
   802    809   
   803    810   #ifndef NDEBUG
   804    811     if( yyTraceFILE ){
................................................................................
   805    812       fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
   806    813     }
   807    814   #endif
   808    815   
   809    816     do{
   810    817       yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
   811    818       if( yyact <= YY_MAX_SHIFTREDUCE ){
   812         -      if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
   813    819         yy_shift(yypParser,yyact,yymajor,yyminor);
   814    820   #ifndef YYNOERRORRECOVERY
   815    821         yypParser->yyerrcnt--;
   816    822   #endif
   817    823         yymajor = YYNOCODE;
   818    824       }else if( yyact <= YY_MAX_REDUCE ){
   819    825         yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
................................................................................
   847    853         **    processing will occur until three tokens have been
   848    854         **    shifted successfully.
   849    855         **
   850    856         */
   851    857         if( yypParser->yyerrcnt<0 ){
   852    858           yy_syntax_error(yypParser,yymajor,yyminor);
   853    859         }
   854         -      yymx = yypParser->yystack[yypParser->yyidx].major;
          860  +      yymx = yypParser->yytos->major;
   855    861         if( yymx==YYERRORSYMBOL || yyerrorhit ){
   856    862   #ifndef NDEBUG
   857    863           if( yyTraceFILE ){
   858    864             fprintf(yyTraceFILE,"%sDiscard input token %s\n",
   859    865                yyTracePrompt,yyTokenName[yymajor]);
   860    866           }
   861    867   #endif
   862    868           yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
   863    869           yymajor = YYNOCODE;
   864    870         }else{
   865         -        while(
   866         -          yypParser->yyidx >= 0 &&
   867         -          yymx != YYERRORSYMBOL &&
   868         -          (yyact = yy_find_reduce_action(
   869         -                        yypParser->yystack[yypParser->yyidx].stateno,
          871  +        while( yypParser->yytos >= &yypParser->yystack
          872  +            && yymx != YYERRORSYMBOL
          873  +            && (yyact = yy_find_reduce_action(
          874  +                        yypParser->yytos->stateno,
   870    875                           YYERRORSYMBOL)) >= YY_MIN_REDUCE
   871    876           ){
   872    877             yy_pop_parser_stack(yypParser);
   873    878           }
   874         -        if( yypParser->yyidx < 0 || yymajor==0 ){
          879  +        if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
   875    880             yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
   876    881             yy_parse_failed(yypParser);
   877    882             yymajor = YYNOCODE;
   878    883           }else if( yymx!=YYERRORSYMBOL ){
   879    884             yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
   880    885           }
   881    886         }
................................................................................
   910    915         yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
   911    916         if( yyendofinput ){
   912    917           yy_parse_failed(yypParser);
   913    918         }
   914    919         yymajor = YYNOCODE;
   915    920   #endif
   916    921       }
   917         -  }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
          922  +  }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack );
   918    923   #ifndef NDEBUG
   919    924     if( yyTraceFILE ){
   920         -    int i;
          925  +    yyStackEntry *i;
          926  +    char cDiv = '[';
   921    927       fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
   922         -    for(i=1; i<=yypParser->yyidx; i++)
   923         -      fprintf(yyTraceFILE,"%c%s", i==1 ? '[' : ' ', 
   924         -              yyTokenName[yypParser->yystack[i].major]);
          928  +    for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){
          929  +      fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]);
          930  +      cDiv = ' ';
          931  +    }
   925    932       fprintf(yyTraceFILE,"]\n");
   926    933     }
   927    934   #endif
   928    935     return;
   929    936   }

Added tool/libvers.c.

            1  +/*
            2  +** Compile this program against an SQLite library of unknown version
            3  +** and then run this program, and it will print out the SQLite version
            4  +** information.
            5  +*/
            6  +#include <stdio.h>
            7  +
            8  +extern const char *sqlite3_libversion(void);
            9  +extern const char *sqlite3_sourceid(void);
           10  +
           11  +int main(int argc, char **argv){
           12  +  printf("SQLite version %s\n", sqlite3_libversion());
           13  +  printf("SQLite source  %s\n", sqlite3_sourceid());
           14  +  return 0;
           15  +}