/ Check-in [be0df0a6]
Login

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

Overview
Comment:Merge latest trunk changes with this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | server-process-edition
Files: files | file ages | folders
SHA3-256: be0df0a65fc781fde6e94c9370b4819c703d3b270c707dd59e587a2a6f36c9f4
User & Date: dan 2017-07-19 18:54:21
Context
2017-07-24
19:23
Only open a db in server-mode if there is a directory named "db-journal" in the file-system and the VFS is an exclusive locking VFS. check-in: e77d29f6 user: dan tags: server-process-edition
2017-07-19
18:54
Merge latest trunk changes with this branch. check-in: be0df0a6 user: dan tags: server-process-edition
18:01
Remove some 'breakpoint' commands in test files. check-in: d14fc621 user: mistachkin tags: trunk
2017-07-14
08:15
Add simple tests for "PRAGMA freelist_format". check-in: 98a36f4c user: dan tags: server-process-edition
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   431    431     $(TOP)/ext/misc/nextchar.c \
   432    432     $(TOP)/ext/misc/percentile.c \
   433    433     $(TOP)/ext/misc/regexp.c \
   434    434     $(TOP)/ext/misc/remember.c \
   435    435     $(TOP)/ext/misc/series.c \
   436    436     $(TOP)/ext/misc/spellfix.c \
   437    437     $(TOP)/ext/misc/totype.c \
          438  +  $(TOP)/ext/misc/unionvtab.c \
   438    439     $(TOP)/ext/misc/wholenumber.c
   439    440   
   440    441   # Source code to the library files needed by the test fixture
   441    442   #
   442    443   TESTSRC2 = \
   443    444     $(TOP)/src/attach.c \
   444    445     $(TOP)/src/backup.c \
................................................................................
   480    481     $(TOP)/ext/fts3/fts3.c \
   481    482     $(TOP)/ext/fts3/fts3_aux.c \
   482    483     $(TOP)/ext/fts3/fts3_expr.c \
   483    484     $(TOP)/ext/fts3/fts3_term.c \
   484    485     $(TOP)/ext/fts3/fts3_tokenizer.c \
   485    486     $(TOP)/ext/fts3/fts3_write.c \
   486    487     $(TOP)/ext/async/sqlite3async.c \
   487         -  $(TOP)/ext/session/sqlite3session.c 
          488  +  $(TOP)/ext/session/sqlite3session.c \
          489  +  $(TOP)/ext/misc/stmt.c 
   488    490   
   489    491   # Header files used by all library source files.
   490    492   #
   491    493   HDR = \
   492    494      $(TOP)/src/btree.h \
   493    495      $(TOP)/src/btreeInt.h \
   494    496      $(TOP)/src/hash.h \

Changes to Makefile.msc.

  1414   1414     $(TOP)\ext\misc\nextchar.c \
  1415   1415     $(TOP)\ext\misc\percentile.c \
  1416   1416     $(TOP)\ext\misc\regexp.c \
  1417   1417     $(TOP)\ext\misc\remember.c \
  1418   1418     $(TOP)\ext\misc\series.c \
  1419   1419     $(TOP)\ext\misc\spellfix.c \
  1420   1420     $(TOP)\ext\misc\totype.c \
         1421  +  $(TOP)\ext\misc\unionvtab.c \
  1421   1422     $(TOP)\ext\misc\wholenumber.c
  1422   1423   
  1423   1424   # Source code to the library files needed by the test fixture
  1424   1425   # (non-amalgamation)
  1425   1426   #
  1426   1427   TESTSRC2 = \
  1427   1428     $(SRC00) \
................................................................................
  2262   2263   	del /Q mkkeywordhash.* keywordhash.h 2>NUL
  2263   2264   	del /Q notasharedlib.* 2>NUL
  2264   2265   	-rmdir /Q/S .deps 2>NUL
  2265   2266   	-rmdir /Q/S .libs 2>NUL
  2266   2267   	-rmdir /Q/S tsrc 2>NUL
  2267   2268   	del /Q .target_source 2>NUL
  2268   2269   	del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL
         2270  +	del /Q lsm.dll lsmtest.exe 2>NUL
  2269   2271   	del /Q testloadext.dll 2>NUL
  2270   2272   	del /Q testfixture.exe test.db 2>NUL
  2271   2273   	del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
  2272   2274   	del /Q changeset.exe 2>NUL
  2273   2275   	del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
  2274   2276   	del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
  2275   2277   	del /Q sqlite3.c sqlite3-*.c 2>NUL

Changes to README.md.

    30     30        to locate the check-in desired, click on its information page link,
    31     31        then click on the "Tarball" or "ZIP Archive" links on the information
    32     32        page.
    33     33   
    34     34   If you do want to use Fossil to check out the source tree, 
    35     35   first install Fossil version 2.0 or later.
    36     36   (Source tarballs and precompiled binaries available
    37         -[here](https://www.fossil-scm.org/fossil/uv/download.html).)
           37  +[here](https://www.fossil-scm.org/fossil/uv/download.html).  Fossil is
           38  +a stand-alone program.  To install, simply download or build the single 
           39  +executable file and put that file someplace on your $PATH.)
    38     40   Then run commands like this:
    39     41   
    40     42           mkdir ~/sqlite
    41     43           cd ~/sqlite
    42     44           fossil clone https://www.sqlite.org/src sqlite.fossil
    43     45           fossil open sqlite.fossil
    44     46       
................................................................................
   102    104   SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation
   103    105   is required by the makefiles (including those for MSVC).  SQLite contains
   104    106   a lot of generated code and Tcl is used to do much of that code generation.
   105    107   The makefiles also require AWK.
   106    108   
   107    109   ## Source Code Tour
   108    110   
   109         -Most of the core source files are in the **src/** subdirectory.  But
   110         -src/ also contains files used to build the "testfixture" test harness;
   111         -those file all begin with "test".  And src/ contains the "shell.c" file
   112         -which is the main program for the "sqlite3.exe" command-line shell and
   113         -the "tclsqlite.c" file which implements the bindings to SQLite from the
   114         -Tcl programming language.  (Historical note:  SQLite began as a Tcl
          111  +Most of the core source files are in the **src/** subdirectory.  The
          112  +**src/** folder also contains files used to build the "testfixture" test
          113  +harness. The names of the source files used by "testfixture" all begin
          114  +with "test".
          115  +The **src/** also contains the "shell.c" file
          116  +which is the main program for the "sqlite3.exe"
          117  +[command-line shell](https://sqlite.org/cli.html) and
          118  +the "tclsqlite.c" file which implements the
          119  +[TCL bindings](https://sqlite.org/tclsqlite.html) for SQLite.
          120  +(Historical note:  SQLite began as a Tcl
   115    121   extension and only later escaped to the wild as an independent library.)
   116    122   
   117    123   Test scripts and programs are found in the **test/** subdirectory.
   118         -There are other test suites for SQLite (see
   119         -[How SQLite Is Tested](http://www.sqlite.org/testing.html))
   120         -but those other test suites are
   121         -in separate source repositories.
          124  +Addtional test code is found in other source repositories.
          125  +See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for
          126  +additional information.
   122    127   
   123    128   The **ext/** subdirectory contains code for extensions.  The
   124    129   Full-text search engine is in **ext/fts3**.  The R-Tree engine is in
   125    130   **ext/rtree**.  The **ext/misc** subdirectory contains a number of
   126    131   smaller, single-file extensions, such as a REGEXP operator.
   127    132   
   128    133   The **tool/** subdirectory contains various scripts and programs used
................................................................................
   138    143   The "target_source" make target will create a subdirectory "tsrc/" and
   139    144   fill it with all the source files needed to build SQLite, both
   140    145   manually-edited files and automatically-generated files.
   141    146   
   142    147   The SQLite interface is defined by the **sqlite3.h** header file, which is
   143    148   generated from src/sqlite.h.in, ./manifest.uuid, and ./VERSION.  The
   144    149   [Tcl script](http://www.tcl.tk) at tool/mksqlite3h.tcl does the conversion.
   145         -The manifest.uuid file contains the SHA1 hash of the particular check-in
          150  +The manifest.uuid file contains the SHA3 hash of the particular check-in
   146    151   and is used to generate the SQLITE\_SOURCE\_ID macro.  The VERSION file
   147    152   contains the current SQLite version number.  The sqlite3.h header is really
   148    153   just a copy of src/sqlite.h.in with the source-id and version number inserted
   149    154   at just the right spots. Note that comment text in the sqlite3.h file is
   150    155   used to generate much of the SQLite API documentation.  The Tcl scripts
   151    156   used to generate that documentation are in a separate source repository.
   152    157   
   153    158   The SQL language parser is **parse.c** which is generate from a grammar in
   154    159   the src/parse.y file.  The conversion of "parse.y" into "parse.c" is done
   155    160   by the [lemon](./doc/lemon.html) LALR(1) parser generator.  The source code
   156         -for lemon is at tool/lemon.c.  Lemon uses a
   157         -template for generating its parser.  A generic template is in tool/lempar.c,
   158         -but SQLite uses a slightly modified template found in src/lempar.c.
          161  +for lemon is at tool/lemon.c.  Lemon uses the tool/lempar.c file as a
          162  +template for generating its parser.
   159    163   
   160    164   Lemon also generates the **parse.h** header file, at the same time it
   161    165   generates parse.c. But the parse.h header file is
   162    166   modified further (to add additional symbols) using the ./addopcodes.awk
   163    167   AWK script.
   164    168   
   165    169   The **opcodes.h** header file contains macros that define the numbers
................................................................................
   171    175   opcode-number to opcode-name that is used for EXPLAIN output.
   172    176   
   173    177   The **keywordhash.h** header file contains the definition of a hash table
   174    178   that maps SQL language keywords (ex: "CREATE", "SELECT", "INDEX", etc.) into
   175    179   the numeric codes used by the parse.c parser.  The keywordhash.h file is
   176    180   generated by a C-language program at tool mkkeywordhash.c.
   177    181   
          182  +The **pragma.h** header file contains various definitions used to parse
          183  +and implement the PRAGMA statements.  The header is generated by a
          184  +script **tool/mkpragmatab.tcl**. If you want to add a new PRAGMA, edit
          185  +the **tool/mkpragmatab.tcl** file to insert the information needed by the
          186  +parser for your new PRAGMA, then run the script to regenerate the
          187  +**pragma.h** header file.
          188  +
   178    189   ### The Amalgamation
   179    190   
   180    191   All of the individual C source code and header files (both manually-edited
   181    192   and automatically-generated) can be combined into a single big source file
   182    193   **sqlite3.c** called "the amalgamation".  The amalgamation is the recommended
   183    194   way of using SQLite in a larger application.  Combining all individual
   184    195   source code files into a single big source code file allows the C compiler
................................................................................
   188    199   
   189    200   The amalgamation is generated from the tool/mksqlite3c.tcl Tcl script.
   190    201   First, all of the individual source files must be gathered into the tsrc/
   191    202   subdirectory (using the equivalent of "make target_source") then the
   192    203   tool/mksqlite3c.tcl script is run to copy them all together in just the
   193    204   right order while resolving internal "#include" references.
   194    205   
   195         -The amalgamation source file is more than 100K lines long.  Some symbolic
          206  +The amalgamation source file is more than 200K lines long.  Some symbolic
   196    207   debuggers (most notably MSVC) are unable to deal with files longer than 64K
   197    208   lines.  To work around this, a separate Tcl script, tool/split-sqlite3c.tcl,
   198    209   can be run on the amalgamation to break it up into a single small C file
   199    210   called **sqlite3-all.c** that does #include on about five other files
   200    211   named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-5.c**.  In this way,
   201    212   all of the source code is contained within a single translation unit so
   202    213   that the compiler can do extra cross-procedure optimization, but no
................................................................................
   205    216   ## How It All Fits Together
   206    217   
   207    218   SQLite is modular in design.
   208    219   See the [architectural description](http://www.sqlite.org/arch.html)
   209    220   for details. Other documents that are useful in
   210    221   (helping to understand how SQLite works include the
   211    222   [file format](http://www.sqlite.org/fileformat2.html) description,
   212         -the [virtual machine](http://www.sqlite.org/vdbe.html) that runs
          223  +the [virtual machine](http://www.sqlite.org/opcode.html) that runs
   213    224   prepared statements, the description of
   214    225   [how transactions work](http://www.sqlite.org/atomiccommit.html), and
   215    226   the [overview of the query planner](http://www.sqlite.org/optoverview.html).
   216    227   
   217         -Unfortunately, years of effort have gone into optimizating SQLite, both
          228  +Years of effort have gone into optimizating SQLite, both
   218    229   for small size and high performance.  And optimizations tend to result in
   219         -complex code.  So there is a lot of complexity in the SQLite implementation.
          230  +complex code.  So there is a lot of complexity in the current SQLite
          231  +implementation.  It will not be the easiest library in the world to hack.
   220    232   
   221    233   Key files:
   222    234   
   223    235     *  **sqlite.h.in** - This file defines the public interface to the SQLite
   224    236        library.  Readers will need to be familiar with this interface before
   225    237        trying to understand how the library works internally.
   226    238   
   227    239     *  **sqliteInt.h** - this header file defines many of the data objects
   228    240        used internally by SQLite.
   229    241   
   230         -  *  **parse.y** - This file describes the LALR(1) grammer that SQLite uses
          242  +  *  **parse.y** - This file describes the LALR(1) grammar that SQLite uses
   231    243        to parse SQL statements, and the actions that are taken at each step
   232    244        in the parsing process.
   233    245   
   234    246     *  **vdbe.c** - This file implements the virtual machine that runs
   235    247        prepared statements.  There are various helper files whose names
   236    248        begin with "vdbe".  The VDBE has access to the vdbeInt.h header file
   237    249        which defines internal data objects.  The rest of SQLite interacts
................................................................................
   256    268        is the file that, when linked against sqlite3.a, generates the
   257    269        "sqlite3.exe" command-line shell.
   258    270   
   259    271     *  **tclsqlite.c** - This file implements the Tcl bindings for SQLite.  It
   260    272        is not part of the core SQLite library.  But as most of the tests in this
   261    273        repository are written in Tcl, the Tcl language bindings are important.
   262    274   
   263         -There are many other source files.  Each has a suscinct header comment that
          275  +There are many other source files.  Each has a succinct header comment that
   264    276   describes its purpose and role within the larger system.
   265    277   
   266    278   
   267    279   ## Contacts
   268    280   
   269    281   The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/)
   270         -with geographically distributed backup servers at
          282  +with geographically distributed backups at
   271    283   [http://www2.sqlite.org/](http://www2.sqlite.org) and
   272    284   [http://www3.sqlite.org/](http://www3.sqlite.org).

Changes to ext/fts3/fts3.c.

  3349   3349   
  3350   3350     /* The column value supplied by SQLite must be in range. */
  3351   3351     assert( iCol>=0 && iCol<=p->nColumn+2 );
  3352   3352   
  3353   3353     switch( iCol-p->nColumn ){
  3354   3354       case 0:
  3355   3355         /* The special 'table-name' column */
  3356         -      sqlite3_result_blob(pCtx, &pCsr, sizeof(Fts3Cursor*), SQLITE_TRANSIENT);
  3357         -      sqlite3_result_subtype(pCtx, SQLITE_BLOB);
         3356  +      sqlite3_result_pointer(pCtx, pCsr, "fts3cursor");
  3358   3357         break;
  3359   3358   
  3360   3359       case 1:
  3361   3360         /* The docid column */
  3362   3361         sqlite3_result_int64(pCtx, pCsr->iPrevId);
  3363   3362         break;
  3364   3363   
................................................................................
  3568   3567   */
  3569   3568   static int fts3FunctionArg(
  3570   3569     sqlite3_context *pContext,      /* SQL function call context */
  3571   3570     const char *zFunc,              /* Function name */
  3572   3571     sqlite3_value *pVal,            /* argv[0] passed to function */
  3573   3572     Fts3Cursor **ppCsr              /* OUT: Store cursor handle here */
  3574   3573   ){
  3575         -  int rc = SQLITE_OK;
  3576         -  if( sqlite3_value_subtype(pVal)==SQLITE_BLOB ){
  3577         -    *ppCsr = *(Fts3Cursor**)sqlite3_value_blob(pVal);
         3574  +  int rc;
         3575  +  *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor");
         3576  +  if( (*ppCsr)!=0 ){
         3577  +    rc = SQLITE_OK;
  3578   3578     }else{
  3579   3579       char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
  3580   3580       sqlite3_result_error(pContext, zErr, -1);
  3581   3581       sqlite3_free(zErr);
  3582   3582       rc = SQLITE_ERROR;
  3583   3583     }
  3584   3584     return rc;

Changes to ext/fts5/fts5_main.c.

  2605   2605   
  2606   2606     sqlite3_free(pGlobal);
  2607   2607   }
  2608   2608   
  2609   2609   static void fts5Fts5Func(
  2610   2610     sqlite3_context *pCtx,          /* Function call context */
  2611   2611     int nArg,                       /* Number of args */
  2612         -  sqlite3_value **apUnused        /* Function arguments */
         2612  +  sqlite3_value **apArg           /* Function arguments */
  2613   2613   ){
  2614   2614     Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
  2615         -  char buf[8];
  2616         -  UNUSED_PARAM2(nArg, apUnused);
  2617         -  assert( nArg==0 );
  2618         -  assert( sizeof(buf)>=sizeof(pGlobal) );
  2619         -  memcpy(buf, (void*)&pGlobal, sizeof(pGlobal));
  2620         -  sqlite3_result_blob(pCtx, buf, sizeof(pGlobal), SQLITE_TRANSIENT);
         2615  +  fts5_api **ppApi;
         2616  +  UNUSED_PARAM(nArg);
         2617  +  assert( nArg==1 );
         2618  +  ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr");
         2619  +  if( ppApi ) *ppApi = &pGlobal->api;
  2621   2620   }
  2622   2621   
  2623   2622   /*
  2624   2623   ** Implementation of fts5_source_id() function.
  2625   2624   */
  2626   2625   static void fts5SourceIdFunc(
  2627   2626     sqlite3_context *pCtx,          /* Function call context */
................................................................................
  2678   2677       if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
  2679   2678       if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
  2680   2679       if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
  2681   2680       if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
  2682   2681       if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
  2683   2682       if( rc==SQLITE_OK ){
  2684   2683         rc = sqlite3_create_function(
  2685         -          db, "fts5", 0, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
         2684  +          db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
  2686   2685         );
  2687   2686       }
  2688   2687       if( rc==SQLITE_OK ){
  2689   2688         rc = sqlite3_create_function(
  2690   2689             db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
  2691   2690         );
  2692   2691       }

Changes to ext/fts5/fts5_tcl.c.

    95     95     int rc = f5tDbPointer(interp, pObj, &db);
    96     96     if( rc!=TCL_OK ){
    97     97       return TCL_ERROR;
    98     98     }else{
    99     99       sqlite3_stmt *pStmt = 0;
   100    100       fts5_api *pApi = 0;
   101    101   
   102         -    rc = sqlite3_prepare_v2(db, "SELECT fts5()", -1, &pStmt, 0);
          102  +    rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0);
   103    103       if( rc!=SQLITE_OK ){
   104    104         Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
   105    105         return TCL_ERROR;
   106    106       }
   107         -
   108         -    if( SQLITE_ROW==sqlite3_step(pStmt) ){
   109         -      const void *pPtr = sqlite3_column_blob(pStmt, 0);
   110         -      memcpy((void*)&pApi, pPtr, sizeof(pApi));
   111         -    }
          107  +    sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr");
          108  +    sqlite3_step(pStmt);
   112    109   
   113    110       if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
   114    111         Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
   115    112         return TCL_ERROR;
   116    113       }
   117    114   
   118    115       *ppDb = db;

Changes to ext/fts5/fts5_test_mi.c.

    69     69   ** handle (accessible using sqlite3_errcode()/errmsg()).
    70     70   */
    71     71   static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){
    72     72     sqlite3_stmt *pStmt = 0;
    73     73     int rc;
    74     74   
    75     75     *ppApi = 0;
    76         -  rc = sqlite3_prepare(db, "SELECT fts5()", -1, &pStmt, 0);
           76  +  rc = sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0);
    77     77     if( rc==SQLITE_OK ){
    78         -    if( SQLITE_ROW==sqlite3_step(pStmt) 
    79         -        && sizeof(fts5_api*)==sqlite3_column_bytes(pStmt, 0)
    80         -      ){
    81         -      memcpy(ppApi, sqlite3_column_blob(pStmt, 0), sizeof(fts5_api*));
    82         -    }
           78  +    sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr");
           79  +    (void)sqlite3_step(pStmt);
    83     80       rc = sqlite3_finalize(pStmt);
    84     81     }
    85     82   
    86     83     return rc;
    87     84   }
    88     85   
    89     86   
................................................................................
   418    415     /* Register the implementation of matchinfo() */
   419    416     rc = pApi->xCreateFunction(pApi, "matchinfo", 0, fts5MatchinfoFunc, 0);
   420    417   
   421    418     return rc;
   422    419   }
   423    420   
   424    421   #endif /* SQLITE_ENABLE_FTS5 */
   425         -

Changes to ext/fts5/test/fts5aa.test.

   437    437   # exception. But since bm25() can now used the cached structure record,
   438    438   # it never sees the corruption introduced by funk() and so the following 
   439    439   # statement no longer fails.
   440    440   #
   441    441   do_catchsql_test 16.2 {
   442    442     SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d'
   443    443   } {0 {{} -1e-06 {}}}
   444         -# {1 {SQL logic error or missing database}}
          444  +# {1 {SQL logic error}}
   445    445   
   446    446   #-------------------------------------------------------------------------
   447    447   #
   448    448   reset_db
   449    449   do_execsql_test 17.1 {
   450    450     CREATE VIRTUAL TABLE b2 USING fts5(x, detail=%DETAIL%);
   451    451     INSERT INTO b2 VALUES('a');
................................................................................
   591    591     SELECT rowid FROM t9('a*')
   592    592   } {1}
   593    593   
   594    594   }
   595    595   
   596    596   
   597    597   finish_test
   598         -
   599         -

Changes to ext/fts5/test/fts5ab.test.

   290    290     INSERT INTO x1 VALUES($doc);
   291    291   }
   292    292   
   293    293   } ;# foreach_detail_mode...
   294    294   
   295    295   
   296    296   finish_test
   297         -

Changes to ext/fts5/test/fts5ac.test.

   272    272   } {
   273    273     do_execsql_test 2.3.$tn {
   274    274       SELECT fts5_expr_tcl($expr, 'N $x')
   275    275     } [list $tclexpr]
   276    276   }
   277    277   
   278    278   finish_test
   279         -

Changes to ext/fts5/test/fts5ad.test.

   227    227         28 {a f*} 29 {a* f*} 30 {a* fghij*}
   228    228       } {
   229    229         set res [prefix_query $prefix]
   230    230         if {$bAsc} {
   231    231           set res [lsort -integer -increasing $res]
   232    232         }
   233    233         set n [llength $res]
   234         -      if {$T==5} breakpoint 
   235    234         do_execsql_test $T.$bAsc.$tn.$n $sql $res
   236    235       }
   237    236     }
   238    237   
   239    238     catchsql COMMIT
   240    239   }
   241    240   
   242    241   }
   243    242   
   244    243   finish_test
   245         -

Changes to ext/fts5/test/fts5ae.test.

   305    305       SELECT fts5_test_phrasecount(t9) FROM t9 WHERE t9 MATCH $q LIMIT 1
   306    306     } $cnt
   307    307   }
   308    308   
   309    309   }
   310    310   
   311    311   finish_test
   312         -

Changes to ext/fts5/test/fts5af.test.

   174    174   do_execsql_test 5.1 {
   175    175     SELECT snippet(p1, 0, '[', ']', '...', 6) FROM p1('x');
   176    176   } {{[x] a a a a a...}}
   177    177   
   178    178   } ;# foreach_detail_mode 
   179    179   
   180    180   finish_test
   181         -

Changes to ext/fts5/test/fts5ag.test.

   138    138     }
   139    139   }
   140    140   
   141    141   } ;# foreach_detail_mode
   142    142   
   143    143   
   144    144   finish_test
   145         -

Changes to ext/fts5/test/fts5ah.test.

   163    163   } {10000}
   164    164   
   165    165   } ;# foreach_detail_mode
   166    166   
   167    167   #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r}
   168    168   
   169    169   finish_test
   170         -

Changes to ext/fts5/test/fts5ai.test.

    51     51   do_execsql_test 1.2 {
    52     52     INSERT INTO t1(t1) VALUES('integrity-check');
    53     53   }
    54     54   }
    55     55   
    56     56   
    57     57   finish_test
    58         -

Changes to ext/fts5/test/fts5aj.test.

    62     62     }
    63     63   }
    64     64   
    65     65   do_execsql_test 2.0 { INSERT INTO t1(t1) VALUES('integrity-check') }
    66     66   
    67     67   
    68     68   finish_test
    69         -

Changes to ext/fts5/test/fts5ak.test.

   143    143     {[a b c] [c d e]}
   144    144     {[a b c d e]}
   145    145   }
   146    146   
   147    147   }
   148    148   
   149    149   finish_test
   150         -

Changes to ext/fts5/test/fts5al.test.

    73     73     1 ""
    74     74     2 "fname"
    75     75     3 "fname(X'234ab')"
    76     76     4 "myfunc(-1.,'abc')"
    77     77   } {
    78     78     do_test 2.2.$tn {
    79     79       catchsql { INSERT INTO ft1(ft1, rank) VALUES('rank', $defn) }
    80         -  } {1 {SQL logic error or missing database}}
           80  +  } {1 {SQL logic error}}
    81     81   }
    82     82   
    83     83   #-------------------------------------------------------------------------
    84     84   # Assorted tests of the tcl interface for creating extension functions.
    85     85   #
    86     86   
    87     87   do_execsql_test 3.1 {
................................................................................
   293    293     SELECT *, rank FROM t3 WHERE t3 MATCH 'a' AND rank MATCH NULL
   294    294   } {1 {parse error in rank function: }}
   295    295   
   296    296   } ;# foreach_detail_mode
   297    297   
   298    298   
   299    299   finish_test
   300         -

Changes to ext/fts5/test/fts5alter.test.

    85     85   
    86     86   do_execsql_test 3.1 {
    87     87     CREATE VIRTUAL TABLE abc USING fts5(a);
    88     88     INSERT INTO abc(rowid, a) VALUES(1, 'a');
    89     89     BEGIN;
    90     90       INSERT INTO abc(rowid, a) VALUES(2, 'a');
    91     91   }
    92         -breakpoint
    93     92   do_execsql_test 3.2 {
    94     93       SELECT rowid FROM abc WHERE abc MATCH 'a';
    95     94   } {1 2}
    96     95   
    97     96   do_execsql_test 3.3 {
    98     97     COMMIT;
    99     98     SELECT rowid FROM abc WHERE abc MATCH 'a';
   100     99   } {1 2}
   101    100   
   102    101   finish_test
   103         -

Changes to ext/fts5/test/fts5auto.test.

   338    338   } {
   339    339     do_auto_test 4.$tn yy $expr
   340    340   }
   341    341   
   342    342   
   343    343   
   344    344   finish_test
   345         -

Changes to ext/fts5/test/fts5aux.test.

   236    236     4  {"a a a" "b" "a d"} {"[a] [a] [a]" "[a] d"}
   237    237     1  {"b d" "a b"}       {"[b] [d]" "[a] b"}
   238    238     2  {"d b" "a d"}       {"[d] [b]" "[a] d"}
   239    239     3  {"a a d"}           {"[a] [a] d"}
   240    240   } {
   241    241     execsql { DELETE FROM x1 }
   242    242     foreach row $lRow { execsql { INSERT INTO x1 VALUES($row) } }
   243         -  breakpoint
   244    243     do_execsql_test 8.$tn {
   245    244       SELECT highlight(x1, 0, '[', ']') FROM x1 WHERE x1 MATCH 'a OR (b AND d)';
   246    245     } $res
   247    246   }
   248    247   
   249    248   #-------------------------------------------------------------------------
   250    249   # Test the built-in bm25() demo.
................................................................................
   275    274   } {
   276    275     9 10
   277    276   }
   278    277   
   279    278   
   280    279   
   281    280   finish_test
   282         -

Changes to ext/fts5/test/fts5auxdata.test.

   108    108   db eval { 
   109    109     SELECT aux_function_2(f1, 2, 'A'), aux_function_2(f1, 2, 'B') 
   110    110     FROM f1 WHERE f1 MATCH 'a'
   111    111     ORDER BY rowid ASC
   112    112   }
   113    113   
   114    114   finish_test
   115         -

Changes to ext/fts5/test/fts5bigpl.test.

    57     57       set doc [string repeat "$t " 150000000]
    58     58       execsql { INSERT INTO t1 VALUES($doc) }
    59     59     }
    60     60     execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
    61     61   } {}
    62     62   
    63     63   finish_test
    64         -

Changes to ext/fts5/test/fts5bigtok.test.

    60     60       do_execsql_test 2.[string range $v 0 0] {
    61     61         SELECT rowid FROM t1($v) ORDER BY rowid DESC
    62     62       } [lsort -integer -decr $res]
    63     63     }
    64     64   }
    65     65   
    66     66   finish_test
    67         -
    68         -

Changes to ext/fts5/test/fts5colset.test.

    80     80     do_catchsql_test 4.1 {
    81     81       SELECT * FROM t1 WHERE rowid MATCH 'a'
    82     82     } {1 {unable to use function MATCH in the requested context}}
    83     83   }
    84     84   
    85     85   
    86     86   finish_test
    87         -
    88         -

Changes to ext/fts5/test/fts5columnsize.test.

   139    139   #
   140    140   do_execsql_test 4.1.1 {
   141    141     CREATE VIRTUAL TABLE t5 USING fts5(x, columnsize=0);
   142    142     INSERT INTO t5 VALUES('1 2 3 4');
   143    143     INSERT INTO t5 VALUES('2 4 6 8');
   144    144   }
   145    145   
   146         -breakpoint
   147    146   do_execsql_test 4.1.2 {
   148    147     INSERT INTO t5(t5) VALUES('integrity-check');
   149    148   }
   150    149   
   151    150   finish_test

Changes to ext/fts5/test/fts5config.test.

    62     62     5 "f1(x':;')"
    63     63     6 "f1(x'[]')"
    64     64     7 "f1(x'{}')"
    65     65     8 "f1('abc)"
    66     66   } {
    67     67     do_catchsql_test 3.$tn {
    68     68       INSERT INTO t1(t1, rank) VALUES('rank', $val);
    69         -  } {1 {SQL logic error or missing database}}
           69  +  } {1 {SQL logic error}}
    70     70   }
    71     71   
    72     72   #-------------------------------------------------------------------------
    73     73   # The parsing of SQL literals specified as part of 'rank' options.
    74     74   #
    75     75   do_execsql_test 4.0 {
    76     76     CREATE VIRTUAL TABLE zzz USING fts5(one);
................................................................................
   106    106   #-------------------------------------------------------------------------
   107    107   # Misquoting in tokenize= and other options. 
   108    108   #
   109    109   do_catchsql_test 5.1 {
   110    110     CREATE VIRTUAL TABLE xx USING fts5(x, tokenize="porter 'ascii");
   111    111   } {1 {parse error in tokenize directive}} 
   112    112   
   113         -breakpoint
   114    113   do_catchsql_test 5.2 {
   115    114     CREATE VIRTUAL TABLE xx USING fts5(x, [y[]);
   116    115   } {0 {}}
   117    116   
   118    117   do_catchsql_test 5.3 {
   119    118     CREATE VIRTUAL TABLE yy USING fts5(x, [y]]);
   120    119   } {1 {unrecognized token: "]"}}
................................................................................
   165    164   #   9.5.* 'hashsize' options.
   166    165   #
   167    166   do_execsql_test 9.0 {
   168    167     CREATE VIRTUAL TABLE abc USING fts5(a, b);
   169    168   } {}
   170    169   do_catchsql_test 9.1.1 {
   171    170     INSERT INTO abc(abc, rank) VALUES('pgsz', -5);
   172         -} {1 {SQL logic error or missing database}}
          171  +} {1 {SQL logic error}}
   173    172   do_catchsql_test 9.1.2 {
   174    173     INSERT INTO abc(abc, rank) VALUES('pgsz', 50000000);
   175         -} {1 {SQL logic error or missing database}}
          174  +} {1 {SQL logic error}}
   176    175   do_catchsql_test 9.1.3 {
   177    176     INSERT INTO abc(abc, rank) VALUES('pgsz', 66.67);
   178         -} {1 {SQL logic error or missing database}}
          177  +} {1 {SQL logic error}}
   179    178   
   180    179   do_catchsql_test 9.2.1 {
   181    180     INSERT INTO abc(abc, rank) VALUES('automerge', -5);
   182         -} {1 {SQL logic error or missing database}}
          181  +} {1 {SQL logic error}}
   183    182   do_catchsql_test 9.2.2 {
   184    183     INSERT INTO abc(abc, rank) VALUES('automerge', 50000000);
   185         -} {1 {SQL logic error or missing database}}
          184  +} {1 {SQL logic error}}
   186    185   do_catchsql_test 9.2.3 {
   187    186     INSERT INTO abc(abc, rank) VALUES('automerge', 66.67);
   188         -} {1 {SQL logic error or missing database}}
          187  +} {1 {SQL logic error}}
   189    188   do_execsql_test 9.2.4 {
   190    189     INSERT INTO abc(abc, rank) VALUES('automerge', 1);
   191    190   } {}
   192    191   
   193    192   do_catchsql_test 9.3.1 {
   194    193     INSERT INTO abc(abc, rank) VALUES('crisismerge', -5);
   195         -} {1 {SQL logic error or missing database}}
          194  +} {1 {SQL logic error}}
   196    195   do_catchsql_test 9.3.2 {
   197    196     INSERT INTO abc(abc, rank) VALUES('crisismerge', 66.67);
   198         -} {1 {SQL logic error or missing database}}
          197  +} {1 {SQL logic error}}
   199    198   do_execsql_test 9.3.3 {
   200    199     INSERT INTO abc(abc, rank) VALUES('crisismerge', 1);
   201    200   } {}
   202    201   do_execsql_test 9.3.4 {
   203    202     INSERT INTO abc(abc, rank) VALUES('crisismerge', 50000000);
   204    203   } {}
   205    204   
   206    205   do_catchsql_test 9.4.1 {
   207    206     INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1);
   208         -} {1 {SQL logic error or missing database}}
          207  +} {1 {SQL logic error}}
   209    208   
   210    209   do_catchsql_test 9.5.1 {
   211    210     INSERT INTO abc(abc, rank) VALUES('hashsize', 'not an integer');
   212         -} {1 {SQL logic error or missing database}}
          211  +} {1 {SQL logic error}}
   213    212   do_catchsql_test 9.5.2 {
   214    213     INSERT INTO abc(abc, rank) VALUES('hashsize', -500000);
   215         -} {1 {SQL logic error or missing database}}
          214  +} {1 {SQL logic error}}
   216    215   do_catchsql_test 9.5.3 {
   217    216     INSERT INTO abc(abc, rank) VALUES('hashsize', 500000);
   218    217   } {0 {}}
   219    218   
   220    219   #-------------------------------------------------------------------------
   221    220   # Too many prefix indexes. Maximum allowed is 31.
   222    221   #
................................................................................
   241    240   } {
   242    241     set res [list 1 {malformed detail=... directive}]
   243    242     do_catchsql_test 11.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res
   244    243   }
   245    244   
   246    245   do_catchsql_test 12.1 {
   247    246     INSERT INTO t1(t1, rank) VALUES('rank', NULL);;
   248         -} {1 {SQL logic error or missing database}}
          247  +} {1 {SQL logic error}}
   249    248   
   250    249   #-------------------------------------------------------------------------
   251    250   # errors in the 'usermerge' option
   252    251   #
   253    252   do_execsql_test 13.0 {
   254    253     CREATE VIRTUAL TABLE tt USING fts5(ttt);
   255    254   }
................................................................................
   256    255   foreach {tn val} {
   257    256     1     -1
   258    257     2     4.2
   259    258     3     17
   260    259     4     1
   261    260   } {
   262    261     set sql "INSERT INTO tt(tt, rank) VALUES('usermerge', $val)"
   263         -  do_catchsql_test 13.$tn $sql {1 {SQL logic error or missing database}}
          262  +  do_catchsql_test 13.$tn $sql {1 {SQL logic error}}
   264    263   }
   265    264   
   266    265   finish_test
   267         -

Changes to ext/fts5/test/fts5conflict.test.

    62     62     REPLACE INTO tbl VALUES(1, '4 5 6', '3 2 1');
    63     63     DELETE FROM tbl WHERE a=100;
    64     64   
    65     65     INSERT INTO fts_idx(fts_idx) VALUES('integrity-check');
    66     66   }
    67     67   
    68     68   finish_test
    69         -
    70         -

Changes to ext/fts5/test/fts5content.test.

   251    251   do_execsql_test 6.2 {
   252    252     DROP TABLE xx;
   253    253     SELECT name FROM sqlite_master;
   254    254   } {}
   255    255   
   256    256   
   257    257   finish_test
   258         -

Changes to ext/fts5/test/fts5corrupt.test.

    92     92   
    93     93   do_catchsql_test 3.1 {
    94     94     DELETE FROM t3_content WHERE rowid = 3;
    95     95     SELECT * FROM t3 WHERE t3 MATCH 'o';
    96     96   } {1 {database disk image is malformed}}
    97     97   
    98     98   finish_test
    99         -

Changes to ext/fts5/test/fts5corrupt2.test.

   265    265   do_catchsql_test 6.2 {
   266    266     SELECT colsize(x5, 0) FROM x5 WHERE x5 MATCH 'a'
   267    267   } {1 SQLITE_CORRUPT_VTAB}
   268    268   
   269    269   
   270    270   sqlite3_fts5_may_be_corrupt 0
   271    271   finish_test
   272         -

Changes to ext/fts5/test/fts5corrupt3.test.

   405    405   } {}
   406    406   do_catchsql_test 9.2.2 {
   407    407     SELECT * FROM t1('one AND two');
   408    408   } {1 {database disk image is malformed}}
   409    409   
   410    410   sqlite3_fts5_may_be_corrupt 0
   411    411   finish_test
   412         -

Changes to ext/fts5/test/fts5delete.test.

    47     47     for {set i 0} {$i < 5} {incr i} {
    48     48       execsql { INSERT INTO t1(t1, rank) VALUES('merge', 1) }
    49     49       execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
    50     50     }
    51     51   } {}
    52     52   
    53     53   finish_test
    54         -

Changes to ext/fts5/test/fts5detail.test.

   237    237       (SELECT sum(length(block)) from t2_data) <
   238    238       (SELECT sum(length(block)) from t3_data)
   239    239   } {1}
   240    240   
   241    241   
   242    242   
   243    243   finish_test
   244         -

Changes to ext/fts5/test/fts5determin.test.

    59     59     } {}
    60     60   
    61     61     do_determin_test 1.4
    62     62   }
    63     63   
    64     64   
    65     65   finish_test
    66         -
    67         -

Changes to ext/fts5/test/fts5dlidx.test.

    62     62           append doc " y" 
    63     63         }
    64     64       }
    65     65       execsql { INSERT INTO t1(rowid, x) VALUES($rowid, $doc) }
    66     66     }
    67     67     execsql COMMIT
    68     68   
    69         -  breakpoint
    70     69     do_test $tn.1 {
    71     70       execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
    72     71     } {}
    73     72     
    74     73     do_fb_test $tn.3.1 { SELECT rowid FROM t1 WHERE t1 MATCH 'a AND x' } $xdoc
    75     74     do_fb_test $tn.3.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'x AND a' } $xdoc
    76     75     
................................................................................
   120    119       INSERT INTO t1(rowid,x) SELECT i, $str FROM iii;
   121    120       COMMIT;
   122    121     }
   123    122   
   124    123     do_execsql_test $tn.1 {
   125    124       SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a'
   126    125     } {1}
   127         -  breakpoint
   128    126     do_execsql_test $tn.2 {
   129    127       SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a' ORDER BY rowid DESC
   130    128     } {1}
   131    129   }
   132    130   
   133    131   do_dlidx_test2 2.1 [expr 20] [expr 1<<57] [expr (1<<57) + 128]
   134    132   
................................................................................
   193    191   }
   194    192   
   195    193   } ;# foreach_detail_mode
   196    194   
   197    195   
   198    196   
   199    197   finish_test
   200         -

Changes to ext/fts5/test/fts5doclist.test.

    40     40   
    41     41   do_execsql_test 1.2 {
    42     42     INSERT INTO ccc(ccc) VALUES('integrity-check');
    43     43   }
    44     44   
    45     45   
    46     46   finish_test
    47         -

Changes to ext/fts5/test/fts5eb.test.

    77     77   do_execsql_test 3.3 {
    78     78     SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"/" OR "just"' ORDER BY rank;
    79     79   } {1 -1e-06}
    80     80   
    81     81   
    82     82   
    83     83   finish_test
    84         -
    85         -
    86         -

Changes to ext/fts5/test/fts5fault1.test.

   347    347       if {$ls != "2 0"} { error "fts5_level_segs says {$ls}" }
   348    348     }
   349    349   }
   350    350   
   351    351   
   352    352   
   353    353   finish_test
   354         -

Changes to ext/fts5/test/fts5fault2.test.

   133    133       );
   134    134     }
   135    135   } -test {
   136    136     faultsim_test_result {0 {}}
   137    137   }
   138    138   
   139    139   finish_test
   140         -

Changes to ext/fts5/test/fts5fault3.test.

   106    106   } -test {
   107    107     faultsim_test_result [list 0 {}]
   108    108   }
   109    109   
   110    110   
   111    111   
   112    112   finish_test
   113         -

Changes to ext/fts5/test/fts5fault4.test.

   391    391   } -body {
   392    392     db eval { ALTER TABLE "tbl one" RENAME TO "tbl two" }
   393    393   } -test {
   394    394     faultsim_test_result {0 {}}
   395    395   }
   396    396   
   397    397   finish_test
   398         -

Changes to ext/fts5/test/fts5fault5.test.

   101    101     db eval {
   102    102       SELECT term FROM tv WHERE term BETWEEN '1' AND '2';
   103    103     }
   104    104   } -test {
   105    105     faultsim_test_result {0 {1 10 11 12 13 14 15 16 17 18 19 2}}
   106    106   }
   107    107   
   108         -breakpoint
   109    108   do_execsql_test 3.3.0 {
   110    109     SELECT * FROM tv2;
   111    110   } {
   112    111     0 x 1 {} 1 x 1 {} 10 x 1 {} 11 x 1 {} 12 x 1 {} 13 x 1 {}        
   113    112     14 x 1 {} 15 x 1 {} 16 x 1 {} 17 x 1 {} 18 x 1 {} 19  x 1 {}     
   114    113     2 x 1 {} 3 x 1 {} 4 x 1 {} 5 x 1 {} 6 x 1 {} 7 x 1 {} 8 x 1 {}   
   115    114     9 x 1 {}
................................................................................
   126    125         9 x 1 {}
   127    126     ]]
   128    127   }
   129    128   
   130    129   
   131    130   
   132    131   finish_test
   133         -

Changes to ext/fts5/test/fts5fault6.test.

   276    276     }
   277    277   } -test {
   278    278     faultsim_test_result {0 1}
   279    279   }
   280    280   
   281    281   #-------------------------------------------------------------------------
   282    282   catch { db close }
   283         -breakpoint
   284    283   do_faultsim_test 6 -faults oom* -prep {
   285    284     sqlite_orig db test.db
   286    285     sqlite3_db_config_lookaside db 0 0 0
   287    286   } -test {
   288    287     faultsim_test_result {0 {}} {1 {initialization of fts5 failed: }}
   289    288     if {$testrc==0} {
   290    289       db eval { CREATE VIRTUAL TABLE temp.t1 USING fts5(x) }
   291    290     }
   292    291     db close
   293    292   }
   294    293   finish_test
   295         -

Changes to ext/fts5/test/fts5fault7.test.

   112    112   do_faultsim_test 2.2 -faults oom-* -body {
   113    113     db eval { SELECT * FROM xy('""') }
   114    114   } -test {
   115    115     faultsim_test_result {0 {}}
   116    116   }
   117    117   
   118    118   finish_test
   119         -

Changes to ext/fts5/test/fts5fault8.test.

    78     78     execsql { INSERT INTO x2(x2) VALUES('optimize') }
    79     79   } -test {
    80     80     faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
    81     81   }
    82     82   
    83     83   
    84     84   finish_test
    85         -

Changes to ext/fts5/test/fts5fault9.test.

   149    149     faultsim_test_result [list 0 {1 3}]
   150    150   }
   151    151   
   152    152   
   153    153   } ;# foreach_detail_mode...
   154    154   
   155    155   finish_test
   156         -

Changes to ext/fts5/test/fts5faultA.test.

    57     57     sqlite3 db test.db
    58     58   } -body {
    59     59     execsql { SELECT rowid FROM o2('a+b+c NOT xyz') }
    60     60   } -test {
    61     61     faultsim_test_result {0 {1 2}}
    62     62   }
    63     63   finish_test
    64         -

Changes to ext/fts5/test/fts5faultB.test.

   128    128     execsql { SELECT rowid FROM t1('{a b c} : (a AND d)') }
   129    129   } -test {
   130    130     faultsim_test_result {0 {2 3}}
   131    131   }
   132    132   
   133    133   
   134    134   finish_test
   135         -

Changes to ext/fts5/test/fts5full.test.

    36     36         execsql { INSERT INTO x8 VALUES( rnddoc(5) ); }
    37     37       }
    38     38     } msg] $msg
    39     39   } {1 {database or disk is full}}
    40     40   
    41     41   
    42     42   finish_test
    43         -

Changes to ext/fts5/test/fts5fuzz1.test.

    86     86   reset_db
    87     87   do_catchsql_test 4.1 {
    88     88     CREATE VIRTUAL TABLE f2 USING fts5(o, t);
    89     89     SELECT * FROM f2('(8 AND 9)`AND 10');
    90     90   } {1 {fts5: syntax error near "`"}}
    91     91   
    92     92   finish_test
    93         -

Changes to ext/fts5/test/fts5hash.test.

   117    117       set hash [sqlite3_fts5_token_hash 1024 $big]
   118    118       while {1} {
   119    119         set small [random_token]
   120    120         if {[sqlite3_fts5_token_hash 1024 $small]==$hash} break
   121    121       }
   122    122   
   123    123       execsql { CREATE VIRTUAL TABLE t2 USING fts5(x, detail=%DETAIL%) }
   124         -breakpoint
   125    124       execsql {
   126    125         INSERT INTO t2 VALUES($small || ' ' || $big);
   127    126       }
   128    127     } {}
   129    128   
   130    129   } ;# foreach_detail_mode
   131    130   
   132    131   finish_test
   133         -

Changes to ext/fts5/test/fts5integrity.test.

   206    206         if {$res == [lsort -integer $res2]} { incr ok }
   207    207       }
   208    208       set ok
   209    209     } {1000}
   210    210   }
   211    211   
   212    212   finish_test
   213         -

Changes to ext/fts5/test/fts5lastrowid.test.

    66     66   do_execsql_test 1.6 {
    67     67     INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1;
    68     68     SELECT last_insert_rowid();
    69     69   } {14}
    70     70   
    71     71   
    72     72   finish_test
    73         -

Changes to ext/fts5/test/fts5leftjoin.test.

    37     37   } {1 1 abc 2 {} {}}
    38     38   
    39     39   do_execsql_test 1.2 {
    40     40     SELECT * FROM t1 LEFT JOIN vt ON (vt MATCH 'abc')
    41     41   } {1 abc 2 abc}
    42     42   
    43     43   finish_test
    44         -
    45         -

Changes to ext/fts5/test/fts5matchinfo.test.

   468    468   } ;# foreach_detail_mode
   469    469   
   470    470   #-------------------------------------------------------------------------
   471    471   # Test that a bad fts5() return is detected
   472    472   #
   473    473   reset_db
   474    474   proc xyz {} {}
   475         -db func fts5 -argcount 0 xyz
          475  +db func fts5 -argcount 1 xyz
   476    476   do_test 13.1 {
   477    477     list [catch { sqlite3_fts5_register_matchinfo db } msg] $msg
   478    478   } {1 SQLITE_ERROR}
   479    479   
   480    480   #-------------------------------------------------------------------------
   481    481   # Test that an invalid matchinfo() flag is detected
   482    482   #
................................................................................
   488    488   } {}
   489    489   
   490    490   do_catchsql_test 14.2 {
   491    491     SELECT matchinfo(x1, 'd') FROM x1('a b c');
   492    492   } {1 {unrecognized matchinfo flag: d}}
   493    493   
   494    494   finish_test
   495         -

Changes to ext/fts5/test/fts5merge.test.

   237    237   do_execsql_test 6.3 {
   238    238     INSERT INTO g1(g1) VALUES('integrity-check');
   239    239   }
   240    240   
   241    241   
   242    242   
   243    243   finish_test
   244         -

Changes to ext/fts5/test/fts5merge2.test.

    51     51   do_execsql_test 1.2 {
    52     52     INSERT INTO t1(t1) VALUES('integrity-check');
    53     53   }
    54     54   
    55     55   }
    56     56   
    57     57   finish_test
    58         -

Changes to ext/fts5/test/fts5multiclient.test.

    41     41       sql1 { INSERT INTO t1 VALUES('a b c') }
    42     42       sql3 { INSERT INTO t1(t1) VALUES('integrity-check') }
    43     43     } {}
    44     44   
    45     45   };# do_multiclient_test
    46     46   };# foreach_detail_mode
    47     47   finish_test
    48         -

Changes to ext/fts5/test/fts5near.test.

    64     64   do_near_test 1.23 "a b c d e f g h i" { NEAR(a+b+c+d i b+c, 4) } 0
    65     65   
    66     66   do_near_test 1.24 "a b c d e f g h i" { NEAR(i a+b+c+d b+c, 5) } 1
    67     67   do_near_test 1.25 "a b c d e f g h i" { NEAR(i a+b+c+d b+c, 4) } 0
    68     68   
    69     69   
    70     70   finish_test
    71         -

Changes to ext/fts5/test/fts5onepass.test.

   174    174       UPDATE ttt SET x = 'A B C' WHERE rowid = 4;
   175    175       INSERT INTO ttt(rowid, x) VALUES(6, 'd e f');
   176    176     COMMIT;
   177    177   } {}
   178    178   do_test 4.2.2 { fts5_level_segs ttt } {3}
   179    179   
   180    180   finish_test
   181         -

Changes to ext/fts5/test/fts5optimize.test.

   102    102     do_execsql_test 2.$tn.5 {
   103    103       INSERT INTO t1(t1) VALUES('integrity-check');
   104    104     }
   105    105   
   106    106     do_test 2.$tn.6 { fts5_segcount t1 } 1
   107    107   }
   108    108   finish_test
   109         -

Changes to ext/fts5/test/fts5phrase.test.

   112    112     FROM t3('a:f+f')
   113    113   } {
   114    114     31 {h *f f*} {i j g e c} {j j f c a i j} 
   115    115     50 {*f f* c} {f f b i i} {f f a j e c i}
   116    116   }
   117    117   
   118    118   finish_test
   119         -

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

    60     60     0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
    61     61   }
    62     62   
    63     63   
    64     64   
    65     65   
    66     66   finish_test
    67         -

Changes to ext/fts5/test/fts5porter.test.

 11799  11799       lindex [sqlite3_fts5_tokenize db porter $in] 0
 11800  11800     } $out
 11801  11801     incr i
 11802  11802   }
 11803  11803   
 11804  11804   
 11805  11805   finish_test
 11806         -

Changes to ext/fts5/test/fts5porter2.test.

    63     63       lindex [sqlite3_fts5_tokenize db porter $in] 0
    64     64     } $out
    65     65     incr i
    66     66   }
    67     67   
    68     68   
    69     69   finish_test
    70         -

Changes to ext/fts5/test/fts5prefix.test.

   337    337       do_execsql_test 7.$tn {
   338    338         SELECT md5sum(id, block) FROM tt_data
   339    339       } [list $::checksum]
   340    340     }
   341    341   }
   342    342   
   343    343   finish_test
   344         -
   345         -

Changes to ext/fts5/test/fts5query.test.

    75     75       } {}
    76     76       incr ret
    77     77     }
    78     78   }
    79     79   
    80     80   
    81     81   finish_test
    82         -
    83         -

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

   148    148     VTest MATCH 'wrinkle in time OR a wrinkle in time' ORDER BY rank;
   149    149   } {{wrinkle in time} {Bill Smith}}
   150    150   
   151    151   
   152    152   
   153    153   
   154    154   finish_test
   155         -

Changes to ext/fts5/test/fts5rebuild.test.

    60     60     CREATE VIRTUAL TABLE nc USING fts5(doc, content=);
    61     61   }
    62     62   
    63     63   do_catchsql_test 2.2 {
    64     64     INSERT INTO nc(nc) VALUES('rebuild');
    65     65   } {1 {'rebuild' may not be used with a contentless fts5 table}}
    66     66   finish_test
    67         -

Changes to ext/fts5/test/fts5restart.test.

   145    145     }
   146    146     set res
   147    147   } {500 400 300}
   148    148   
   149    149   
   150    150   
   151    151   finish_test
   152         -

Changes to ext/fts5/test/fts5rowid.test.

   212    212   } {36}
   213    213   
   214    214   #db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM x5_data} {puts $r}
   215    215   
   216    216   
   217    217   
   218    218   finish_test
   219         -

Changes to ext/fts5/test/fts5simple.test.

   407    407   
   408    408   do_catchsql_test 19.2 {
   409    409     SELECT * FROM x1 WHERE x1 MATCH 'c0 AND (c1 AND (c2 AND (c3 AND (c4 AND (c5 AND (c6 AND (c7 AND (c8 AND (c9 AND (c10 AND (c11 AND (c12 AND (c13 AND (c14 AND (c15 AND (c16 AND (c17 AND (c18 AND (c19 AND (c20 AND (c21 AND (c22 AND (c23 AND (c24 AND (c25 AND (c26 AND (c27 AND (c28 AND (c29 AND (c30 AND (c31 AND (c32 AND (c33 AND (c34 AND (c35 AND (c36 AND (c37 AND (c38 AND (c39 AND (c40 AND (c41 AND (c42 AND (c43 AND (c44 AND (c45 AND (c46 AND (c47 AND (c48 AND (c49 AND (c50 AND (c51 AND (c52 AND (c53 AND (c54 AND (c55 AND (c56 AND (c57 AND (c58 AND (c59 AND (c60 AND (c61 AND (c62 AND (c63 AND (c64 AND (c65 AND (c66 AND (c67 AND (c68 AND (c69 AND (c70 AND (c71 AND (c72 AND (c73 AND (c74 AND (c75 AND (c76 AND (c77 AND (c78 AND (c79 AND (c80 AND (c81 AND (c82 AND (c83 AND (c84 AND (c85 AND (c86 AND (c87 AND (c88 AND (c89 AND (c90 AND (c91 AND (c92 AND (c93 AND (c94 AND (c95 AND (c96 AND (c97 AND (c98 AND (c99 AND (c100 AND (c101 AND (c102 AND (c103 AND (c104 AND (c105 AND (c106 AND (c107 AND (c108 AND (c109 AND (c110 AND (c111 AND (c112 AND (c113 AND (c114 AND (c115 AND (c116 AND (c117 AND (c118 AND (c119 AND (c120 AND (c121 AND (c122 AND (c123 AND (c124 AND (c125 AND (c126 AND (c127 AND (c128 AND (c129 AND (c130 AND (c131 AND (c132 AND (c133 AND (c134 AND (c135 AND (c136 AND (c137 AND (c138 AND (c139 AND (c140 AND (c141 AND (c142 AND (c143 AND (c144 AND (c145 AND (c146 AND (c147 AND (c148 AND (c149 AND (c150 AND (c151 AND (c152 AND (c153 AND (c154 AND (c155 AND (c156 AND (c157 AND (c158 AND (c159 AND (c160 AND (c161 AND (c162 AND (c163 AND (c164 AND (c165 AND (c166 AND (c167 AND (c168 AND (c169 AND (c170 AND (c171 AND (c172 AND (c173 AND (c174 AND (c175 AND (c176 AND (c177 AND (c178 AND (c179 AND (c180 AND (c181 AND (c182 AND (c183 AND (c184 AND (c185 AND (c186 AND (c187 AND (c188 AND (c189 AND (c190 AND (c191 AND (c192 AND (c193 AND (c194 AND (c195 AND (c196 AND (c197 AND (c198 AND (c199 AND c200)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
   410    410   } {1 {fts5: parser stack overflow}}
   411    411   
   412    412   #-------------------------------------------------------------------------
   413    413   reset_db
   414         -breakpoint
   415    414   do_execsql_test 20.0 {
   416    415     CREATE VIRTUAL TABLE x1 USING fts5(x);
   417    416     INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
   418    417     INSERT INTO x1(rowid, x) VALUES(11111, 'onetwothree');
   419    418   }
   420    419   do_test 20.1 {
   421    420     for {set i 1} {$i <= 200} {incr i} {

Changes to ext/fts5/test/fts5simple2.test.

   366    366   do_execsql_test 17.6 { 
   367    367     SELECT * FROM t2('x:b* OR y:a*') WHERE rowid>55
   368    368   }
   369    369   
   370    370   #db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM t2_data} {puts $r}
   371    371     
   372    372   finish_test
   373         -

Changes to ext/fts5/test/fts5simple3.test.

   112    112   } 
   113    113   do_execsql_test 4.6 {
   114    114     SELECT * FROM t2('ab + xyz');
   115    115   }
   116    116   
   117    117   
   118    118   finish_test
   119         -

Changes to ext/fts5/test/fts5synonym.test.

   417    417   do_execsql_test 7.1.2 {
   418    418     INSERT INTO t2(t2) VALUES('integrity-check');
   419    419   }
   420    420   
   421    421   } ;# foreach_detail_mode
   422    422   
   423    423   finish_test
   424         -

Changes to ext/fts5/test/fts5synonym2.test.

   157    157   
   158    158   }
   159    159   
   160    160   }
   161    161   }
   162    162   
   163    163   finish_test
   164         -

Changes to ext/fts5/test/fts5tok1.test.

   105    105   do_catchsql_test 2.0 {
   106    106     CREATE VIRTUAL TABLE tX USING fts5tokenize(nosuchtokenizer);
   107    107   } {1 {vtable constructor failed: tX}}
   108    108   
   109    109   do_catchsql_test 2.1 {
   110    110     CREATE VIRTUAL TABLE t4 USING fts5tokenize;
   111    111     SELECT * FROM t4;
   112         -} {1 {SQL logic error or missing database}}
          112  +} {1 {SQL logic error}}
   113    113   
   114    114   
   115    115   finish_test

Changes to ext/fts5/test/fts5tokenizer.test.

   298    298   
   299    299   set ::flags [list]
   300    300   do_execsql_test 9.5.1 { SELECT * FROM t1('"abc xyz*"'); } {}
   301    301   do_test 9.5.2 { set ::flags } {query}
   302    302   
   303    303   
   304    304   finish_test
   305         -

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

    46     46     CREATE VIRTUAL TABLE t1 USING fts5(x);
    47     47     CREATE VIRTUAL TABLE t2 USING fts5(x, tokenize = unicode61);
    48     48     CREATE VIRTUAL TABLE t3 USING fts5(x, tokenize = ascii);
    49     49     INSERT INTO t1 VALUES('\xC0\xC8\xCC');
    50     50     INSERT INTO t2 VALUES('\xC0\xC8\xCC');
    51     51     INSERT INTO t3 VALUES('\xC0\xC8\xCC');
    52     52   "
    53         -breakpoint
    54     53   do_execsql_test 2.1 "
    55     54     SELECT 't1' FROM t1 WHERE t1 MATCH '\xE0\xE8\xEC';
    56     55     SELECT 't2' FROM t2 WHERE t2 MATCH '\xE0\xE8\xEC';
    57     56     SELECT 't3' FROM t3 WHERE t3 MATCH '\xE0\xE8\xEC';
    58     57   " {t1 t2}
    59     58   
    60     59   
    61     60   finish_test
    62         -

Changes to ext/fts5/test/fts5unicode2.test.

   277    277       INSERT INTO t9(a) VALUES('abc%88def %89ghi%90');
   278    278     }
   279    279   } {0 {}}
   280    280   
   281    281   
   282    282   #-------------------------------------------------------------------------
   283    283   
   284         -breakpoint
   285    284   do_unicode_token_test3 5.1 {tokenchars {}} {
   286    285     sqlite3_reset sqlite3_column_int
   287    286   } {
   288    287     sqlite3 sqlite3 
   289    288     reset reset 
   290    289     sqlite3 sqlite3 
   291    290     column column 

Changes to ext/fts5/test/fts5unicode3.test.

   122    122     }
   123    123     append str {'");}
   124    124     execsql $str
   125    125   } {}
   126    126   
   127    127   
   128    128   finish_test
   129         -

Changes to ext/fts5/test/fts5unindexed.test.

    72     72     INSERT INTO t4(t4, rowid, a, b, c) VALUES('delete', 20, 'j k l', '', 'p q r');
    73     73     DELETE FROM x4 WHERE rowid=20;
    74     74     INSERT INTO t4(t4) VALUES('integrity-check');
    75     75   } {}
    76     76   
    77     77   
    78     78   finish_test
    79         -

Changes to ext/fts5/test/fts5update.test.

   113    113   } {}
   114    114   do_execsql_test 2.2.integrity {
   115    115     INSERT INTO x2(x2) VALUES('integrity-check');
   116    116   }
   117    117   
   118    118   }
   119    119   finish_test
   120         -
   121         -

Changes to ext/fts5/test/fts5version.test.

    57     57     db close
    58     58     sqlite3 db test.db
    59     59     catchsql { SELECT * FROM t1 WHERE t1 MATCH 'a' }
    60     60   } {1 {invalid fts5 file format (found 0, expected 4) - run 'rebuild'}}
    61     61   
    62     62   
    63     63   finish_test
    64         -

Changes to ext/fts5/test/fts5vocab.test.

   206    206     INSERT INTO temp.t1 VALUES('1 5 3');
   207    207   
   208    208     INSERT INTO aux.t1 VALUES('x y z');
   209    209     INSERT INTO aux.t1 VALUES('m n o');
   210    210     INSERT INTO aux.t1 VALUES('x n z');
   211    211   }
   212    212   
   213         -breakpoint
   214    213   do_execsql_test 5.1 {
   215    214     CREATE VIRTUAL TABLE temp.vm  USING fts5vocab(main, t1, row);
   216    215     CREATE VIRTUAL TABLE temp.vt1 USING fts5vocab(t1, row);
   217    216     CREATE VIRTUAL TABLE temp.vt2 USING fts5vocab(temp, t1, row);
   218    217     CREATE VIRTUAL TABLE temp.va  USING fts5vocab(aux, t1, row);
   219    218   }
   220    219   

Changes to ext/lsm1/Makefile.

     1      1   #
     2      2   # This Makefile is designed for use with main.mk in the root directory of
     3      3   # this project. After including main.mk, the users makefile should contain:
     4      4   #
     5      5   #    LSMDIR=$(TOP)/ext/lsm1/
            6  +#    LSMOPTS=-fPIC
     6      7   #    include $(LSMDIR)/Makefile
     7      8   #
     8      9   # The most useful targets are [lsmtest] and [lsm.so].
     9     10   #
    10     11   
    11     12   LSMOBJ    = \
    12     13     lsm_ckpt.o \
................................................................................
    38     39                $(LSMDIR)/lsm-test/lsmtest_main.c $(LSMDIR)/lsm-test/lsmtest_mem.c \
    39     40                $(LSMDIR)/lsm-test/lsmtest_tdb.c $(LSMDIR)/lsm-test/lsmtest_tdb3.c \
    40     41                $(LSMDIR)/lsm-test/lsmtest_util.c $(LSMDIR)/lsm-test/lsmtest_win32.c
    41     42   
    42     43   
    43     44   # all: lsm.so
    44     45   
    45         -LSMOPTS = -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR)
           46  +LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR)
    46     47   
    47     48   lsm.so:	$(LSMOBJ)
    48     49   	$(TCCX) -shared -o lsm.so $(LSMOBJ)
    49     50   
    50     51   %.o:	$(LSMDIR)/%.c $(LSMHDR) sqlite3.h
    51     52   	$(TCCX) $(LSMOPTS) -c $<
    52     53   	
    53     54   lsmtest$(EXE): $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) sqlite3.o
    54     55   	# $(TCPPX) -c $(TOP)/lsm-test/lsmtest_tdb2.cc
    55         -	$(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB) 
    56         -
           56  +	$(TCCX) $(LSMOPTS) $(LSMTESTSRC) $(LSMOBJ) sqlite3.o -o lsmtest$(EXE) $(THREADLIB)

Changes to ext/lsm1/Makefile.msc.

     1      1   #
     2         -# This Makefile is designed for use with main.mk in the root directory of
     3         -# this project. After including main.mk, the users makefile should contain:
            2  +# This Makefile is designed for use with Makefile.msc in the root directory
            3  +# of this project.  The Makefile.msc should contain:
     4      4   #
     5         -#    LSMDIR=$(TOP)\ext\lsm1\
     6         -#    include $(LSMDIR)\Makefile.msc
            5  +#    LSMDIR=$(TOP)\ext\lsm1
            6  +#    !INCLUDE $(LSMDIR)\Makefile.msc
     7      7   #
     8      8   # The most useful targets are [lsmtest.exe] and [lsm.dll].
     9      9   #
    10     10   
    11     11   LSMOBJ    = \
    12     12     lsm_ckpt.lo \
    13     13     lsm_file.lo \
................................................................................
    35     35                $(LSMDIR)\lsm-test\lsmtest9.c                                   \
    36     36                $(LSMDIR)\lsm-test\lsmtest_datasource.c \
    37     37                $(LSMDIR)\lsm-test\lsmtest_func.c $(LSMDIR)\lsm-test\lsmtest_io.c  \
    38     38                $(LSMDIR)\lsm-test\lsmtest_main.c $(LSMDIR)\lsm-test\lsmtest_mem.c \
    39     39                $(LSMDIR)\lsm-test\lsmtest_tdb.c $(LSMDIR)\lsm-test\lsmtest_tdb3.c \
    40     40                $(LSMDIR)\lsm-test\lsmtest_util.c $(LSMDIR)\lsm-test\lsmtest_win32.c
    41     41   
    42         -# all: lsm.dll
           42  +# all: lsm.dll lsmtest.exe
    43     43   
    44         -LSMOPTS = -DLSM_MUTEX_WIN32=1 -I$(LSMDIR)
           44  +LSMOPTS = $(NO_WARN) -DLSM_MUTEX_WIN32=1 -I$(LSMDIR)
           45  +
           46  +!IF $(DEBUG)>2
           47  +LSMOPTS = $(LSMOPTS) -DLSM_DEBUG=1
           48  +!ENDIF
           49  +
           50  +!IF $(MEMDEBUG)!=0
           51  +LSMOPTS = $(LSMOPTS) -DLSM_DEBUG_MEM=1
           52  +!ENDIF
    45     53   
    46     54   lsm_ckpt.lo:	$(LSMDIR)\lsm_ckpt.c $(LSMHDR) $(SQLITE3H)
    47     55   	$(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_ckpt.c
    48     56   
    49     57   lsm_file.lo:	$(LSMDIR)\lsm_file.c $(LSMHDR) $(SQLITE3H)
    50     58   	$(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_file.c
    51     59   
................................................................................
    83     91   	$(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_varint.c
    84     92   
    85     93   lsm_vtab.lo:	$(LSMDIR)\lsm_vtab.c $(LSMHDR) $(SQLITE3H)
    86     94   	$(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_vtab.c
    87     95   
    88     96   lsm.dll:	$(LSMOBJ)
    89     97   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ $(LSMOBJ)
           98  +	copy /Y $@ $(LSMDIR)\$@
    90     99   
    91         -lsmtest.exe: $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) $(LIBOBJS1)
    92         -	$(LTLINK) $(LSMOPTS) $(LSMTESTSRC) /link $(LSMOBJ) $(LIBOBJS1)
          100  +lsmtest.exe: $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) $(LIBOBJ)
          101  +	$(LTLINK) $(LSMOPTS) $(LSMTESTSRC) /link $(LSMOBJ) $(LIBOBJ)
          102  +	copy /Y $@ $(LSMDIR)\$@

Changes to ext/lsm1/lsm-test/lsmtest.h.

     3      3   #define __WRAPPER_INT_H_
     4      4   
     5      5   #include "lsmtest_tdb.h"
     6      6   #include "sqlite3.h"
     7      7   #include "lsm.h"
     8      8   
     9      9   #include <assert.h>
           10  +#include <stdarg.h>
    10     11   #include <stdlib.h>
    11     12   #include <string.h>
    12     13   #include <stdio.h>
           14  +#ifndef _WIN32
           15  +# include <unistd.h>
           16  +#endif
           17  +#include <sys/types.h>
           18  +#include <sys/stat.h>
           19  +#include <fcntl.h>
           20  +#include <ctype.h>
           21  +#include <stdlib.h>
           22  +#include <errno.h>
    13     23   
    14     24   #ifdef __cplusplus
    15     25   extern "C" {
    16     26   #endif
    17     27   
    18     28   #ifdef _WIN32
    19     29   # include "windows.h"
    20     30   # define gettimeofday win32GetTimeOfDay
    21     31   # define F_OK  (0)
    22     32   # define sleep(sec) Sleep(1000 * (sec))
    23         -# define usleep(usec) Sleep((usec) / 1000)
           33  +# define usleep(usec) Sleep(((usec) + 999) / 1000)
    24     34   # ifdef _MSC_VER
    25     35   #  include <io.h>
    26     36   #  define snprintf _snprintf
    27     37   #  define fsync(fd) FlushFileBuffers((HANDLE)_get_osfhandle((fd)))
    28     38   #  define fdatasync(fd) FlushFileBuffers((HANDLE)_get_osfhandle((fd)))
    29     39   #  define __va_copy(dst,src) ((dst) = (src))
    30     40   #  define ftruncate(fd,sz) ((_chsize_s((fd), (sz))==0) ? 0 : -1)
................................................................................
    47     57   #define MIN(x,y) ((x)<(y) ? (x) : (y))
    48     58   #define MAX(x,y) ((x)>(y) ? (x) : (y))
    49     59   
    50     60   #define unused_parameter(x) (void)(x)
    51     61   
    52     62   #define TESTDB_DEFAULT_PAGE_SIZE   4096
    53     63   #define TESTDB_DEFAULT_CACHE_SIZE  2048
           64  +
           65  +#ifndef _O_BINARY
           66  +# define _O_BINARY (0)
           67  +#endif
    54     68   
    55     69   /*
    56     70   ** Ideally, these should be in wrapper.c. But they are here instead so that 
    57     71   ** they can be used by the C++ database wrappers in wrapper2.cc.
    58     72   */
    59     73   typedef struct DatabaseMethods DatabaseMethods;
    60     74   struct TestDb {

Changes to ext/lsm1/lsm-test/lsmtest6.c.

   196    196     int nScan,
   197    197     int *pRc
   198    198   ){
   199    199     if( *pRc==0 ){
   200    200       int rc;
   201    201       int iScan = 0;
   202    202       lsm_cursor *pCsr;
   203         -    int (*xAdvance)(lsm_cursor *);
          203  +    int (*xAdvance)(lsm_cursor *) = 0;
   204    204       
   205    205   
   206    206       rc = lsm_csr_open(pDb, &pCsr);
   207    207       testOomAssertRc(pOom, rc);
   208    208   
   209    209       if( rc==LSM_OK ){
   210    210         if( bReverse ){
................................................................................
   236    236       lsm_csr_close(pCsr);
   237    237       *pRc = rc;
   238    238     }
   239    239   }
   240    240   
   241    241   #define LSMTEST6_TESTDB "testdb.lsm" 
   242    242   
   243         -#ifndef _WIN32
   244         -# include <unistd.h>
   245         -#endif
   246         -#include <sys/types.h>
   247         -#include <sys/stat.h>
   248         -#include <fcntl.h>
   249         -
   250    243   void testDeleteLsmdb(const char *zFile){
   251    244     char *zLog = testMallocPrintf("%s-log", zFile);
   252    245     char *zShm = testMallocPrintf("%s-shm", zFile);
   253    246     unlink(zFile);
   254    247     unlink(zLog);
   255    248     unlink(zShm);
   256    249     testFree(zLog);
   257    250     testFree(zShm);
   258    251   }
   259    252   
   260         -static void copy_file(const char *zFrom, const char *zTo){
          253  +static void copy_file(const char *zFrom, const char *zTo, int isDatabase){
   261    254   
   262    255     if( access(zFrom, F_OK) ){
   263    256       unlink(zTo);
   264    257     }else{
   265    258       int fd1;
   266    259       int fd2;
   267    260       off_t sz;
   268    261       off_t i;
   269    262       struct stat buf;
   270    263       u8 *aBuf;
   271    264   
   272         -    fd1 = open(zFrom, O_RDONLY, 0644);
   273         -    fd2 = open(zTo, O_RDWR | O_CREAT, 0644);
          265  +    fd1 = open(zFrom, O_RDONLY | _O_BINARY, 0644);
          266  +    fd2 = open(zTo, O_RDWR | O_CREAT | _O_BINARY, 0644);
   274    267   
   275    268       fstat(fd1, &buf);
   276    269       sz = buf.st_size;
   277    270       ftruncate(fd2, sz);
   278    271   
   279    272       aBuf = testMalloc(4096);
   280    273       for(i=0; i<sz; i+=4096){
   281         -      int nByte = MIN(4096, sz - i);
          274  +      int bLockPage = isDatabase && i == 0;
          275  +      int nByte = MIN((bLockPage ? 4066 : 4096), sz - i);
          276  +      memset(aBuf, 0, 4096);
   282    277         read(fd1, aBuf, nByte);
   283    278         write(fd2, aBuf, nByte);
          279  +      if( bLockPage ){
          280  +        lseek(fd1, 4096, SEEK_SET);
          281  +        lseek(fd2, 4096, SEEK_SET);
          282  +      }
   284    283       }
   285    284       testFree(aBuf);
   286    285   
   287    286       close(fd1);
   288    287       close(fd2);
   289    288     }
   290    289   }
................................................................................
   294    293     char *zLog2 = testMallocPrintf("%s-log", zTo);
   295    294     char *zShm1 = testMallocPrintf("%s-shm", zFrom);
   296    295     char *zShm2 = testMallocPrintf("%s-shm", zTo);
   297    296   
   298    297     unlink(zShm2);
   299    298     unlink(zLog2);
   300    299     unlink(zTo);
   301         -  copy_file(zFrom, zTo);
   302         -  copy_file(zLog1, zLog2);
   303         -  copy_file(zShm1, zShm2);
          300  +  copy_file(zFrom, zTo, 1);
          301  +  copy_file(zLog1, zLog2, 0);
          302  +  copy_file(zShm1, zShm2, 0);
   304    303   
   305    304     testFree(zLog1); testFree(zLog2); testFree(zShm1); testFree(zShm2);
   306    305   }
   307    306   
   308    307   /*
   309    308   ** File zFile is the path to a database. This function makes backups
   310    309   ** of the database file and its log as follows:
................................................................................
   318    317   void testSaveDb(const char *zFile, const char *zAux){
   319    318     char *zLog = testMallocPrintf("%s-%s", zFile, zAux);
   320    319     char *zFileSave = testMallocPrintf("%s-save", zFile);
   321    320     char *zLogSave = testMallocPrintf("%s-%s-save", zFile, zAux);
   322    321   
   323    322     unlink(zFileSave);
   324    323     unlink(zLogSave);
   325         -  copy_file(zFile, zFileSave);
   326         -  copy_file(zLog, zLogSave);
          324  +  copy_file(zFile, zFileSave, 1);
          325  +  copy_file(zLog, zLogSave, 0);
   327    326   
   328    327     testFree(zLog); testFree(zFileSave); testFree(zLogSave);
   329    328   }
   330    329   
   331    330   /*
   332    331   ** File zFile is the path to a database. This function restores
   333    332   ** a backup of the database made by a previous call to testSaveDb().
................................................................................
   337    336   **     cp $(zFile)-save-$(zAux) $(zFile)-$(zAux)
   338    337   */
   339    338   void testRestoreDb(const char *zFile, const char *zAux){
   340    339     char *zLog = testMallocPrintf("%s-%s", zFile, zAux);
   341    340     char *zFileSave = testMallocPrintf("%s-save", zFile);
   342    341     char *zLogSave = testMallocPrintf("%s-%s-save", zFile, zAux);
   343    342   
   344         -  copy_file(zFileSave, zFile);
   345         -  copy_file(zLogSave, zLog);
          343  +  copy_file(zFileSave, zFile, 1);
          344  +  copy_file(zLogSave, zLog, 0);
   346    345   
   347    346     testFree(zLog); testFree(zFileSave); testFree(zLogSave);
   348    347   }
   349    348   
   350    349   
   351    350   static int lsmWriteStr(lsm_db *pDb, const char *zKey, const char *zVal){
   352    351     int nKey = strlen(zKey);
   353    352     int nVal = strlen(zVal);
   354    353     return lsm_insert(pDb, (void *)zKey, nKey, (void *)zVal, nVal);
   355    354   }
   356    355   
   357         -static void setup_delete_db(){
          356  +static void setup_delete_db(void){
   358    357     testDeleteLsmdb(LSMTEST6_TESTDB);
   359    358   }
   360    359   
   361    360   /*
   362    361   ** Create a small database. With the following content:
   363    362   **
   364    363   **    "one"   -> "one"
................................................................................
   366    365   **    "three" -> "nine"
   367    366   **    "four"  -> "sixteen"
   368    367   **    "five"  -> "twentyfive"
   369    368   **    "six"   -> "thirtysix"
   370    369   **    "seven" -> "fourtynine"
   371    370   **    "eight" -> "sixtyfour"
   372    371   */
   373         -static void setup_populate_db(){
          372  +static void setup_populate_db(void){
   374    373     const char *azStr[] = {
   375    374       "one",   "one",
   376    375       "two",   "four",
   377    376       "three", "nine",
   378    377       "four",  "sixteen",
   379    378       "five",  "twentyfive",
   380    379       "six",   "thirtysix",
................................................................................
   408    407   ** Set up a database file with the following properties:
   409    408   **
   410    409   **   * Page size is 1024 bytes.
   411    410   **   * Block size is 64 KB.
   412    411   **   * Contains 5000 key-value pairs starting at 0 from the
   413    412   **     datasource returned getDatasource().
   414    413   */
   415         -static void setup_populate_db2(){
          414  +static void setup_populate_db2(void){
   416    415     Datasource *pData;
   417    416     int ii;
   418    417     int rc;
   419    418     int nBlocksize = 64*1024;
   420    419     int nPagesize = 1024;
   421    420     int nWritebuffer = 4*1024;
   422    421     lsm_db *pDb;

Changes to ext/lsm1/lsm-test/lsmtest8.c.

    81     81     }
    82     82   }
    83     83   
    84     84   #include <stdio.h>
    85     85   void testReadFile(const char *zFile, int iOff, void *pOut, int nByte, int *pRc){
    86     86     if( *pRc==0 ){
    87     87       FILE *fd;
    88         -    fd = fopen(zFile, "r");
           88  +    fd = fopen(zFile, "rb");
    89     89       if( fd==0 ){
    90     90         *pRc = 1;
    91     91       }else{
    92     92         if( 0!=fseek(fd, iOff, SEEK_SET) ){
    93     93           *pRc = 1;
    94     94         }else{
    95         -        if( nByte!=fread(pOut, 1, nByte, fd) ){
           95  +        assert( nByte>=0 );
           96  +        if( (size_t)nByte!=fread(pOut, 1, nByte, fd) ){
    96     97             *pRc = 1;
    97     98           }
    98     99         }
    99    100         fclose(fd);
   100    101       }
   101    102     }
   102    103   }
................................................................................
   106    107     int iOff, 
   107    108     void *pOut, 
   108    109     int nByte, 
   109    110     int *pRc
   110    111   ){
   111    112     if( *pRc==0 ){
   112    113       FILE *fd;
   113         -    fd = fopen(zFile, "r+");
          114  +    fd = fopen(zFile, "r+b");
   114    115       if( fd==0 ){
   115    116         *pRc = 1;
   116    117       }else{
   117    118         if( 0!=fseek(fd, iOff, SEEK_SET) ){
   118    119           *pRc = 1;
   119    120         }else{
   120         -        if( nByte!=fwrite(pOut, 1, nByte, fd) ){
          121  +        assert( nByte>=0 );
          122  +        if( (size_t)nByte!=fwrite(pOut, 1, nByte, fd) ){
   121    123             *pRc = 1;
   122    124           }
   123    125         }
   124    126         fclose(fd);
   125    127       }
   126    128     }
   127    129   }
................................................................................
   151    153   **    1) Check that the checksum of the database is zCksum. 
   152    154   **    2) Write a few keys to the database. Then delete the same keys. 
   153    155   **    3) Check that the checksum is zCksum.
   154    156   **    4) Flush the db to disk and run a checkpoint. 
   155    157   **    5) Check once more that the checksum is still zCksum.
   156    158   */
   157    159   static void doLiveRecovery(const char *zDb, const char *zCksum, int *pRc){
   158         -  const DatasourceDefn defn = {TEST_DATASOURCE_RANDOM, 20, 25, 100, 500};
   159         -  Datasource *pData;
   160         -  const char *zCopy = "testcopy.lsm";
   161         -  char zCksum2[TEST_CKSUM_BYTES];
   162         -  TestDb *pDb = 0;
   163         -  int rc;
          160  +  if( *pRc==LSM_OK ){
          161  +    const DatasourceDefn defn = {TEST_DATASOURCE_RANDOM, 20, 25, 100, 500};
          162  +    Datasource *pData;
          163  +    const char *zCopy = "testcopy.lsm";
          164  +    char zCksum2[TEST_CKSUM_BYTES];
          165  +    TestDb *pDb = 0;
          166  +    int rc;
   164    167   
   165         -  pData = testDatasourceNew(&defn);
          168  +    pData = testDatasourceNew(&defn);
   166    169   
   167         -  testCopyLsmdb(zDb, zCopy);
   168         -  rc = tdb_lsm_open("test_no_recovery=1", zCopy, 0, &pDb);
   169         -  if( rc==0 ){
   170         -    ShmHeader *pHdr;
   171         -    lsm_db *db;
   172         -    testCksumDatabase(pDb, zCksum2);
   173         -    testCompareStr(zCksum, zCksum2, &rc);
   174         -
   175         -    testWriteDatasourceRange(pDb, pData, 1, 10, &rc);
   176         -    testDeleteDatasourceRange(pDb, pData, 1, 10, &rc);
   177         -
   178         -    /* Test that the two tree-headers are now consistent. */
   179         -    pHdr = getShmHeader(zCopy);
   180         -    if( rc==0 && memcmp(&pHdr->hdr1, &pHdr->hdr2, sizeof(pHdr->hdr1)) ){
   181         -      rc = 1;
   182         -    }
   183         -    testFree(pHdr);
   184         -
          170  +    testCopyLsmdb(zDb, zCopy);
          171  +    rc = tdb_lsm_open("test_no_recovery=1", zCopy, 0, &pDb);
   185    172       if( rc==0 ){
   186         -      int nBuf = 64;
   187         -      db = tdb_lsm(pDb);
   188         -      lsm_config(db, LSM_CONFIG_AUTOFLUSH, &nBuf);
   189         -      lsm_begin(db, 1);
   190         -      lsm_commit(db, 0);
   191         -      rc = lsm_work(db, 0, 0, 0);
          173  +      ShmHeader *pHdr;
          174  +      lsm_db *db;
          175  +      testCksumDatabase(pDb, zCksum2);
          176  +      testCompareStr(zCksum, zCksum2, &rc);
          177  +
          178  +      testWriteDatasourceRange(pDb, pData, 1, 10, &rc);
          179  +      testDeleteDatasourceRange(pDb, pData, 1, 10, &rc);
          180  +
          181  +      /* Test that the two tree-headers are now consistent. */
          182  +      pHdr = getShmHeader(zCopy);
          183  +      if( rc==0 && memcmp(&pHdr->hdr1, &pHdr->hdr2, sizeof(pHdr->hdr1)) ){
          184  +        rc = 1;
          185  +      }
          186  +      testFree(pHdr);
          187  +
          188  +      if( rc==0 ){
          189  +        int nBuf = 64;
          190  +        db = tdb_lsm(pDb);
          191  +        lsm_config(db, LSM_CONFIG_AUTOFLUSH, &nBuf);
          192  +        lsm_begin(db, 1);
          193  +        lsm_commit(db, 0);
          194  +        rc = lsm_work(db, 0, 0, 0);
          195  +      }
          196  +
          197  +      testCksumDatabase(pDb, zCksum2);
          198  +      testCompareStr(zCksum, zCksum2, &rc);
   192    199       }
   193    200   
   194         -    testCksumDatabase(pDb, zCksum2);
   195         -    testCompareStr(zCksum, zCksum2, &rc);
          201  +    testDatasourceFree(pData);
          202  +    testClose(&pDb);
          203  +    testDeleteLsmdb(zCopy);
          204  +    *pRc = rc;
   196    205     }
   197         -
   198         -  testDatasourceFree(pData);
   199         -  testClose(&pDb);
   200         -  testDeleteLsmdb(zCopy);
   201         -  *pRc = rc;
   202    206   }
   203    207   
   204    208   static void doWriterCrash1(int *pRc){
   205    209     const int nWrite = 2000;
   206    210     const int nStep = 10;
   207    211     const int iWriteStart = 20000;
   208    212     int rc = 0;

Changes to ext/lsm1/lsm-test/lsmtest_io.c.

    51     51   **     $ echo "2M@6M 1492K@4M S 4096@4K S" | lsmtest io testfile.db 4096 
    52     52   **     3544K written in 127 ms
    53     53   **
    54     54   */
    55     55   
    56     56   #include "lsmtest.h"
    57     57   
    58         -#include <sys/types.h>
    59         -#include <sys/stat.h>
    60         -#include <fcntl.h>
    61         -#ifndef _WIN32
    62         -# include <unistd.h>
    63         -#endif
    64         -#include <ctype.h>
    65         -
    66     58   typedef struct IoContext IoContext;
    67     59   
    68     60   struct IoContext {
    69     61     int fd;
    70     62     int nWrite;
    71     63   };
    72     64   
................................................................................
   151    143     if( safe_isdigit(c) ){
   152    144       i64 iOff = 0;
   153    145       int nByte = 0;
   154    146       int rc = 0;
   155    147       int nPg;
   156    148       int iPg;
   157    149   
   158         -    nByte = getNextSize(z, &z, &rc);
          150  +    nByte = (int)getNextSize(z, &z, &rc);
   159    151       if( rc || *z!='@' ) goto bad_command;
   160    152       z++;
   161    153       iOff = getNextSize(z, &z, &rc);
   162    154       if( rc || (safe_isspace(*z)==0 && *z!='\0') ) goto bad_command;
   163    155       if( pzOut ) *pzOut = z;
   164    156   
   165    157       nPg = (nByte+pgsz-1) / pgsz;
   166         -    lseek(pCtx->fd, iOff, SEEK_SET);
          158  +    lseek(pCtx->fd, (off_t)iOff, SEEK_SET);
   167    159       for(iPg=0; iPg<nPg; iPg++){
   168    160         write(pCtx->fd, aData, pgsz);
   169    161       }
   170    162       pCtx->nWrite += nByte/1024;
   171    163   
   172    164       return 0;
   173    165     }
................................................................................
   215    207     if( nArg<2 ){
   216    208       testPrintUsage("FILE PGSZ ?CMD-1 ...?");
   217    209       return -1;
   218    210     }
   219    211     zFile = azArg[0];
   220    212     zPgsz = azArg[1];
   221    213   
   222         -  pgsz = getNextSize(zPgsz, 0, &rc);
          214  +  pgsz = (int)getNextSize(zPgsz, 0, &rc);
   223    215     if( pgsz<=0 ){
   224    216       testPrintError("Ridiculous page size: %d", pgsz);
   225    217       return -1;
   226    218     }
   227    219     aData = malloc(pgsz);
   228    220     memset(aData, 0x77, pgsz);
   229    221   
   230         -  ctx.fd = open(zFile, O_RDWR|O_CREAT, 0644);
          222  +  ctx.fd = open(zFile, O_RDWR|O_CREAT|_O_BINARY, 0644);
   231    223     if( ctx.fd<0 ){
   232    224       perror("open: ");
   233    225       return -1;
   234    226     }
   235    227   
   236    228     if( nArg==2 ){
   237    229       readStdin(&zStdin);

Changes to ext/lsm1/lsm-test/lsmtest_main.c.

     1      1   
     2         -#include "stdarg.h"
     3      2   #include "lsmtest.h"
     4         -#include "stdio.h"
     5         -#include "assert.h"
     6         -#include "string.h"
     7         -#include "stdlib.h"
     8         -
     9      3   #include <sqlite3.h>
    10         -
    11         -#ifndef _WIN32
    12         -# include <unistd.h>
    13         -#endif
    14         -#include <sys/types.h>
    15         -#include <sys/stat.h>
    16         -#include <fcntl.h>
    17         -#include <errno.h>
    18         -
    19      4   
    20      5   void test_failed(){ 
    21      6     assert( 0 );
    22      7     return; 
    23      8   }
    24      9   
    25     10   #define testSetError(rc) testSetErrorFunc(rc, pRc, __FILE__, __LINE__)
................................................................................
   913    898         pLog = fopen("/tmp/speed.log", "w");
   914    899         tdb_lsm_write_hook(pDb, do_speed_write_hook2, (void *)pLog);
   915    900   #endif
   916    901     
   917    902         testTimeInit();
   918    903         for(i=0; i<nRow; i+=nStep){
   919    904           int iStep;
   920         -        int nWrite1, nWrite2;
          905  +        int nWrite1 = 0, nWrite2 = 0;
   921    906           testCaseProgress(i, nRow, testCaseNDot(), &iDot);
   922    907           if( pLsm ) lsm_info(pLsm, LSM_INFO_NWRITE, &nWrite1);
   923    908           for(iStep=0; iStep<nStep; iStep++){
   924    909             u32 aKey[4];                  /* 16-byte key */
   925    910             u32 aVal[25];                 /* 100 byte value */
   926    911             testPrngArray(i+iStep, aKey, ArraySize(aKey));
   927    912             testPrngArray(i+iStep, aVal, ArraySize(aVal));
................................................................................
  1235   1220     }else{
  1236   1221       printf("Sync after each %d blocks.\n", nSync);
  1237   1222     }
  1238   1223   
  1239   1224     printf("Preparing file... ");
  1240   1225     fflush(stdout);
  1241   1226     unlink("writer.out");
  1242         -  fd = open("writer.out", O_RDWR|O_CREAT, 0664);
         1227  +  fd = open("writer.out", O_RDWR|O_CREAT|_O_BINARY, 0664);
  1243   1228     if( fd<0 ){
  1244   1229       testPrintError("open(): %d - %s\n", errno, strerror(errno));
  1245   1230       return -1;
  1246   1231     }
  1247   1232     testTimeInit();
  1248   1233     for(i=0; i<nBlock; i++){
  1249   1234       int iPg;

Changes to ext/lsm1/lsm-test/lsmtest_mem.c.

    41     41   
    42     42     /* Mutex to protect pFirst and aHash */
    43     43     void (*xEnterMutex)(TmGlobal*); /* Call this to enter the mutex */
    44     44     void (*xLeaveMutex)(TmGlobal*); /* Call this to leave mutex */
    45     45     void (*xDelMutex)(TmGlobal*);   /* Call this to delete mutex */
    46     46     void *pMutex;                   /* Mutex handle */
    47     47   
    48         -  void *xSaveMalloc;
    49         -  void *xSaveRealloc;
    50         -  void *xSaveFree;
           48  +  void *(*xSaveMalloc)(void *, size_t);
           49  +  void *(*xSaveRealloc)(void *, void *, size_t);
           50  +  void (*xSaveFree)(void *, void *);
    51     51   
    52     52     /* OOM injection scheduling. If nCountdown is greater than zero when a 
    53     53     ** malloc attempt is made, it is decremented. If this means nCountdown 
    54     54     ** transitions from 1 to 0, then the allocation fails. If bPersist is true 
    55     55     ** when this happens, nCountdown is then incremented back to 1 (so that the 
    56     56     ** next attempt fails too).  
    57     57     */
................................................................................
   179    179   
   180    180   static void tmFree(TmGlobal *pTm, void *p){
   181    181     if( p ){
   182    182       TmBlockHdr *pHdr;
   183    183       u8 *pUser = (u8 *)p;
   184    184   
   185    185       tmEnterMutex(pTm);
   186         -    pHdr = (TmBlockHdr *)&pUser[BLOCK_HDR_SIZE * -1];
          186  +    pHdr = (TmBlockHdr *)(pUser - BLOCK_HDR_SIZE);
   187    187       assert( pHdr->iForeGuard==FOREGUARD );
   188    188       assert( 0==memcmp(&pUser[pHdr->nByte], &rearguard, 4) );
   189    189   
   190    190       if( pHdr->pPrev ){
   191    191         assert( pHdr->pPrev->pNext==pHdr );
   192    192         pHdr->pPrev->pNext = pHdr->pNext;
   193    193       }else{
................................................................................
   214    214   static void *tmRealloc(TmGlobal *pTm, void *p, int nByte){
   215    215     void *pNew;
   216    216   
   217    217     pNew = tmMalloc(pTm, nByte);
   218    218     if( pNew && p ){
   219    219       TmBlockHdr *pHdr;
   220    220       u8 *pUser = (u8 *)p;
   221         -    pHdr = (TmBlockHdr *)&pUser[BLOCK_HDR_SIZE * -1];
          221  +    pHdr = (TmBlockHdr *)(pUser - BLOCK_HDR_SIZE);
   222    222       memcpy(pNew, p, MIN(nByte, pHdr->nByte));
   223    223       tmFree(pTm, p);
   224    224     }
   225    225     return pNew;
   226    226   }
   227    227   
   228    228   static void tmMallocOom(
................................................................................
   351    351     pMutex->pEnv = pEnv;
   352    352     pEnv->xMutexStatic(pEnv, LSM_MUTEX_HEAP, &pMutex->pMutex);
   353    353     pGlobal->xEnterMutex = tmLsmMutexEnter;
   354    354     pGlobal->xLeaveMutex = tmLsmMutexLeave;
   355    355     pGlobal->xDelMutex = tmLsmMutexDel;
   356    356     pGlobal->pMutex = (void *)pMutex;
   357    357   
   358         -  pGlobal->xSaveMalloc = (void *)pEnv->xMalloc;
   359         -  pGlobal->xSaveRealloc = (void *)pEnv->xRealloc;
   360         -  pGlobal->xSaveFree = (void *)pEnv->xFree;
          358  +  pGlobal->xSaveMalloc = pEnv->xMalloc;
          359  +  pGlobal->xSaveRealloc = pEnv->xRealloc;
          360  +  pGlobal->xSaveFree = pEnv->xFree;
   361    361   
   362    362     /* Set up pEnv to the use the new TmGlobal */
   363    363     pEnv->pMemCtx = (void *)pGlobal;
   364    364     pEnv->xMalloc = tmLsmEnvMalloc;
   365    365     pEnv->xRealloc = tmLsmEnvRealloc;
   366    366     pEnv->xFree = tmLsmEnvFree;
   367    367   }

Changes to ext/lsm1/lsm-test/lsmtest_tdb.c.

   763    763       nLib++;
   764    764     }
   765    765     zSpec = &zLib[nLib];
   766    766     while( *zSpec==' ' ) zSpec++;
   767    767     if( *zSpec=='\0' ) zSpec = 0;
   768    768   
   769    769     for(i=0; i<ArraySize(aLib); i++){
   770         -    if( strlen(aLib[i].zName)==nLib && 0==memcmp(zLib, aLib[i].zName, nLib) ){
          770  +    if( (int)strlen(aLib[i].zName)==nLib
          771  +        && 0==memcmp(zLib, aLib[i].zName, nLib) ){
   771    772         rc = aLib[i].xOpen(zSpec, (zDb ? zDb : aLib[i].zDefaultDb), bClear, ppDb);
   772    773         if( rc==0 ){
   773    774           (*ppDb)->zLibrary = aLib[i].zName;
   774    775         }
   775    776         break;
   776    777       }
   777    778     }

Changes to ext/lsm1/lsm-test/lsmtest_tdb3.c.

   195    195     lsm_env *pRealEnv = tdb_lsm_env();
   196    196     LsmFile *p = (LsmFile *)pFile;
   197    197     LsmDb *pDb = p->pDb;
   198    198   
   199    199     if( pDb->bCrashed ) return LSM_IOERR;
   200    200   
   201    201     if( pDb->bPrepareCrash ){
   202         -    FileData *pData = &pDb->aFile[p->bLog];
          202  +    FileData *pData2 = &pDb->aFile[p->bLog];
   203    203       int iFirst;                 
   204    204       int iLast;
   205    205       int iSector;
   206    206   
   207         -    iFirst = (iOff / pDb->szSector);
   208         -    iLast =  ((iOff + nData - 1) / pDb->szSector);
          207  +    iFirst = (int)(iOff / pDb->szSector);
          208  +    iLast =  (int)((iOff + nData - 1) / pDb->szSector);
   209    209   
   210         -    if( pData->nSector<(iLast+1) ){
          210  +    if( pData2->nSector<(iLast+1) ){
   211    211         int nNew = ( ((iLast + 1) + 63) / 64 ) * 64;
   212    212         assert( nNew>iLast );
   213         -      pData->aSector = (FileSector *)testRealloc(
   214         -          pData->aSector, nNew*sizeof(FileSector)
          213  +      pData2->aSector = (FileSector *)testRealloc(
          214  +          pData2->aSector, nNew*sizeof(FileSector)
   215    215         );
   216         -      memset(&pData->aSector[pData->nSector], 
   217         -          0, (nNew - pData->nSector) * sizeof(FileSector)
          216  +      memset(&pData2->aSector[pData2->nSector], 
          217  +          0, (nNew - pData2->nSector) * sizeof(FileSector)
   218    218         );
   219         -      pData->nSector = nNew;
          219  +      pData2->nSector = nNew;
   220    220       }
   221    221   
   222    222       for(iSector=iFirst; iSector<=iLast; iSector++){
   223         -      if( pData->aSector[iSector].aOld==0 ){
          223  +      if( pData2->aSector[iSector].aOld==0 ){
   224    224           u8 *aOld = (u8 *)testMalloc(pDb->szSector);
   225    225           pRealEnv->xRead(
   226    226               p->pReal, (lsm_i64)iSector*pDb->szSector, aOld, pDb->szSector
   227    227           );
   228         -        pData->aSector[iSector].aOld = aOld;
          228  +        pData2->aSector[iSector].aOld = aOld;
   229    229         }
   230    230       }
   231    231     }
   232    232   
   233    233     if( pDb->xWriteHook ){
   234    234       int rc;
   235    235       int nUs;
................................................................................
   543    543   static int waitOnWorker(LsmDb *pDb){
   544    544     int rc;
   545    545     int nLimit = -1;
   546    546     int nSleep = 0;
   547    547   
   548    548     rc = lsm_config(pDb->db, LSM_CONFIG_AUTOFLUSH, &nLimit);
   549    549     do {
   550         -    int nOld, nNew, rc;
   551         -    rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &nOld, &nNew);
   552         -    if( rc!=LSM_OK ) return rc;
          550  +    int nOld, nNew, rc2;
          551  +    rc2 = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &nOld, &nNew);
          552  +    if( rc2!=LSM_OK ) return rc2;
   553    553       if( nOld==0 || nNew<(nLimit/2) ) break;
   554    554   #ifdef LSM_MUTEX_PTHREADS
   555    555       mt_signal_worker(pDb, 0);
   556    556   #endif
   557    557       usleep(5000);
   558    558       nSleep += 5;
   559    559     }while( 1 );
................................................................................
   884    884     testPrintError("syntax error at: \"%s\"\n", z);
   885    885     return 1;
   886    886   }
   887    887   
   888    888   int tdb_lsm_config_str(TestDb *pDb, const char *zStr){
   889    889     int rc = 0;
   890    890     if( tdb_lsm(pDb) ){
          891  +#ifdef LSM_MUTEX_PTHREADS
   891    892       int i;
          893  +#endif
   892    894       LsmDb *pLsm = (LsmDb *)pDb;
   893    895   
   894    896       rc = test_lsm_config_str(pLsm, pLsm->db, 0, zStr, 0);
   895    897   #ifdef LSM_MUTEX_PTHREADS
   896    898       for(i=0; rc==0 && i<pLsm->nWorker; i++){
   897    899         rc = test_lsm_config_str(0, pLsm->aWorker[i].pWorker, 1, zStr, 0);
   898    900       }

Changes to ext/lsm1/lsm-test/lsmtest_win32.c.

     8      8   #define TICKS_UNIX_EPOCH      (116444736000000000LL)
     9      9   
    10     10   int win32GetTimeOfDay(
    11     11     struct timeval *tp,
    12     12     void *tzp
    13     13   ){
    14     14     FILETIME fileTime;
    15         -  ULARGE_INTEGER largeInteger;
    16     15     ULONGLONG ticks;
           16  +  ULONGLONG unixTicks;
    17     17   
    18     18     unused_parameter(tzp);
    19     19     memset(&fileTime, 0, sizeof(FILETIME));
    20     20     GetSystemTimeAsFileTime(&fileTime);
    21         -  memset(&largeInteger, 0, sizeof(ULARGE_INTEGER));
    22         -  largeInteger.LowPart = fileTime.dwLowDateTime;
    23         -  largeInteger.HighPart = fileTime.dwHighDateTime;
    24         -  ticks = largeInteger.QuadPart - TICKS_UNIX_EPOCH;
    25         -  tp->tv_sec = (long)(ticks / TICKS_PER_SECOND);
    26         -  ticks -= ((ULONGLONG)tp->tv_sec * TICKS_PER_SECOND);
    27         -  tp->tv_usec = (long)(ticks / TICKS_PER_MICROSECOND);
           21  +  ticks = (ULONGLONG)fileTime.dwHighDateTime << 32;
           22  +  ticks |= (ULONGLONG)fileTime.dwLowDateTime;
           23  +  unixTicks = ticks - TICKS_UNIX_EPOCH;
           24  +  tp->tv_sec = (long)(unixTicks / TICKS_PER_SECOND);
           25  +  unixTicks -= ((ULONGLONG)tp->tv_sec * TICKS_PER_SECOND);
           26  +  tp->tv_usec = (long)(unixTicks / TICKS_PER_MICROSECOND);
           27  +
    28     28     return 0;
    29     29   }
    30     30   #endif

Changes to ext/lsm1/lsmInt.h.

   585    585     u32 nWrite;                     /* Total number of pages written to disk */
   586    586   };
   587    587   #define LSM_INITIAL_SNAPSHOT_ID 11
   588    588   
   589    589   /*
   590    590   ** Functions from file "lsm_ckpt.c".
   591    591   */
   592         -int lsmCheckpointWrite(lsm_db *, int, u32 *);
          592  +int lsmCheckpointWrite(lsm_db *, u32 *);
   593    593   int lsmCheckpointLevels(lsm_db *, int, void **, int *);
   594    594   int lsmCheckpointLoadLevels(lsm_db *pDb, void *pVal, int nVal);
   595    595   
   596    596   int lsmCheckpointRecover(lsm_db *);
   597    597   int lsmCheckpointDeserialize(lsm_db *, int, u32 *, Snapshot **);
   598    598   
   599    599   int lsmCheckpointLoadWorker(lsm_db *pDb);
................................................................................
   691    691   /**************************************************************************
   692    692   ** Start of functions from "lsm_file.c".
   693    693   */
   694    694   int lsmFsOpen(lsm_db *, const char *, int);
   695    695   int lsmFsOpenLog(lsm_db *, int *);
   696    696   void lsmFsCloseLog(lsm_db *);
   697    697   void lsmFsClose(FileSystem *);
          698  +
          699  +int lsmFsUnmap(FileSystem *);
   698    700   
   699    701   int lsmFsConfigure(lsm_db *db);
   700    702   
   701    703   int lsmFsBlockSize(FileSystem *);
   702    704   void lsmFsSetBlockSize(FileSystem *, int);
   703    705   int lsmFsMoveBlock(FileSystem *pFS, Segment *pSeg, int iTo, int iFrom);
   704    706   

Changes to ext/lsm1/lsm_ckpt.c.

   218    218   **
   219    219   ** The value of the nCkpt parameter includes the two checksum values at
   220    220   ** the end of the checkpoint. They are not used as inputs to the checksum 
   221    221   ** calculation. The checksum is based on the array of (nCkpt-2) integers
   222    222   ** at aCkpt[].
   223    223   */
   224    224   static void ckptChecksum(u32 *aCkpt, u32 nCkpt, u32 *piCksum1, u32 *piCksum2){
   225         -  int i;
          225  +  u32 i;
   226    226     u32 cksum1 = 1;
   227    227     u32 cksum2 = 2;
   228    228   
   229    229     if( nCkpt % 2 ){
   230    230       cksum1 += aCkpt[nCkpt-3] & 0x0000FFFF;
   231    231       cksum2 += aCkpt[nCkpt-3] & 0xFFFF0000;
   232    232     }
................................................................................
   507    507     Segment *pSegment               /* Populate this structure */
   508    508   ){
   509    509     assert( pSegment->iFirst==0 && pSegment->iLastPg==0 );
   510    510     assert( pSegment->nSize==0 && pSegment->iRoot==0 );
   511    511     pSegment->iFirst = ckptGobble64(aIn, piIn);
   512    512     pSegment->iLastPg = ckptGobble64(aIn, piIn);
   513    513     pSegment->iRoot = ckptGobble64(aIn, piIn);
   514         -  pSegment->nSize = ckptGobble64(aIn, piIn);
          514  +  pSegment->nSize = (int)ckptGobble64(aIn, piIn);
   515    515     assert( pSegment->iFirst );
   516    516   }
   517    517   
   518    518   static int ckptSetupMerge(lsm_db *pDb, u32 *aInt, int *piIn, Level *pLevel){
   519    519     Merge *pMerge;                  /* Allocated Merge object */
   520    520     int nInput;                     /* Number of input segments in merge */
   521    521     int iIn = *piIn;                /* Next value to read from aInt[] */
................................................................................
  1013   1013       if( rc==LSM_OK && bInclFreelist ){
  1014   1014         nFree = aCkpt[iIn++];
  1015   1015         if( nFree ){
  1016   1016           pNew->freelist.aEntry = (FreelistEntry *)lsmMallocZeroRc(
  1017   1017               pDb->pEnv, sizeof(FreelistEntry)*nFree, &rc
  1018   1018           );
  1019   1019           if( rc==LSM_OK ){
  1020         -          int i;
  1021         -          for(i=0; i<nFree; i++){
  1022         -            FreelistEntry *p = &pNew->freelist.aEntry[i];
         1020  +          int j;
         1021  +          for(j=0; j<nFree; j++){
         1022  +            FreelistEntry *p = &pNew->freelist.aEntry[j];
  1023   1023               p->iBlk = aCkpt[iIn++];
  1024   1024               p->iId = ((i64)(aCkpt[iIn])<<32) + aCkpt[iIn+1];
  1025   1025               iIn += 2;
  1026   1026             }
  1027   1027             pNew->freelist.nEntry = pNew->freelist.nAlloc = nFree;
  1028   1028           }
  1029   1029         }

Changes to ext/lsm1/lsm_file.c.

   536    536     return ((i64)iReal*pFS->nPagesize <= pFS->nMapLimit);
   537    537   }
   538    538   
   539    539   /*
   540    540   ** Given that there are currently nHash slots in the hash table, return 
   541    541   ** the hash key for file iFile, page iPg.
   542    542   */
   543         -static int fsHashKey(int nHash, int iPg){
          543  +static int fsHashKey(int nHash, Pgno iPg){
   544    544     return (iPg % nHash);
   545    545   }
   546    546   
   547    547   /*
   548    548   ** This is a helper function for lsmFsOpen(). It opens a single file on
   549    549   ** disk (either the database or log file).
   550    550   */
................................................................................
   918    918   
   919    919   /*
   920    920   ** Return the block number of the block that page iPg is located on. 
   921    921   ** Blocks are numbered starting from 1.
   922    922   */
   923    923   static int fsPageToBlock(FileSystem *pFS, Pgno iPg){
   924    924     if( pFS->pCompress ){
   925         -    return (iPg / pFS->nBlocksize) + 1;
          925  +    return (int)((iPg / pFS->nBlocksize) + 1);
   926    926     }else{
   927         -    return 1 + ((iPg-1) / (pFS->nBlocksize / pFS->nPagesize));
          927  +    return (int)(1 + ((iPg-1) / (pFS->nBlocksize / pFS->nPagesize)));
   928    928     }
   929    929   }
   930    930   
   931    931   /*
   932    932   ** Return true if page iPg is the last page on its block.
   933    933   **
   934    934   ** This function is only called in non-compressed database mode.
................................................................................
  1145   1145           pFix->aData += iOff;
  1146   1146         }
  1147   1147         lsmSortedRemap(pFS->pDb);
  1148   1148       }
  1149   1149       *pRc = rc;
  1150   1150     }
  1151   1151   }
         1152  +
         1153  +/*
         1154  +** If it is mapped, unmap the database file.
         1155  +*/
         1156  +int lsmFsUnmap(FileSystem *pFS){
         1157  +  int rc = LSM_OK;
         1158  +  if( pFS ){
         1159  +    rc = lsmEnvRemap(pFS->pEnv, pFS->fdDb, -1, &pFS->pMap, &pFS->nMap);
         1160  +  }
         1161  +  return rc;
         1162  +}
  1152   1163   
  1153   1164   /*
  1154   1165   ** fsync() the database file.
  1155   1166   */
  1156   1167   int lsmFsSyncDb(FileSystem *pFS, int nBlock){
  1157   1168     return lsmEnvSync(pFS->pEnv, pFS->fdDb);
  1158   1169   }
................................................................................
  1282   1293     i64 iEob;                       /* End of block */
  1283   1294     int nRead;
  1284   1295     int rc;
  1285   1296   
  1286   1297     assert( pFS->pCompress );
  1287   1298   
  1288   1299     iEob = fsLastPageOnPagesBlock(pFS, iOff) + 1;
  1289         -  nRead = LSM_MIN(iEob - iOff, nData);
         1300  +  nRead = (int)LSM_MIN(iEob - iOff, nData);
  1290   1301   
  1291   1302     rc = lsmEnvRead(pFS->pEnv, pFS->fdDb, iOff, aData, nRead);
  1292   1303     if( rc==LSM_OK && nRead!=nData ){
  1293   1304       int iBlk;
  1294   1305   
  1295   1306       rc = fsBlockNext(pFS, pSeg, fsPageToBlock(pFS, iOff), &iBlk);
  1296   1307       if( rc==LSM_OK ){
................................................................................
  1718   1729   static int fsFreeBlock(
  1719   1730     FileSystem *pFS,                /* File system object */
  1720   1731     Snapshot *pSnapshot,            /* Worker snapshot */
  1721   1732     Segment *pIgnore,               /* Ignore this run when searching */
  1722   1733     int iBlk                        /* Block number of block to free */
  1723   1734   ){
  1724   1735     int rc = LSM_OK;                /* Return code */
  1725         -  int iFirst;                     /* First page on block iBlk */
  1726         -  int iLast;                      /* Last page on block iBlk */
         1736  +  Pgno iFirst;                    /* First page on block iBlk */
         1737  +  Pgno iLast;                     /* Last page on block iBlk */
  1727   1738     Level *pLevel;                  /* Used to iterate through levels */
  1728   1739   
  1729   1740     int iIn;                        /* Used to iterate through append points */
  1730   1741     int iOut = 0;                   /* Used to output append points */
  1731   1742     Pgno *aApp = pSnapshot->aiAppend;
  1732   1743   
  1733   1744     iFirst = fsFirstPageOnBlock(pFS, iBlk);
................................................................................
  1852   1863     int iBlk;
  1853   1864   
  1854   1865     assert( pRun->nSize>0 );
  1855   1866     assert( 0==fsSegmentRedirects(pFS, pRun) );
  1856   1867     assert( nPgno>0 && 0==fsPageRedirects(pFS, pRun, aPgno[0]) );
  1857   1868   
  1858   1869     iBlk = fsPageToBlock(pFS, pRun->iFirst);
  1859         -  pRun->nSize += (pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk));
         1870  +  pRun->nSize += (int)(pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk));
  1860   1871   
  1861   1872     while( rc==LSM_OK ){
  1862   1873       int iNext = 0;
  1863   1874       Pgno iFirst = firstOnBlock(pFS, iBlk, aPgno, nPgno);
  1864   1875       if( iFirst ){
  1865   1876         pRun->iFirst = iFirst;
  1866   1877         break;
  1867   1878       }
  1868   1879       rc = fsBlockNext(pFS, pRun, iBlk, &iNext);
  1869   1880       if( rc==LSM_OK ) rc = fsFreeBlock(pFS, pSnapshot, pRun, iBlk);
  1870         -    pRun->nSize -= (
         1881  +    pRun->nSize -= (int)(
  1871   1882           1 + fsLastPageOnBlock(pFS, iBlk) - fsFirstPageOnBlock(pFS, iBlk)
  1872   1883       );
  1873   1884       iBlk = iNext;
  1874   1885     }
  1875   1886   
  1876         -  pRun->nSize -= (pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk));
         1887  +  pRun->nSize -= (int)(pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk));
  1877   1888     assert( pRun->nSize>0 );
  1878   1889   }
  1879   1890   
  1880   1891   /*
  1881   1892   ** This function is only used in compressed database mode.
  1882   1893   **
  1883   1894   ** Argument iPg is the page number (byte offset) of a page within segment
................................................................................
  2083   2094     Snapshot *pSnapshot,
  2084   2095     Level *pLvl,
  2085   2096     int bDefer,
  2086   2097     Page **ppOut
  2087   2098   ){
  2088   2099     int rc = LSM_OK;
  2089   2100     Page *pPg = 0;
  2090         -  int iApp = 0;
  2091         -  int iNext = 0;
         2101  +  Pgno iApp = 0;
         2102  +  Pgno iNext = 0;
  2092   2103     Segment *p = &pLvl->lhs;
  2093         -  int iPrev = p->iLastPg;
         2104  +  Pgno iPrev = p->iLastPg;
  2094   2105   
  2095   2106     *ppOut = 0;
  2096   2107     assert( p->pRedirect==0 );
  2097   2108   
  2098   2109     if( pFS->pCompress || bDefer ){
  2099   2110       /* In compressed database mode the page is not assigned a page number
  2100   2111       ** or location in the database file at this point. This will be done
................................................................................
  2112   2123         pPg->nRef = 1;
  2113   2124         pFS->nOut++;
  2114   2125       }
  2115   2126     }else{
  2116   2127       if( iPrev==0 ){
  2117   2128         iApp = findAppendPoint(pFS, pLvl);
  2118   2129       }else if( fsIsLast(pFS, iPrev) ){
  2119         -      int iNext;
  2120         -      rc = fsBlockNext(pFS, 0, fsPageToBlock(pFS, iPrev), &iNext);
         2130  +      int iNext2;
         2131  +      rc = fsBlockNext(pFS, 0, fsPageToBlock(pFS, iPrev), &iNext2);
  2121   2132         if( rc!=LSM_OK ) return rc;
  2122         -      iApp = fsFirstPageOnBlock(pFS, iNext);
         2133  +      iApp = fsFirstPageOnBlock(pFS, iNext2);
  2123   2134       }else{
  2124   2135         iApp = iPrev + 1;
  2125   2136       }
  2126   2137   
  2127   2138       /* If this is the first page allocated, or if the page allocated is the
  2128   2139       ** last in the block, also allocate the next block here.  */
  2129   2140       if( iApp==0 || fsIsLast(pFS, iApp) ){
................................................................................
  2453   2464     int nData,                      /* Size of buffer aData[] in bytes */
  2454   2465     int *pRc                        /* IN/OUT: Error code */
  2455   2466   ){
  2456   2467     Pgno iRet = 0;
  2457   2468     int rc = *pRc;
  2458   2469     assert( pFS->pCompress );
  2459   2470     if( rc==LSM_OK ){
  2460         -    int nRem;
  2461         -    int nWrite;
         2471  +    int nRem = 0;
         2472  +    int nWrite = 0;
  2462   2473       Pgno iLastOnBlock;
  2463   2474       Pgno iApp = pSeg->iLastPg+1;
  2464   2475   
  2465   2476       /* If this is the first data written into the segment, find an append-point
  2466   2477       ** or allocate a new block.  */
  2467   2478       if( iApp==1 ){
  2468   2479         pSeg->iFirst = iApp = findAppendPoint(pFS, 0);
................................................................................
  2473   2484         }
  2474   2485       }
  2475   2486       iRet = iApp;
  2476   2487   
  2477   2488       /* Write as much data as is possible at iApp (usually all of it). */
  2478   2489       iLastOnBlock = fsLastPageOnPagesBlock(pFS, iApp);
  2479   2490       if( rc==LSM_OK ){
  2480         -      int nSpace = iLastOnBlock - iApp + 1;
         2491  +      int nSpace = (int)(iLastOnBlock - iApp + 1);
  2481   2492         nWrite = LSM_MIN(nData, nSpace);
  2482   2493         nRem = nData - nWrite;
  2483   2494         assert( nWrite>=0 );
  2484   2495         if( nWrite!=0 ){
  2485   2496           rc = lsmEnvWrite(pFS->pEnv, pFS->fdDb, iApp, aData, nWrite);
  2486   2497         }
  2487   2498         iApp += nWrite;
................................................................................
  2796   2807       Pgno iLast2;
  2797   2808       Pgno iLast = pSeg->iLastPg;     /* Current last page of segment */
  2798   2809       int nPad;                       /* Bytes of padding required */
  2799   2810       u8 aSz[3];
  2800   2811   
  2801   2812       iLast2 = (1 + iLast/pFS->szSector) * pFS->szSector - 1;
  2802   2813       assert( fsPageToBlock(pFS, iLast)==fsPageToBlock(pFS, iLast2) );
  2803         -    nPad = iLast2 - iLast;
         2814  +    nPad = (int)(iLast2 - iLast);
  2804   2815   
  2805   2816       if( iLast2>fsLastPageOnPagesBlock(pFS, iLast) ){
  2806   2817         nPad -= 4;
  2807   2818       }
  2808   2819       assert( nPad>=0 );
  2809   2820   
  2810   2821       if( nPad>=6 ){
................................................................................
  3253   3264       ** builds, this probably means the user is running an OOM injection test.
  3254   3265       ** Regardless, it will not be possible to run the integrity-check at this
  3255   3266       ** time, so assume the database is Ok and return non-zero. */
  3256   3267       return 1;
  3257   3268     }
  3258   3269   
  3259   3270     for(pLevel=pWorker->pLevel; pLevel; pLevel=pLevel->pNext){
  3260         -    int i;
         3271  +    int j;
  3261   3272       checkBlocks(pFS, &pLevel->lhs, (pLevel->nRight!=0), nBlock, aUsed);
  3262         -    for(i=0; i<pLevel->nRight; i++){
  3263         -      checkBlocks(pFS, &pLevel->aRhs[i], 0, nBlock, aUsed);
         3273  +    for(j=0; j<pLevel->nRight; j++){
         3274  +      checkBlocks(pFS, &pLevel->aRhs[j], 0, nBlock, aUsed);
  3264   3275       }
  3265   3276     }
  3266   3277   
  3267   3278     /* Mark all blocks in the free-list as used */
  3268   3279     ctx.aUsed = aUsed;
  3269   3280     ctx.nBlock = nBlock;
  3270   3281     rc = lsmWalkFreelist(pDb, 0, checkFreelistCb, (void *)&ctx);

Changes to ext/lsm1/lsm_log.c.

   541    541       if( nPad ){
   542    542         u8 aPad[7] = {0,0,0,0,0,0,0};
   543    543         nPad = 8-nPad;
   544    544         if( nPad==1 ){
   545    545           aPad[0] = LSM_LOG_PAD1;
   546    546         }else{
   547    547           aPad[0] = LSM_LOG_PAD2;
   548         -        aPad[1] = (nPad-2);
          548  +        aPad[1] = (u8)(nPad-2);
   549    549         }
   550    550         rc = lsmStringBinAppend(&pLog->buf, aPad, nPad);
   551    551         if( rc!=LSM_OK ) return rc;
   552    552       }
   553    553   
   554    554       /* Append the JUMP record to the buffer. Then flush the buffer to disk
   555    555       ** and update the checksums. The next write to the log file (assuming
................................................................................
   623    623       while( nPad ){
   624    624         if( nPad==1 ){
   625    625           pLog->buf.z[pLog->buf.n++] = LSM_LOG_PAD1;
   626    626           nPad = 0;
   627    627         }else{
   628    628           int n = LSM_MIN(200, nPad-2);
   629    629           pLog->buf.z[pLog->buf.n++] = LSM_LOG_PAD2;
   630         -        pLog->buf.z[pLog->buf.n++] = n;
          630  +        pLog->buf.z[pLog->buf.n++] = (char)n;
   631    631           nPad -= 2;
   632    632           memset(&pLog->buf.z[pLog->buf.n], 0x2B, n);
   633    633           pLog->buf.n += n;
   634    634           nPad -= n;
   635    635         }
   636    636       }
   637    637     }
   638    638   
   639    639     /* Make sure there is room in the log-buffer to add the CKSUM or COMMIT
   640    640     ** record. Then add the first byte of it.  */
   641    641     rc = lsmStringExtend(&pLog->buf, 9);
   642    642     if( rc!=LSM_OK ) return rc;
   643         -  pLog->buf.z[pLog->buf.n++] = eType;
          643  +  pLog->buf.z[pLog->buf.n++] = (char)eType;
   644    644     memset(&pLog->buf.z[pLog->buf.n], 0, 8);
   645    645   
   646    646     rc = logCksumAndFlush(pDb);
   647    647   
   648    648     /* If this is a commit and synchronous=full, sync the log to disk. */
   649    649     if( rc==LSM_OK && eType==LSM_LOG_COMMIT && pDb->eSafety==LSM_SAFETY_FULL ){
   650    650       rc = lsmFsSyncLog(pDb->pFS);
................................................................................
   768    768     LogWriter *pLog;
   769    769   
   770    770     if( pDb->bUseLog==0 ) return;
   771    771     pLog = pDb->pLogWriter;
   772    772   
   773    773     assert( pMark->iOff<=pLog->iOff+pLog->buf.n );
   774    774     if( (pMark->iOff & 0xFFFFFFF8)>=pLog->iOff ){
   775         -    pLog->buf.n = pMark->iOff - pLog->iOff;
          775  +    pLog->buf.n = (int)(pMark->iOff - pLog->iOff);
   776    776       pLog->iCksumBuf = (pLog->buf.n & 0xFFFFFFF8);
   777    777     }else{
   778    778       pLog->buf.n = pMark->nBuf;
   779    779       memcpy(pLog->buf.z, pMark->aBuf, pMark->nBuf);
   780    780       pLog->iCksumBuf = 0;
   781    781       pLog->iOff = pMark->iOff - pMark->nBuf;
   782    782     }

Changes to ext/lsm1/lsm_shared.c.

    93     93   #else
    94     94   # define assertNotInFreelist(x,y)
    95     95   #endif
    96     96   
    97     97   /*
    98     98   ** Append an entry to the free-list. If (iId==-1), this is a delete.
    99     99   */
   100         -int freelistAppend(lsm_db *db, int iBlk, i64 iId){
          100  +int freelistAppend(lsm_db *db, u32 iBlk, i64 iId){
   101    101     lsm_env *pEnv = db->pEnv;
   102    102     Freelist *p;
   103    103     int i; 
   104    104   
   105    105     assert( iId==-1 || iId>=0 );
   106    106     p = db->bUseFreelist ? db->pFreelist : &db->pWorker->freelist;
   107    107   
................................................................................
   226    226       ** contains data. */
   227    227       ctx.nBlock = pDb->pWorker->nBlock;
   228    228       ctx.iInUse = -1;
   229    229       rc = lsmWalkFreelist(pDb, 1, dbTruncateCb, (void *)&ctx);
   230    230   
   231    231       /* If the last block that contains data is not already the last block in
   232    232       ** the database file, truncate the database file so that it is. */
   233         -    if( rc==LSM_OK && ctx.nBlock!=pDb->pWorker->nBlock ){
          233  +    if( rc==LSM_OK ){
   234    234         rc = lsmFsTruncateDb(
   235    235             pDb->pFS, (i64)ctx.nBlock*lsmFsBlockSize(pDb->pFS)
   236    236         );
   237    237       }
   238    238     }
   239    239   
   240    240     lsmFreeSnapshot(pDb->pEnv, pDb->pWorker);
................................................................................
   248    248     if( pDb->bReadonly ){
   249    249       lsmShmLock(pDb, LSM_LOCK_DMS3, LSM_LOCK_UNLOCK, 0);
   250    250     }else{
   251    251       /* Block for an exclusive lock on DMS1. This lock serializes all calls
   252    252       ** to doDbConnect() and doDbDisconnect() across all processes.  */
   253    253       rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1);
   254    254       if( rc==LSM_OK ){
          255  +
          256  +      lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
   255    257   
   256    258         /* Try an exclusive lock on DMS2. If successful, this is the last
   257    259         ** connection to the database. In this case flush the contents of the
   258    260         ** in-memory tree to disk and write a checkpoint.  */
   259    261         rc = lsmShmTestLock(pDb, LSM_LOCK_DMS2, 1, LSM_LOCK_EXCL);
   260    262         if( rc==LSM_OK ){
   261    263           rc = lsmShmTestLock(pDb, LSM_LOCK_CHECKPOINTER, 1, LSM_LOCK_EXCL);
................................................................................
   287    289               bReadonly = 1;
   288    290               rc = LSM_OK;
   289    291             }
   290    292           }
   291    293   
   292    294           /* Write a checkpoint to disk. */
   293    295           if( rc==LSM_OK ){
   294         -          rc = lsmCheckpointWrite(pDb, (bReadonly==0), 0);
          296  +          rc = lsmCheckpointWrite(pDb, 0);
   295    297           }
   296    298   
   297    299           /* If the checkpoint was written successfully, delete the log file
   298    300           ** and, if possible, truncate the database file.  */
   299    301           if( rc==LSM_OK ){
   300    302             int bRotrans = 0;
   301    303             Database *p = pDb->pDatabase;
................................................................................
   306    308             if( rc==LSM_OK && bRotrans==0 ){
   307    309               lsmFsCloseAndDeleteLog(pDb->pFS);
   308    310             }
   309    311   
   310    312             /* The database may only be truncated if there exist no read-only
   311    313             ** clients - either connected or running rotrans transactions. */
   312    314             if( bReadonly==0 && bRotrans==0 ){
          315  +            lsmFsUnmap(pDb->pFS);
   313    316               dbTruncateFile(pDb);
   314    317               if( p->pFile && p->bMultiProc ){
   315    318                 lsmEnvShmUnmap(pDb->pEnv, p->pFile, 1);
   316    319               }
   317    320             }
   318    321           }
   319    322         }
................................................................................
   320    323       }
   321    324   
   322    325       if( pDb->iRwclient>=0 ){
   323    326         lsmShmLock(pDb, LSM_LOCK_RWCLIENT(pDb->iRwclient), LSM_LOCK_UNLOCK, 0);
   324    327         pDb->iRwclient = -1;
   325    328       }
   326    329   
   327         -    lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0);
   328    330       lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0);
   329    331     }
   330    332     pDb->pShmhdr = 0;
   331    333   }
   332    334   
   333    335   static int doDbConnect(lsm_db *pDb){
   334    336     const int nUsMax = 100000;      /* Max value for nUs */
................................................................................
   473    475         ** attempt to take the exclusive lock on DMS2.  */
   474    476         if( rc==LSM_OK ){
   475    477           int bReadonly = (pDb->bReadonly && pDb->bMultiProc);
   476    478           rc = dbOpenSharedFd(pDb->pEnv, p, bReadonly);
   477    479         }
   478    480   
   479    481         if( rc==LSM_OK && p->bMultiProc==0 ){
          482  +        /* Hold an exclusive lock DMS1 while grabbing DMS2. This ensures
          483  +        ** that any ongoing call to doDbDisconnect() (even one in another
          484  +        ** process) is finished before proceeding.  */
   480    485           assert( p->bReadonly==0 );
   481         -        rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL);
          486  +        rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_EXCL);
          487  +        if( rc==LSM_OK ){
          488  +          rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL);
          489  +          lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK);
          490  +        }
   482    491         }
   483    492   
   484    493         if( rc==LSM_OK ){
   485    494           p->pDbNext = gShared.pDatabase;
   486    495           gShared.pDatabase = p;
   487    496         }else{
   488    497           freeDatabase(pEnv, p);
................................................................................
   556    565     if( p ){
   557    566       lsm_db **ppDb;
   558    567   
   559    568       if( pDb->pShmhdr ){
   560    569         doDbDisconnect(pDb);
   561    570       }
   562    571   
          572  +    lsmFsUnmap(pDb->pFS);
   563    573       lsmMutexEnter(pDb->pEnv, p->pClientMutex);
   564    574       for(ppDb=&p->pConn; *ppDb!=pDb; ppDb=&((*ppDb)->pNext));
   565    575       *ppDb = pDb->pNext;
   566    576       dbDeferClose(pDb);
   567    577       lsmMutexLeave(pDb->pEnv, p->pClientMutex);
   568    578   
   569    579       enterGlobalMutex(pDb->pEnv);
................................................................................
   627    637   */
   628    638   static int walkFreelistCb(void *pCtx, int iBlk, i64 iSnapshot){
   629    639     WalkFreelistCtx *p = (WalkFreelistCtx *)pCtx;
   630    640     const int iDir = (p->bReverse ? -1 : 1);
   631    641     Freelist *pFree = p->pFreelist;
   632    642   
   633    643     assert( p->bDone==0 );
          644  +  assert( iBlk>=0 );
   634    645     if( pFree ){
   635    646       while( (p->iFree < pFree->nEntry) && p->iFree>=0 ){
   636    647         FreelistEntry *pEntry = &pFree->aEntry[p->iFree];
   637         -      if( (p->bReverse==0 && pEntry->iBlk>iBlk)
   638         -       || (p->bReverse!=0 && pEntry->iBlk<iBlk)
          648  +      if( (p->bReverse==0 && pEntry->iBlk>(u32)iBlk)
          649  +       || (p->bReverse!=0 && pEntry->iBlk<(u32)iBlk)
   639    650         ){
   640    651           break;
   641    652         }else{
   642    653           p->iFree += iDir;
   643    654           if( pEntry->iId>=0 
   644    655               && p->xUsr(p->pUsrctx, pEntry->iBlk, pEntry->iId) 
   645    656             ){
   646    657             p->bDone = 1;
   647    658             return 1;
   648    659           }
   649         -        if( pEntry->iBlk==iBlk ) return 0;
          660  +        if( pEntry->iBlk==(u32)iBlk ) return 0;
   650    661         }
   651    662       }
   652    663     }
   653    664   
   654    665     if( p->xUsr(p->pUsrctx, iBlk, iSnapshot) ){
   655    666       p->bDone = 1;
   656    667       return 1;
................................................................................
   901    912   ** database itself.
   902    913   **
   903    914   ** The WORKER lock must not be held when this is called. This is because
   904    915   ** this function may indirectly call fsync(). And the WORKER lock should
   905    916   ** not be held that long (in case it is required by a client flushing an
   906    917   ** in-memory tree to disk).
   907    918   */
   908         -int lsmCheckpointWrite(lsm_db *pDb, int bTruncate, u32 *pnWrite){
          919  +int lsmCheckpointWrite(lsm_db *pDb, u32 *pnWrite){
   909    920     int rc;                         /* Return Code */
   910    921     u32 nWrite = 0;
   911    922   
   912    923     assert( pDb->pWorker==0 );
   913    924     assert( 1 || pDb->pClient==0 );
   914    925     assert( lsmShmAssertLock(pDb, LSM_LOCK_WORKER, LSM_LOCK_UNLOCK) );
   915    926   
................................................................................
   925    936       /* Check if this checkpoint has already been written to the database
   926    937       ** file. If so, set variable bDone to true.  */
   927    938       if( pShm->iMetaPage ){
   928    939         MetaPage *pPg;              /* Meta page */
   929    940         u8 *aData;                  /* Meta-page data buffer */
   930    941         int nData;                  /* Size of aData[] in bytes */
   931    942         i64 iCkpt;                  /* Id of checkpoint just loaded */
   932         -      i64 iDisk;                  /* Id of checkpoint already stored in db */
          943  +      i64 iDisk = 0;              /* Id of checkpoint already stored in db */
   933    944         iCkpt = lsmCheckpointId(pDb->aSnapshot, 0);
   934    945         rc = lsmFsMetaPageGet(pDb->pFS, 0, pShm->iMetaPage, &pPg);
   935    946         if( rc==LSM_OK ){
   936    947           aData = lsmFsMetaPageData(pPg, &nData);
   937    948           iDisk = lsmCheckpointId((u32 *)aData, 1);
   938    949           nWrite = lsmCheckpointNWrite((u32 *)aData, 1);
   939    950           lsmFsMetaPageRelease(pPg);
................................................................................
   956    967         }
   957    968   #ifdef LSM_LOG_WORK
   958    969         lsmLogMessage(pDb, 0, "finish checkpoint %d", 
   959    970             (int)lsmCheckpointId(pDb->aSnapshot, 0)
   960    971         );
   961    972   #endif
   962    973       }
   963         -
   964         -    if( rc==LSM_OK && bTruncate && nBlock>0 ){
   965         -      rc = lsmFsTruncateDb(pDb->pFS, (i64)nBlock*lsmFsBlockSize(pDb->pFS));
   966         -    }
   967    974     }
   968    975   
   969    976     lsmShmLock(pDb, LSM_LOCK_CHECKPOINTER, LSM_LOCK_UNLOCK, 0);
   970    977     if( pnWrite && rc==LSM_OK ) *pnWrite = nWrite;
   971    978     return rc;
   972    979   }
   973    980   
................................................................................
  1743   1750     for(i=iLock; i<(iLock+nLock); i++){
  1744   1751       mask |= ((u64)1 << (iLock-1));
  1745   1752       if( eOp==LSM_LOCK_EXCL ) mask |= ((u64)1 << (iLock+32-1));
  1746   1753     }
  1747   1754   
  1748   1755     lsmMutexEnter(db->pEnv, p->pClientMutex);
  1749   1756     for(pIter=p->pConn; pIter; pIter=pIter->pNext){
  1750         -    if( pIter!=db && (pIter->mLock & mask) ) break;
         1757  +    if( pIter!=db && (pIter->mLock & mask) ){
         1758  +      assert( pIter!=db );
         1759  +      break;
         1760  +    }
  1751   1761     }
  1752   1762   
  1753   1763     if( pIter ){
  1754   1764       rc = LSM_BUSY;
  1755   1765     }else if( p->bMultiProc ){
  1756   1766       rc = lsmEnvTestLock(db->pEnv, p->pFile, iLock, nLock, eOp);
  1757   1767     }
................................................................................
  1871   1881   ** follows:
  1872   1882   **
  1873   1883   **   (eOp==LSM_LOCK_UNLOCK) -> true if db has no lock on iLock
  1874   1884   **   (eOp==LSM_LOCK_SHARED) -> true if db has at least a SHARED lock on iLock.
  1875   1885   **   (eOp==LSM_LOCK_EXCL)   -> true if db has an EXCLUSIVE lock on iLock.
  1876   1886   */
  1877   1887   int lsmShmAssertLock(lsm_db *db, int iLock, int eOp){
  1878         -  int ret;
         1888  +  int ret = 0;
  1879   1889     int eHave;
  1880   1890   
  1881   1891     assert( iLock>=1 && iLock<=LSM_LOCK_READER(LSM_LOCK_NREADER-1) );
  1882   1892     assert( iLock<=16 );
  1883   1893     assert( eOp==LSM_LOCK_UNLOCK || eOp==LSM_LOCK_SHARED || eOp==LSM_LOCK_EXCL );
  1884   1894   
  1885   1895     eHave = shmLockType(db, iLock);
................................................................................
  1950   1960   
  1951   1961   int lsm_checkpoint(lsm_db *pDb, int *pnKB){
  1952   1962     int rc;                         /* Return code */
  1953   1963     u32 nWrite = 0;                 /* Number of pages checkpointed */
  1954   1964   
  1955   1965     /* Attempt the checkpoint. If successful, nWrite is set to the number of
  1956   1966     ** pages written between this and the previous checkpoint.  */
  1957         -  rc = lsmCheckpointWrite(pDb, 0, &nWrite);
         1967  +  rc = lsmCheckpointWrite(pDb, &nWrite);
  1958   1968   
  1959   1969     /* If required, calculate the output variable (KB of data checkpointed). 
  1960   1970     ** Set it to zero if an error occured.  */
  1961   1971     if( pnKB ){
  1962   1972       int nKB = 0;
  1963   1973       if( rc==LSM_OK && nWrite ){
  1964   1974         nKB = (((i64)nWrite * lsmFsPageSize(pDb->pFS)) + 1023) / 1024;
  1965   1975       }
  1966   1976       *pnKB = nKB;
  1967   1977     }
  1968   1978   
  1969   1979     return rc;
  1970   1980   }

Changes to ext/lsm1/lsm_sorted.c.

   658    658   }
   659    659   
   660    660   static int btreeCursorPtr(u8 *aData, int nData, int iCell){
   661    661     int nCell;
   662    662   
   663    663     nCell = pageGetNRec(aData, nData);
   664    664     if( iCell>=nCell ){
   665         -    return pageGetPtr(aData, nData);
          665  +    return (int)pageGetPtr(aData, nData);
   666    666     }
   667         -  return pageGetRecordPtr(aData, nData, iCell);
          667  +  return (int)pageGetRecordPtr(aData, nData, iCell);
   668    668   }
   669    669   
   670    670   static int btreeCursorNext(BtreeCursor *pCsr){
   671    671     int rc = LSM_OK;
   672    672   
   673    673     BtreePg *pPg = &pCsr->aPg[pCsr->iPg];
   674    674     int nCell; 
................................................................................
   747    747   }
   748    748   
   749    749   static int btreeCursorFirst(BtreeCursor *pCsr){
   750    750     int rc;
   751    751   
   752    752     Page *pPg = 0;
   753    753     FileSystem *pFS = pCsr->pFS;
   754         -  int iPg = pCsr->pSeg->iRoot;
          754  +  int iPg = (int)pCsr->pSeg->iRoot;
   755    755   
   756    756     do {
   757    757       rc = lsmFsDbPageGet(pFS, pCsr->pSeg, iPg, &pPg);
   758    758       assert( (rc==LSM_OK)==(pPg!=0) );
   759    759       if( rc==LSM_OK ){
   760    760         u8 *aData;
   761    761         int nData;
................................................................................
   775    775           }
   776    776         }
   777    777   
   778    778         if( rc==LSM_OK ){
   779    779           assert( pCsr->aPg[pCsr->nDepth].iCell==0 );
   780    780           pCsr->aPg[pCsr->nDepth].pPage = pPg;
   781    781           pCsr->nDepth++;
   782         -        iPg = pageGetRecordPtr(aData, nData, 0);
          782  +        iPg = (int)pageGetRecordPtr(aData, nData, 0);
   783    783         }
   784    784       }
   785    785     }while( rc==LSM_OK );
   786    786     lsmFsPageRelease(pPg);
   787    787     pCsr->iPg = pCsr->nDepth-1;
   788    788   
   789    789     if( rc==LSM_OK && pCsr->nDepth ){
................................................................................
   867    867       /* Populate any other aPg[] array entries */
   868    868       if( rc==LSM_OK && nDepth>1 ){
   869    869         Blob blob = {0,0,0};
   870    870         void *pSeek;
   871    871         int nSeek;
   872    872         int iTopicSeek;
   873    873         int iPg = 0;
   874         -      int iLoad = pSeg->iRoot;
          874  +      int iLoad = (int)pSeg->iRoot;
   875    875         Page *pPg = pCsr->aPg[nDepth-1].pPage;
   876    876    
   877    877         if( pageObjGetNRec(pPg)==0 ){
   878    878           /* This can happen when pPg is the right-most leaf in the b-tree.
   879    879           ** In this case, set the iTopicSeek/pSeek/nSeek key to a value
   880    880           ** greater than any real key.  */
   881    881           assert( iCell==-1 );
................................................................................
   886    886           Pgno dummy;
   887    887           rc = pageGetBtreeKey(pSeg, pPg,
   888    888               0, &dummy, &iTopicSeek, &pSeek, &nSeek, &pCsr->blob
   889    889           );
   890    890         }
   891    891   
   892    892         do {
   893         -        Page *pPg;
   894         -        rc = lsmFsDbPageGet(pCsr->pFS, pSeg, iLoad, &pPg);
   895         -        assert( rc==LSM_OK || pPg==0 );
          893  +        Page *pPg2;
          894  +        rc = lsmFsDbPageGet(pCsr->pFS, pSeg, iLoad, &pPg2);
          895  +        assert( rc==LSM_OK || pPg2==0 );
   896    896           if( rc==LSM_OK ){
   897    897             u8 *aData;                  /* Buffer containing page data */
   898    898             int nData;                  /* Size of aData[] in bytes */
   899    899             int iMin;
   900    900             int iMax;
   901         -          int iCell;
          901  +          int iCell2;
   902    902   
   903         -          aData = fsPageData(pPg, &nData);
          903  +          aData = fsPageData(pPg2, &nData);
   904    904             assert( (pageGetFlags(aData, nData) & SEGMENT_BTREE_FLAG) );
   905    905   
   906         -          iLoad = pageGetPtr(aData, nData);
   907         -          iCell = pageGetNRec(aData, nData); 
   908         -          iMax = iCell-1;
          906  +          iLoad = (int)pageGetPtr(aData, nData);
          907  +          iCell2 = pageGetNRec(aData, nData); 
          908  +          iMax = iCell2-1;
   909    909             iMin = 0;
   910    910   
   911    911             while( iMax>=iMin ){
   912    912               int iTry = (iMin+iMax)/2;
   913    913               void *pKey; int nKey;         /* Key for cell iTry */
   914    914               int iTopic;                   /* Topic for key pKeyT/nKeyT */
   915    915               Pgno iPtr;                    /* Pointer for cell iTry */
   916    916               int res;                      /* (pSeek - pKeyT) */
   917    917   
   918    918               rc = pageGetBtreeKey(
   919         -                pSeg, pPg, iTry, &iPtr, &iTopic, &pKey, &nKey, &blob
          919  +                pSeg, pPg2, iTry, &iPtr, &iTopic, &pKey, &nKey, &blob
   920    920               );
   921    921               if( rc!=LSM_OK ) break;
   922    922   
   923    923               res = sortedKeyCompare(
   924    924                   xCmp, iTopicSeek, pSeek, nSeek, iTopic, pKey, nKey
   925    925               );
   926    926               assert( res!=0 );
   927    927   
   928    928               if( res<0 ){
   929         -              iLoad = iPtr;
   930         -              iCell = iTry;
          929  +              iLoad = (int)iPtr;
          930  +              iCell2 = iTry;
   931    931                 iMax = iTry-1;
   932    932               }else{
   933    933                 iMin = iTry+1;
   934    934               }
   935    935             }
   936    936   
   937         -          pCsr->aPg[iPg].pPage = pPg;
   938         -          pCsr->aPg[iPg].iCell = iCell;
          937  +          pCsr->aPg[iPg].pPage = pPg2;
          938  +          pCsr->aPg[iPg].iCell = iCell2;
   939    939             iPg++;
   940    940             assert( iPg!=nDepth-1 
   941    941                  || lsmFsRedirectPage(pCsr->pFS, pSeg->pRedirect, iLoad)==iLeaf
   942    942             );
   943    943           }
   944    944         }while( rc==LSM_OK && iPg<(nDepth-1) );
   945    945         sortedBlobFree(&blob);
................................................................................
   997    997   
   998    998   static void segmentPtrSetPage(SegmentPtr *pPtr, Page *pNext){
   999    999     lsmFsPageRelease(pPtr->pPg);
  1000   1000     if( pNext ){
  1001   1001       int nData;
  1002   1002       u8 *aData = fsPageData(pNext, &nData);
  1003   1003       pPtr->nCell = pageGetNRec(aData, nData);
  1004         -    pPtr->flags = pageGetFlags(aData, nData);
         1004  +    pPtr->flags = (u16)pageGetFlags(aData, nData);
  1005   1005       pPtr->iPtr = pageGetPtr(aData, nData);
  1006   1006     }
  1007   1007     pPtr->pPg = pNext;
  1008   1008   }
  1009   1009   
  1010   1010   /*
  1011   1011   ** Load a new page into the SegmentPtr object pPtr.
................................................................................
  1633   1633     int iTopic,                     /* Key topic to seek to */
  1634   1634     void *pKey, int nKey,           /* Key to seek to */
  1635   1635     int eSeek,                      /* Search bias - see above */
  1636   1636     int *piPtr,                     /* OUT: FC pointer */
  1637   1637     int *pbStop
  1638   1638   ){
  1639   1639     int (*xCmp)(void *, int, void *, int) = pCsr->pDb->xCmp;
  1640         -  int res;                        /* Result of comparison operation */
         1640  +  int res = 0;                        /* Result of comparison operation */
  1641   1641     int rc = LSM_OK;
  1642   1642     int iMin;
  1643   1643     int iMax;
  1644   1644     Pgno iPtrOut = 0;
  1645   1645   
  1646   1646     /* If the current page contains an oversized entry, then there are no
  1647   1647     ** pointers to one or more of the subsequent pages in the sorted run.
................................................................................
  1755   1755       ){
  1756   1756         assert( eSeek!=LSM_SEEK_EQ );
  1757   1757         rc = segmentPtrAdvance(pCsr, pPtr, eSeek==LSM_SEEK_LE);
  1758   1758       }
  1759   1759     }
  1760   1760   
  1761   1761     assert( rc!=LSM_OK || assertSeekResult(pCsr,pPtr,iTopic,pKey,nKey,eSeek) );
  1762         -  *piPtr = iPtrOut;
         1762  +  *piPtr = (int)iPtrOut;
  1763   1763     return rc;
  1764   1764   }
  1765   1765   
  1766   1766   static int seekInBtree(
  1767   1767     MultiCursor *pCsr,              /* Multi-cursor object */
  1768   1768     Segment *pSeg,                  /* Seek within this segment */
  1769   1769     int iTopic,
................................................................................
  1773   1773   ){
  1774   1774     int i = 0;
  1775   1775     int rc;
  1776   1776     int iPg;
  1777   1777     Page *pPg = 0;
  1778   1778     Blob blob = {0, 0, 0};
  1779   1779   
  1780         -  iPg = pSeg->iRoot;
         1780  +  iPg = (int)pSeg->iRoot;
  1781   1781     do {
  1782   1782       Pgno *piFirst = 0;
  1783   1783       if( aPg ){
  1784   1784         aPg[i++] = iPg;
  1785   1785         piFirst = &aPg[i];
  1786   1786       }
  1787   1787   
................................................................................
  1795   1795         int nRec;
  1796   1796         int flags;
  1797   1797   
  1798   1798         aData = fsPageData(pPg, &nData);
  1799   1799         flags = pageGetFlags(aData, nData);
  1800   1800         if( (flags & SEGMENT_BTREE_FLAG)==0 ) break;
  1801   1801   
  1802         -      iPg = pageGetPtr(aData, nData);
         1802  +      iPg = (int)pageGetPtr(aData, nData);
  1803   1803         nRec = pageGetNRec(aData, nData);
  1804   1804   
  1805   1805         iMin = 0;
  1806   1806         iMax = nRec-1;
  1807   1807         while( iMax>=iMin ){
  1808   1808           int iTry = (iMin+iMax)/2;
  1809   1809           void *pKeyT; int nKeyT;       /* Key for cell iTry */
................................................................................
  1821   1821             i++;
  1822   1822           }
  1823   1823   
  1824   1824           res = sortedKeyCompare(
  1825   1825               pCsr->pDb->xCmp, iTopic, pKey, nKey, iTopicT, pKeyT, nKeyT
  1826   1826           );
  1827   1827           if( res<0 ){
  1828         -          iPg = iPtr;
         1828  +          iPg = (int)iPtr;
  1829   1829             iMax = iTry-1;
  1830   1830           }else{
  1831   1831             iMin = iTry+1;
  1832   1832           }
  1833   1833         }
  1834   1834         lsmFsPageRelease(pPg);
  1835   1835         pPg = 0;
................................................................................
  1862   1862     if( pPtr->pSeg->iRoot ){
  1863   1863       Page *pPg;
  1864   1864       assert( pPtr->pSeg->iRoot!=0 );
  1865   1865       rc = seekInBtree(pCsr, pPtr->pSeg, iTopic, pKey, nKey, 0, &pPg);
  1866   1866       if( rc==LSM_OK ) segmentPtrSetPage(pPtr, pPg);
  1867   1867     }else{
  1868   1868       if( iPtr==0 ){
  1869         -      iPtr = pPtr->pSeg->iFirst;
         1869  +      iPtr = (int)pPtr->pSeg->iFirst;
  1870   1870       }
  1871   1871       if( rc==LSM_OK ){
  1872   1872         rc = segmentPtrLoadPage(pCsr->pDb->pFS, pPtr, iPtr);
  1873   1873       }
  1874   1874     }
  1875   1875   
  1876   1876     if( rc==LSM_OK ){
................................................................................
  1919   1919     }
  1920   1920   
  1921   1921     /* If (res<0), then key pKey/nKey is smaller than the split-key (or this
  1922   1922     ** is not a composite level and there is no split-key). Search the 
  1923   1923     ** left-hand-side of the level in this case.  */
  1924   1924     if( res<0 ){
  1925   1925       int iPtr = 0;
  1926         -    if( nRhs==0 ) iPtr = *piPgno;
         1926  +    if( nRhs==0 ) iPtr = (int)*piPgno;
  1927   1927   
  1928   1928       rc = seekInSegment(
  1929   1929           pCsr, &aPtr[0], iTopic, pKey, nKey, iPtr, eSeek, &iOut, &bStop
  1930   1930       );
  1931   1931       if( rc==LSM_OK && nRhs>0 && eSeek==LSM_SEEK_GE && aPtr[0].pPg==0 ){
  1932   1932         res = 0;
  1933   1933       }
  1934   1934     }
  1935   1935     
  1936   1936     if( res>=0 ){
  1937   1937       int bHit = 0;                 /* True if at least one rhs is not EOF */
  1938         -    int iPtr = *piPgno;
         1938  +    int iPtr = (int)*piPgno;
  1939   1939       int i;
  1940   1940       for(i=1; rc==LSM_OK && i<=nRhs && bStop==0; i++){
  1941   1941         SegmentPtr *pPtr = &aPtr[i];
  1942   1942         iOut = 0;
  1943   1943         rc = seekInSegment(
  1944   1944             pCsr, pPtr, iTopic, pKey, nKey, iPtr, eSeek, &iOut, &bStop
  1945   1945         );
................................................................................
  2003   2003       case CURSOR_DATA_SYSTEM: {
  2004   2004         Snapshot *pWorker = pCsr->pDb->pWorker;
  2005   2005         if( pWorker && (pCsr->flags & CURSOR_FLUSH_FREELIST) ){
  2006   2006           int nEntry = pWorker->freelist.nEntry;
  2007   2007           if( pCsr->iFree < (nEntry*2) ){
  2008   2008             FreelistEntry *aEntry = pWorker->freelist.aEntry;
  2009   2009             int i = nEntry - 1 - (pCsr->iFree / 2);
  2010         -          u32 iKey = 0;
         2010  +          u32 iKey2 = 0;
  2011   2011   
  2012   2012             if( (pCsr->iFree % 2) ){
  2013   2013               eType = LSM_END_DELETE|LSM_SYSTEMKEY;
  2014         -            iKey = aEntry[i].iBlk-1;
         2014  +            iKey2 = aEntry[i].iBlk-1;
  2015   2015             }else if( aEntry[i].iId>=0 ){
  2016   2016               eType = LSM_INSERT|LSM_SYSTEMKEY;
  2017         -            iKey = aEntry[i].iBlk;
         2017  +            iKey2 = aEntry[i].iBlk;
  2018   2018   
  2019   2019               /* If the in-memory entry immediately before this one was a
  2020   2020                ** DELETE, and the block number is one greater than the current
  2021   2021                ** block number, mark this entry as an "end-delete-range". */
  2022         -            if( i<(nEntry-1) && aEntry[i+1].iBlk==iKey+1 && aEntry[i+1].iId<0 ){
         2022  +            if( i<(nEntry-1) && aEntry[i+1].iBlk==iKey2+1 && aEntry[i+1].iId<0 ){
  2023   2023                 eType |= LSM_END_DELETE;
  2024   2024               }
  2025   2025   
  2026   2026             }else{
  2027   2027               eType = LSM_START_DELETE|LSM_SYSTEMKEY;
  2028         -            iKey = aEntry[i].iBlk + 1;
         2028  +            iKey2 = aEntry[i].iBlk + 1;
  2029   2029             }
  2030   2030   
  2031   2031             /* If the in-memory entry immediately after this one is a
  2032   2032             ** DELETE, and the block number is one less than the current
  2033   2033             ** key, mark this entry as an "start-delete-range".  */
  2034         -          if( i>0 && aEntry[i-1].iBlk==iKey-1 && aEntry[i-1].iId<0 ){
         2034  +          if( i>0 && aEntry[i-1].iBlk==iKey2-1 && aEntry[i-1].iId<0 ){
  2035   2035               eType |= LSM_START_DELETE;
  2036   2036             }
  2037   2037   
  2038   2038             pKey = pCsr->pSystemVal;
  2039   2039             nKey = 4;
  2040         -          lsmPutU32(pKey, ~iKey);
         2040  +          lsmPutU32(pKey, ~iKey2);
  2041   2041           }
  2042   2042         }
  2043   2043         break;
  2044   2044       }
  2045   2045   
  2046   2046       default: {
  2047   2047         int iPtr = iKey - CURSOR_DATA_SEGMENT;
................................................................................
  2613   2613         rc = lsmMCursorLast(pCsr);
  2614   2614       }else{
  2615   2615         rc = lsmMCursorSeek(pCsr, 1, "", 0, LSM_SEEK_GE);
  2616   2616       }
  2617   2617   
  2618   2618       while( rc==LSM_OK && lsmMCursorValid(pCsr) && rtIsSystem(pCsr->eType) ){
  2619   2619         void *pKey; int nKey;
  2620         -      void *pVal; int nVal;
         2620  +      void *pVal = 0; int nVal = 0;
  2621   2621   
  2622   2622         rc = lsmMCursorKey(pCsr, &pKey, &nKey);
  2623   2623         if( rc==LSM_OK ) rc = lsmMCursorValue(pCsr, &pVal, &nVal);
  2624   2624         if( rc==LSM_OK && (nKey!=4 || nVal!=8) ) rc = LSM_CORRUPT_BKPT;
  2625   2625   
  2626   2626         if( rc==LSM_OK ){
  2627   2627           int iBlk;
................................................................................
  3471   3471     p = &pMW->hier;
  3472   3472   
  3473   3473     if( p->apHier==0 && pSeg->iRoot!=0 ){
  3474   3474       FileSystem *pFS = pMW->pDb->pFS;
  3475   3475       lsm_env *pEnv = pMW->pDb->pEnv;
  3476   3476       Page **apHier = 0;
  3477   3477       int nHier = 0;
  3478         -    int iPg = pSeg->iRoot;
         3478  +    int iPg = (int)pSeg->iRoot;
  3479   3479   
  3480   3480       do {
  3481   3481         Page *pPg = 0;
  3482   3482         u8 *aData;
  3483   3483         int nData;
  3484   3484         int flags;
  3485   3485   
................................................................................
  3497   3497             break;
  3498   3498           }
  3499   3499           apHier = apNew;
  3500   3500           memmove(&apHier[1], &apHier[0], sizeof(Page *) * nHier);
  3501   3501           nHier++;
  3502   3502   
  3503   3503           apHier[0] = pPg;
  3504         -        iPg = pageGetPtr(aData, nData);
         3504  +        iPg = (int)pageGetPtr(aData, nData);
  3505   3505         }else{
  3506   3506           lsmFsPageRelease(pPg);
  3507   3507           break;
  3508   3508         }
  3509   3509       }while( 1 );
  3510   3510   
  3511   3511       if( rc==LSM_OK ){
................................................................................
  3616   3616   
  3617   3617         /* If the key will fit on this page, break out of the loop here.
  3618   3618         ** The new entry will be written to page apHier[iLevel]. */
  3619   3619         pOld = p->apHier[iLevel];
  3620   3620         assert( lsmFsPageWritable(pOld) );
  3621   3621         aData = fsPageData(pOld, &nData);
  3622   3622         if( eType==0 ){
  3623         -        nByte = 2 + 1 + lsmVarintLen32(iPtr) + lsmVarintLen32(iKeyPg);
         3623  +        nByte = 2 + 1 + lsmVarintLen32((int)iPtr) + lsmVarintLen32((int)iKeyPg);
  3624   3624         }else{
  3625         -        nByte = 2 + 1 + lsmVarintLen32(iPtr) + lsmVarintLen32(nKey) + nKey;
         3625  +        nByte = 2 + 1 + lsmVarintLen32((int)iPtr) + lsmVarintLen32(nKey) + nKey;
  3626   3626         }
  3627   3627         nRec = pageGetNRec(aData, nData);
  3628   3628         nFree = SEGMENT_EOF(nData, nRec) - mergeWorkerPageOffset(aData, nData);
  3629   3629         if( nByte<=nFree ) break;
  3630   3630   
  3631   3631         /* Otherwise, this page is full. Set the right-hand-child pointer
  3632   3632         ** to iPtr and release it.  */
................................................................................
  3659   3659       }
  3660   3660     }
  3661   3661   
  3662   3662     /* Write the key into page apHier[iLevel]. */
  3663   3663     aData = fsPageData(p->apHier[iLevel], &nData);
  3664   3664     iOff = mergeWorkerPageOffset(aData, nData);
  3665   3665     nRec = pageGetNRec(aData, nData);
  3666         -  lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], iOff);
  3667         -  lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], nRec+1);
         3666  +  lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], (u16)iOff);
         3667  +  lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], (u16)(nRec+1));
  3668   3668     if( eType==0 ){
  3669   3669       aData[iOff++] = 0x00;
  3670         -    iOff += lsmVarintPut32(&aData[iOff], iPtr);
  3671         -    iOff += lsmVarintPut32(&aData[iOff], iKeyPg);
         3670  +    iOff += lsmVarintPut32(&aData[iOff], (int)iPtr);
         3671  +    iOff += lsmVarintPut32(&aData[iOff], (int)iKeyPg);
  3672   3672     }else{
  3673   3673       aData[iOff++] = eType;
  3674         -    iOff += lsmVarintPut32(&aData[iOff], iPtr);
         3674  +    iOff += lsmVarintPut32(&aData[iOff], (int)iPtr);
  3675   3675       iOff += lsmVarintPut32(&aData[iOff], nKey);
  3676   3676       memcpy(&aData[iOff], pKey, nKey);
  3677   3677     }
  3678   3678   
  3679   3679     return rc;
  3680   3680   }
  3681   3681   
................................................................................
  3914   3914     int iFPtr = 0;                  /* Pointer value read from footer of pPg */
  3915   3915     MultiCursor *pCsr = pMW->pCsr;
  3916   3916   
  3917   3917     assert( pMW->pPage==0 );
  3918   3918   
  3919   3919     if( pCsr->pBtCsr ){
  3920   3920       rc = LSM_OK;
  3921         -    iFPtr = pMW->pLevel->pNext->lhs.iFirst;
         3921  +    iFPtr = (int)pMW->pLevel->pNext->lhs.iFirst;
  3922   3922     }else if( pCsr->nPtr>0 ){
  3923   3923       Segment *pSeg;
  3924   3924       pSeg = pCsr->aPtr[pCsr->nPtr-1].pSeg;
  3925   3925       rc = lsmFsDbPageGet(pMW->pDb->pFS, pSeg, pSeg->iFirst, &pPg);
  3926   3926       if( rc==LSM_OK ){
  3927   3927         u8 *aData;                    /* Buffer for page pPg */
  3928   3928         int nData;                    /* Size of aData[] in bytes */
  3929   3929         aData = fsPageData(pPg, &nData);
  3930         -      iFPtr = pageGetPtr(aData, nData);
         3930  +      iFPtr = (int)pageGetPtr(aData, nData);
  3931   3931         lsmFsPageRelease(pPg);
  3932   3932       }
  3933   3933     }
  3934   3934   
  3935   3935     if( rc==LSM_OK ){
  3936   3936       rc = mergeWorkerNextPage(pMW, iFPtr);
  3937   3937       if( pCsr->pPrevMergePtr ) *pCsr->pPrevMergePtr = iFPtr;
................................................................................
  3949   3949     int iPtr                        /* Absolute value of page pointer, or 0 */
  3950   3950   ){
  3951   3951     int rc = LSM_OK;                /* Return code */
  3952   3952     Merge *pMerge;                  /* Persistent part of level merge state */
  3953   3953     int nHdr;                       /* Space required for this record header */
  3954   3954     Page *pPg;                      /* Page to write to */
  3955   3955     u8 *aData;                      /* Data buffer for page pWriter->pPage */
  3956         -  int nData;                      /* Size of buffer aData[] in bytes */
  3957         -  int nRec;                       /* Number of records on page pPg */
  3958         -  int iFPtr;                      /* Value of pointer in footer of pPg */
         3956  +  int nData = 0;                  /* Size of buffer aData[] in bytes */
         3957  +  int nRec = 0;                   /* Number of records on page pPg */
         3958  +  int iFPtr = 0;                  /* Value of pointer in footer of pPg */
  3959   3959     int iRPtr = 0;                  /* Value of pointer written into record */
  3960         -  int iOff;                       /* Current write offset within page pPg */
         3960  +  int iOff = 0;                   /* Current write offset within page pPg */
  3961   3961     Segment *pSeg;                  /* Segment being written */
  3962   3962     int flags = 0;                  /* If != 0, flags value for page footer */
  3963   3963     int bFirst = 0;                 /* True for first key of output run */
  3964   3964   
  3965   3965     pMerge = pMW->pLevel->pMerge;    
  3966   3966     pSeg = &pMW->pLevel->lhs;
  3967   3967   
................................................................................
  3969   3969       rc = mergeWorkerFirstPage(pMW);
  3970   3970       bFirst = 1;
  3971   3971     }
  3972   3972     pPg = pMW->pPage;
  3973   3973     if( pPg ){
  3974   3974       aData = fsPageData(pPg, &nData);
  3975   3975       nRec = pageGetNRec(aData, nData);
  3976         -    iFPtr = pageGetPtr(aData, nData);
         3976  +    iFPtr = (int)pageGetPtr(aData, nData);
  3977   3977       iRPtr = iPtr - iFPtr;
  3978   3978     }
  3979   3979        
  3980   3980     /* Figure out how much space is required by the new record. The space
  3981   3981     ** required is divided into two sections: the header and the body. The
  3982   3982     ** header consists of the intial varint fields. The body are the blobs 
  3983   3983     ** of data that correspond to the key and value data. The entire header 
................................................................................
  3995   3995       nHdr = 1 + lsmVarintLen32(iRPtr) + lsmVarintLen32(nKey);
  3996   3996       if( rtIsWrite(eType) ) nHdr += lsmVarintLen32(nVal);
  3997   3997   
  3998   3998       /* If the entire header will not fit on page pPg, or if page pPg is 
  3999   3999       ** marked read-only, advance to the next page of the output run. */
  4000   4000       iOff = pMerge->iOutputOff;
  4001   4001       if( iOff<0 || pPg==0 || iOff+nHdr > SEGMENT_EOF(nData, nRec+1) ){
  4002         -      iFPtr = *pMW->pCsr->pPrevMergePtr;
         4002  +      iFPtr = (int)*pMW->pCsr->pPrevMergePtr;
  4003   4003         iRPtr = iPtr - iFPtr;
  4004   4004         iOff = 0;
  4005   4005         nRec = 0;
  4006   4006         rc = mergeWorkerNextPage(pMW, iFPtr);
  4007   4007         pPg = pMW->pPage;
  4008   4008       }
  4009   4009     }
................................................................................
  4029   4029     }
  4030   4030   
  4031   4031     /* Update the output segment */
  4032   4032     if( rc==LSM_OK ){
  4033   4033       aData = fsPageData(pPg, &nData);
  4034   4034   
  4035   4035       /* Update the page footer. */
  4036         -    lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], nRec+1);
  4037         -    lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], iOff);
  4038         -    if( flags ) lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], flags);
         4036  +    lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], (u16)(nRec+1));
         4037  +    lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], (u16)iOff);
         4038  +    if( flags ) lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], (u16)flags);
  4039   4039   
  4040   4040       /* Write the entry header into the current page. */
  4041         -    aData[iOff++] = eType;                                               /* 1 */
         4041  +    aData[iOff++] = (u8)eType;                                           /* 1 */
  4042   4042       iOff += lsmVarintPut32(&aData[iOff], iRPtr);                         /* 2 */
  4043   4043       iOff += lsmVarintPut32(&aData[iOff], nKey);                          /* 3 */
  4044   4044       if( rtIsWrite(eType) ) iOff += lsmVarintPut32(&aData[iOff], nVal);   /* 4 */
  4045   4045       pMerge->iOutputOff = iOff;
  4046   4046   
  4047   4047       /* Write the key and data into the segment. */
  4048   4048       assert( iFPtr==pageGetPtr(aData, nData) );
................................................................................
  4256   4256         rc = multiCursorGetVal(pCsr, iVal, &pVal, &nVal);
  4257   4257         if( pVal && rc==LSM_OK ){
  4258   4258           assert( nVal>=0 );
  4259   4259           rc = sortedBlobSet(pDb->pEnv, &pCsr->val, pVal, nVal);
  4260   4260           pVal = pCsr->val.pData;
  4261   4261         }
  4262   4262         if( rc==LSM_OK ){
  4263         -        rc = mergeWorkerWrite(pMW, eType, pKey, nKey, pVal, nVal, iPtr);
         4263  +        rc = mergeWorkerWrite(pMW, eType, pKey, nKey, pVal, nVal, (int)iPtr);
  4264   4264         }
  4265   4265       }
  4266   4266     }
  4267   4267   
  4268   4268     /* Advance the cursor to the next input record (assuming one exists). */
  4269   4269     assert( lsmMCursorValid(pMW->pCsr) );
  4270   4270     if( rc==LSM_OK ) rc = lsmMCursorNext(pMW->pCsr);
................................................................................
  4577   4577         int i;
  4578   4578         for(i=0; rc==LSM_OK && i<pCsr->nPtr; i++){
  4579   4579           MergeInput *pInput = &pMerge->aInput[i];
  4580   4580           if( pInput->iPg ){
  4581   4581             SegmentPtr *pPtr;
  4582   4582             assert( pCsr->aPtr[i].pPg==0 );
  4583   4583             pPtr = &pCsr->aPtr[i];
  4584         -          rc = segmentPtrLoadPage(pDb->pFS, pPtr, pInput->iPg);
         4584  +          rc = segmentPtrLoadPage(pDb->pFS, pPtr, (int)pInput->iPg);
  4585   4585             if( rc==LSM_OK && pPtr->nCell>0 ){
  4586   4586               rc = segmentPtrLoadCell(pPtr, pInput->iCell);
  4587   4587             }
  4588   4588           }
  4589   4589         }
  4590   4590   
  4591   4591         if( rc==LSM_OK && pCsr->pBtCsr ){
................................................................................
  5180   5180       u32 nUnsync;
  5181   5181       int nPgsz;
  5182   5182   
  5183   5183       lsmCheckpointSynced(pDb, 0, 0, &nSync);
  5184   5184       nUnsync = lsmCheckpointNWrite(pDb->pShmhdr->aSnap1, 0);
  5185   5185       nPgsz = lsmCheckpointPgsz(pDb->pShmhdr->aSnap1);
  5186   5186   
  5187         -    nMax = LSM_MIN(nMax, (pDb->nAutockpt/nPgsz) - (int)(nUnsync-nSync));
         5187  +    nMax = (int)LSM_MIN(nMax, (pDb->nAutockpt/nPgsz) - (int)(nUnsync-nSync));
  5188   5188       if( nMax<nRem ){
  5189   5189         bCkpt = 1;
  5190   5190         nRem = LSM_MAX(nMax, 0);
  5191   5191       }
  5192   5192     }
  5193   5193   
  5194   5194     /* If there exists in-memory data ready to be flushed to disk, attempt
................................................................................
  5518   5518     int flags;
  5519   5519     u8 *aData;
  5520   5520     int nData;
  5521   5521   
  5522   5522     aData = fsPageData(pPg, &nData);
  5523   5523   
  5524   5524     nRec = pageGetNRec(aData, nData);
  5525         -  iPtr = pageGetPtr(aData, nData);
         5525  +  iPtr = (int)pageGetPtr(aData, nData);
  5526   5526     flags = pageGetFlags(aData, nData);
  5527   5527   
  5528   5528     lsmStringInit(&s, pDb->pEnv);
  5529   5529     lsmStringAppendf(&s,"nCell=%d iPtr=%d flags=%d {", nRec, iPtr, flags);
  5530   5530     if( flags&SEGMENT_BTREE_FLAG ) iPtr = 0;
  5531   5531   
  5532   5532     for(i=0; i<nRec; i++){
  5533   5533       Page *pRef = 0;               /* Pointer to page iRef */
  5534   5534       int iChar;
  5535   5535       u8 *aKey; int nKey = 0;       /* Key */
  5536         -    u8 *aVal; int nVal = 0;       /* Value */
         5536  +    u8 *aVal = 0; int nVal = 0;   /* Value */
  5537   5537       int iTopic;
  5538   5538       u8 *aCell;
  5539   5539       int iPgPtr;
  5540   5540       int eType;
  5541   5541   
  5542   5542       aCell = pageGetCell(aData, nData, i);
  5543   5543       eType = *aCell++;
................................................................................
  5589   5589     int *piPgPtr,
  5590   5590     u8 **paKey, int *pnKey,
  5591   5591     u8 **paVal, int *pnVal,
  5592   5592     Blob *pBlob
  5593   5593   ){
  5594   5594     u8 *aData; int nData;           /* Page data */
  5595   5595     u8 *aKey; int nKey = 0;         /* Key */
  5596         -  u8 *aVal; int nVal = 0;         /* Value */
         5596  +  u8 *aVal = 0; int nVal = 0;     /* Value */
  5597   5597     int eType;
  5598   5598     int iPgPtr;
  5599   5599     Page *pRef = 0;                 /* Pointer to page iRef */
  5600   5600     u8 *aCell;
  5601   5601   
  5602   5602     aData = fsPageData(pPg, &nData);
  5603   5603   
................................................................................
  5695   5695   
  5696   5696     if( rc==LSM_OK ){
  5697   5697       Blob blob = {0, 0, 0, 0};
  5698   5698       int nKeyWidth = 0;
  5699   5699       LsmString str;
  5700   5700       int nRec;
  5701   5701       int iPtr;
  5702         -    int flags;
         5702  +    int flags2;
  5703   5703       int iCell;
  5704   5704       u8 *aData; int nData;         /* Page data and size thereof */
  5705   5705   
  5706   5706       aData = fsPageData(pPg, &nData);
  5707   5707       nRec = pageGetNRec(aData, nData);
  5708         -    iPtr = pageGetPtr(aData, nData);
  5709         -    flags = pageGetFlags(aData, nData);
         5708  +    iPtr = (int)pageGetPtr(aData, nData);
         5709  +    flags2 = pageGetFlags(aData, nData);
  5710   5710   
  5711   5711       lsmStringInit(&str, pDb->pEnv);
  5712   5712       lsmStringAppendf(&str, "Page : %lld  (%d bytes)\n", iPg, nData);
  5713   5713       lsmStringAppendf(&str, "nRec : %d\n", nRec);
  5714   5714       lsmStringAppendf(&str, "iPtr : %d\n", iPtr);
  5715         -    lsmStringAppendf(&str, "flags: %04x\n", flags);
         5715  +    lsmStringAppendf(&str, "flags: %04x\n", flags2);
  5716   5716       lsmStringAppendf(&str, "\n");
  5717   5717   
  5718   5718       for(iCell=0; iCell<nRec; iCell++){
  5719   5719         int nKey;
  5720   5720         infoCellDump(
  5721   5721             pDb, pSeg, bIndirect, pPg, iCell, 0, 0, 0, &nKey, 0, 0, &blob
  5722   5722         );
................................................................................
  5731   5731         int eType;
  5732   5732         Pgno iAbsPtr;
  5733   5733         char zFlags[8];
  5734   5734   
  5735   5735         infoCellDump(pDb, pSeg, bIndirect, pPg, iCell, &eType, &iPgPtr,
  5736   5736             &aKey, &nKey, &aVal, &nVal, &blob
  5737   5737         );
  5738         -      iAbsPtr = iPgPtr + ((flags & SEGMENT_BTREE_FLAG) ? 0 : iPtr);
         5738  +      iAbsPtr = iPgPtr + ((flags2 & SEGMENT_BTREE_FLAG) ? 0 : iPtr);
  5739   5739   
  5740   5740         lsmFlagsToString(eType, zFlags);
  5741   5741         lsmStringAppendf(&str, "%s %d (%s) ", 
  5742   5742             zFlags, iAbsPtr, (rtTopic(eType) ? "sys" : "usr")
  5743   5743         );
  5744   5744         infoAppendBlob(&str, bHex, aKey, nKey); 
  5745   5745         if( nVal>0 && bValues ){

Changes to ext/lsm1/lsm_tree.c.

   274    274   
   275    275   /*
   276    276   ** The pointer passed as the first argument points to an interior node,
   277    277   ** not a leaf. This function returns the offset of the iCell'th child
   278    278   ** sub-tree of the node.
   279    279   */
   280    280   static u32 getChildPtr(TreeNode *p, int iVersion, int iCell){
          281  +  assert( iVersion>=0 );
   281    282     assert( iCell>=0 && iCell<=array_size(p->aiChildPtr) );
   282         -  if( p->iV2 && p->iV2<=iVersion && iCell==p->iV2Child ) return p->iV2Ptr;
          283  +  if( p->iV2 && p->iV2<=(u32)iVersion && iCell==p->iV2Child ) return p->iV2Ptr;
   283    284     return p->aiChildPtr[iCell];
   284    285   }
   285    286   
   286    287   /*
   287    288   ** Given an offset within the *-shm file, return the associated chunk number.
   288    289   */
   289    290   static int treeOffsetToChunk(u32 iOff){
................................................................................
   296    297   
   297    298   /*
   298    299   ** Return a pointer to the mapped memory location associated with *-shm 
   299    300   ** file offset iPtr.
   300    301   */
   301    302   static void *treeShmptr(lsm_db *pDb, u32 iPtr){
   302    303   
   303         -  assert( (iPtr>>15)<pDb->nShm );
          304  +  assert( (iPtr>>15)<(u32)pDb->nShm );
   304    305     assert( pDb->apShm[iPtr>>15] );
   305    306   
   306    307     return iPtr ? treeShmptrUnsafe(pDb, iPtr) : 0;
   307    308   }
   308    309   
   309    310   static ShmChunk * treeShmChunk(lsm_db *pDb, int iChunk){
   310    311     return (ShmChunk *)(pDb->apShm[iChunk]);
................................................................................
   515    516       printf("% 6d %.*sleaf%.*s: %s\n", 
   516    517           iNode, nPath, zPath, 20-nPath-4, zSpace, s.z
   517    518       );
   518    519       lsmStringClear(&s);
   519    520     }else{
   520    521       for(i=0; i<4 && nHeight>0; i++){
   521    522         u32 iPtr = getChildPtr(pNode, pDb->treehdr.root.iTransId, i);
   522         -      zPath[nPath] = i+'0';
          523  +      zPath[nPath] = (char)(i+'0');
   523    524         zPath[nPath+1] = '/';
   524    525   
   525    526         if( iPtr ){
   526    527           dump_node_contents(pDb, iPtr, zPath, nPath+2, nHeight-1);
   527    528         }
   528    529         if( i!=3 && pNode->aiKeyPtr[i] ){
   529    530           TreeKey *pKey = treeShmkey(pDb, pNode->aiKeyPtr[i], TKV_LOADKEY,&b,&rc);
................................................................................
   640    641         iWrite = (iWrite + 3) & ~0x0003;
   641    642         assert( (iWrite % 4)==0 );
   642    643       }
   643    644   
   644    645       assert( iWrite );
   645    646       iChunk = treeOffsetToChunk(iWrite-1);
   646    647       iEof = (iChunk+1) * CHUNK_SIZE;
   647         -    assert( iEof>=iWrite && (iEof-iWrite)<CHUNK_SIZE );
          648  +    assert( iEof>=iWrite && (iEof-iWrite)<(u32)CHUNK_SIZE );
   648    649       if( (iWrite+nByte)>iEof ){
   649    650         ShmChunk *pHdr;           /* Header of chunk just finished (iChunk) */
   650    651         ShmChunk *pFirst;         /* Header of chunk treehdr.iFirst */
   651    652         ShmChunk *pNext;          /* Header of new chunk */
   652    653         int iNext = 0;            /* Next chunk */
   653    654         int rc = LSM_OK;
   654    655   
................................................................................
   753    754       while( nRem>0 ){
   754    755         u8 *aAlloc;
   755    756         int nAlloc;
   756    757         u32 iWrite;
   757    758   
   758    759         iWrite = (pDb->treehdr.iWrite & (LSM_SHM_CHUNK_SIZE-1));
   759    760         iWrite = LSM_MAX(iWrite, LSM_SHM_CHUNK_HDR);
   760         -      nAlloc = LSM_MIN((LSM_SHM_CHUNK_SIZE-iWrite), nRem);
          761  +      nAlloc = LSM_MIN((LSM_SHM_CHUNK_SIZE-iWrite), (u32)nRem);
   761    762   
   762    763         aAlloc = treeShmptr(pDb, treeShmalloc(pDb, 0, nAlloc, pRc));
   763    764         if( aAlloc==0 ) break;
   764    765         memcpy(aAlloc, &a[n-nRem], nAlloc);
   765    766         nRem -= nAlloc;
   766    767       }
   767    768       a = pVal;
................................................................................
  1205   1206         }
  1206   1207       }else{
  1207   1208         p = 0;
  1208   1209       }
  1209   1210       nVisit++;
  1210   1211     }
  1211   1212   
  1212         -  if( rc==LSM_OK && nVisit!=db->treehdr.nChunk-1 ){
         1213  +  if( rc==LSM_OK && (u32)nVisit!=db->treehdr.nChunk-1 ){
  1213   1214       rc = LSM_CORRUPT_BKPT;
  1214   1215     }
  1215   1216     return rc;
  1216   1217   }
  1217   1218   
  1218   1219   /*
  1219   1220   ** Iterate through the current in-memory tree. If there are any v2-pointers
................................................................................
  1255   1256     int i;
  1256   1257     ShmChunk *p;
  1257   1258     ShmChunk *pMin = 0;
  1258   1259     u32 iMin = 0;
  1259   1260   
  1260   1261     /* Iterate through all shm chunks. Find the smallest shm-id present in
  1261   1262     ** the shared-memory region. */
  1262         -  for(i=1; rc==LSM_OK && i<db->treehdr.nChunk; i++){
         1263  +  for(i=1; rc==LSM_OK && (u32)i<db->treehdr.nChunk; i++){
  1263   1264       p = treeShmChunkRc(db, i, &rc);
  1264   1265       if( p && (pMin==0 || shm_sequence_ge(pMin->iShmid, p->iShmid)) ){
  1265   1266         pMin = p;
  1266   1267         iMin = i;
  1267   1268       }
  1268   1269     }
  1269   1270   
................................................................................
  1275   1276       int nSort;
  1276   1277       int nByte;
  1277   1278       u32 iPrevShmid;
  1278   1279       ShmChunkLoc *aSort;
  1279   1280   
  1280   1281       /* Allocate space for a merge sort. */
  1281   1282       nSort = 1;
  1282         -    while( nSort < (db->treehdr.nChunk-1) ) nSort = nSort * 2;
         1283  +    while( (u32)nSort < (db->treehdr.nChunk-1) ) nSort = nSort * 2;
  1283   1284       nByte = sizeof(ShmChunkLoc) * nSort * 2;
  1284   1285       aSort = lsmMallocZeroRc(db->pEnv, nByte, &rc);
  1285   1286       iPrevShmid = pMin->iShmid;
  1286   1287   
  1287   1288       /* Fix all shm-ids, if required. */
  1288   1289       if( rc==LSM_OK ){
  1289   1290         iPrevShmid = pMin->iShmid-1;
  1290         -      for(i=1; i<db->treehdr.nChunk; i++){
         1291  +      for(i=1; (u32)i<db->treehdr.nChunk; i++){
  1291   1292           p = treeShmChunk(db, i);
  1292   1293           aSort[i-1].pShm = p;
  1293   1294           aSort[i-1].iLoc = i;
  1294         -        if( i!=db->treehdr.iFirst ){
         1295  +        if( (u32)i!=db->treehdr.iFirst ){
  1295   1296             if( shm_sequence_ge(p->iShmid, db->treehdr.iNextShmid) ){
  1296   1297               p->iShmid = iPrevShmid--;
  1297   1298             }
  1298   1299           }
  1299   1300         }
  1300   1301         if( iMin!=db->treehdr.iFirst ){
  1301   1302           p = treeShmChunk(db, db->treehdr.iFirst);
................................................................................
  1371   1372       TreeRoot *p = &db->treehdr.root;
  1372   1373       TreeNode *pNew;
  1373   1374       u32 iNew;
  1374   1375       TreeNode *pNode = pCsr->apTreeNode[pCsr->iNode];
  1375   1376       int iCell = pCsr->aiCell[pCsr->iNode];
  1376   1377   
  1377   1378       /* Create a copy of this node */
  1378         -    if( (pCsr->iNode>0 && pCsr->iNode==(p->nHeight-1)) ){
         1379  +    if( (pCsr->iNode>0 && (u32)pCsr->iNode==(p->nHeight-1)) ){
  1379   1380         pNew = copyTreeLeaf(db, (TreeLeaf *)pNode, &iNew, pRc);
  1380   1381       }else{
  1381   1382         pNew = copyTreeNode(db, pNode, &iNew, pRc);
  1382   1383       }
  1383   1384   
  1384   1385       if( pNew ){
  1385   1386         /* Modify the value in the new version */
................................................................................
  1394   1395   }
  1395   1396   
  1396   1397   static int treeNextIsEndDelete(lsm_db *db, TreeCursor *pCsr){
  1397   1398     int iNode = pCsr->iNode;
  1398   1399     int iCell = pCsr->aiCell[iNode]+1;
  1399   1400   
  1400   1401     /* Cursor currently points to a leaf node. */
  1401         -  assert( pCsr->iNode==(db->treehdr.root.nHeight-1) );
         1402  +  assert( (u32)pCsr->iNode==(db->treehdr.root.nHeight-1) );
  1402   1403   
  1403   1404     while( iNode>=0 ){
  1404   1405       TreeNode *pNode = pCsr->apTreeNode[iNode];
  1405   1406       if( iCell<3 && pNode->aiKeyPtr[iCell] ){
  1406   1407         int rc = LSM_OK;
  1407   1408         TreeKey *pKey = treeShmptr(db, pNode->aiKeyPtr[iCell]);
  1408   1409         assert( rc==LSM_OK );
................................................................................
  1415   1416     return 0;
  1416   1417   }
  1417   1418   
  1418   1419   static int treePrevIsStartDelete(lsm_db *db, TreeCursor *pCsr){
  1419   1420     int iNode = pCsr->iNode;
  1420   1421   
  1421   1422     /* Cursor currently points to a leaf node. */
  1422         -  assert( pCsr->iNode==(db->treehdr.root.nHeight-1) );
         1423  +  assert( (u32)pCsr->iNode==(db->treehdr.root.nHeight-1) );
  1423   1424   
  1424   1425     while( iNode>=0 ){
  1425   1426       TreeNode *pNode = pCsr->apTreeNode[iNode];
  1426   1427       int iCell = pCsr->aiCell[iNode]-1;
  1427   1428       if( iCell>=0 && pNode->aiKeyPtr[iCell] ){
  1428   1429         int rc = LSM_OK;
  1429   1430         TreeKey *pKey = treeShmptr(db, pNode->aiKeyPtr[iCell]);
................................................................................
  1446   1447     int nVal                        /* Bytes in value data (or -ve for delete) */
  1447   1448   ){
  1448   1449     int rc = LSM_OK;                /* Return Code */
  1449   1450     TreeKey *pTreeKey;              /* New key-value being inserted */
  1450   1451     u32 iTreeKey;
  1451   1452     TreeRoot *p = &pDb->treehdr.root;
  1452   1453     TreeCursor csr;                 /* Cursor to seek to pKey/nKey */
  1453         -  int res;                        /* Result of seek operation on csr */
         1454  +  int res = 0;                    /* Result of seek operation on csr */
  1454   1455   
  1455   1456     assert( nVal>=0 || pVal==0 );
  1456   1457     assert_tree_looks_ok(LSM_OK, pTree);
  1457   1458     assert( flags==LSM_INSERT       || flags==LSM_POINT_DELETE 
  1458   1459          || flags==LSM_START_DELETE || flags==LSM_END_DELETE 
  1459   1460     );
  1460   1461     assert( (flags & LSM_CONTIGUOUS)==0 );
................................................................................
  1593   1594     int iSlot = pCsr->aiCell[pCsr->iNode];
  1594   1595     int bLeaf;
  1595   1596     int rc = LSM_OK;
  1596   1597   
  1597   1598     assert( pNode->aiKeyPtr[1] );
  1598   1599     assert( pNode->aiKeyPtr[iSlot] );
  1599   1600     assert( iSlot==0 || iSlot==1 || iSlot==2 );
  1600         -  assert( (pCsr->iNode==(db->treehdr.root.nHeight-1))==(iNewptr==0) );
         1601  +  assert( ((u32)pCsr->iNode==(db->treehdr.root.nHeight-1))==(iNewptr==0) );
  1601   1602   
  1602         -  bLeaf = (pCsr->iNode==(p->nHeight-1) && p->nHeight>1);
         1603  +  bLeaf = ((u32)pCsr->iNode==(p->nHeight-1) && p->nHeight>1);
  1603   1604     
  1604   1605     if( pNode->aiKeyPtr[0] || pNode->aiKeyPtr[2] ){
  1605   1606       /* There are currently at least 2 keys on this node. So just create
  1606   1607       ** a new copy of the node with one of the keys removed. If the node
  1607   1608       ** happens to be the root node of the tree, allocate an entire 
  1608   1609       ** TreeNode structure instead of just a TreeLeaf.  */
  1609   1610       TreeNode *pNew;
................................................................................
  1760   1761             }
  1761   1762           }
  1762   1763         }
  1763   1764         if( iDir==-1 ){
  1764   1765           iPSlot--;
  1765   1766           pNew1->aiKeyPtr[iKOut++] = pParent->aiKeyPtr[iPSlot];
  1766   1767           if( bLeaf==0 ) pNew1->aiChildPtr[iPOut++] = iNewptr;
  1767         -        pCsr->aiCell[pCsr->iNode] = iPSlot;
         1768  +        pCsr->aiCell[pCsr->iNode] = (u8)iPSlot;
  1768   1769         }
  1769   1770   
  1770   1771         rc = treeDeleteEntry(db, pCsr, iNew1);
  1771   1772       }
  1772   1773     }
  1773   1774   
  1774   1775     return rc;
................................................................................
  1835   1836       bDone = 1;
  1836   1837       if( lsmTreeCursorValid(&csr) ){
  1837   1838         lsmTreeCursorKey(&csr, 0, &pDel, &nDel);
  1838   1839         if( treeKeycmp(pDel, nDel, pKey2, nKey2)<0 ) bDone = 0;
  1839   1840       }
  1840   1841   
  1841   1842       if( bDone==0 ){
  1842         -      if( csr.iNode==(p->nHeight-1) ){
         1843  +      if( (u32)csr.iNode==(p->nHeight-1) ){
  1843   1844           /* The element to delete already lies on a leaf node */
  1844   1845           rc = treeDeleteEntry(db, &csr, 0);
  1845   1846         }else{
  1846   1847           /* 1. Overwrite the current key with a copy of the next key in the 
  1847   1848           **    tree (key N).
  1848   1849           **
  1849   1850           ** 2. Seek to key N (cursor will stop at the internal node copy of
................................................................................
  1850   1851           **    N). Move to the next key (original copy of N). Delete
  1851   1852           **    this entry. 
  1852   1853           */
  1853   1854           u32 iKey;
  1854   1855           TreeKey *pKey;
  1855   1856           int iNode = csr.iNode;
  1856   1857           lsmTreeCursorNext(&csr);
  1857         -        assert( csr.iNode==(p->nHeight-1) );
         1858  +        assert( (u32)csr.iNode==(p->nHeight-1) );
  1858   1859   
  1859   1860           iKey = csr.apTreeNode[csr.iNode]->aiKeyPtr[csr.aiCell[csr.iNode]];
  1860   1861           lsmTreeCursorPrev(&csr);
  1861   1862   
  1862   1863           treeOverwriteKey(db, &csr, iKey, &rc);
  1863   1864           pKey = treeShmkey(db, iKey, TKV_LOADKEY, &blob, &rc);
  1864   1865           if( pKey ){
................................................................................
  2024   2025           pTreeKey = (TreeKey*)treeShmptrUnsafe(pDb, iTreeKey);
  2025   2026           if( !(pTreeKey->flags & LSM_CONTIGUOUS) ){
  2026   2027             pTreeKey = treeShmkey(pDb, iTreeKey, TKV_LOADKEY, &b, &rc);
  2027   2028             if( rc ) break;
  2028   2029           }
  2029   2030           res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey);
  2030   2031           if( res==0 ){
  2031         -          pCsr->aiCell[iNode] = iTest;
         2032  +          pCsr->aiCell[iNode] = (u8)iTest;
  2032   2033             break;
  2033   2034           }
  2034   2035         }else{
  2035   2036           iTest = 1;
  2036   2037         }
  2037   2038   
  2038         -      if( iNode<(pRoot->nHeight-1) ){
         2039  +      if( (u32)iNode<(pRoot->nHeight-1) ){
  2039   2040           iNodePtr = getChildPtr(pNode, pRoot->iTransId, iTest + (res<0));
  2040   2041         }else{
  2041   2042           iNodePtr = 0;
  2042   2043         }
  2043         -      pCsr->aiCell[iNode] = iTest + (iNodePtr && (res<0));
         2044  +      pCsr->aiCell[iNode] = (u8)(iTest + (iNodePtr && (res<0)));
  2044   2045       }
  2045   2046   
  2046   2047       *pRes = res;
  2047   2048       pCsr->iNode = iNode;
  2048   2049       tblobFree(pDb, &b);
  2049   2050     }
  2050   2051   
................................................................................
  2163   2164         u32 iNodePtr;
  2164   2165         pCsr->iNode++;
  2165   2166         iNodePtr = getChildPtr(pNode, pRoot->iTransId, iCell);
  2166   2167         pNode = (TreeNode *)treeShmptr(pDb, iNodePtr);
  2167   2168         if( rc!=LSM_OK ) break;
  2168   2169         pCsr->apTreeNode[pCsr->iNode] = pNode;
  2169   2170         iCell = 1 + (pNode->aiKeyPtr[2]!=0) + (pCsr->iNode < iLeaf);
  2170         -      pCsr->aiCell[pCsr->iNode] = iCell;
         2171  +      pCsr->aiCell[pCsr->iNode] = (u8)iCell;
  2171   2172       }while( pCsr->iNode < iLeaf );
  2172   2173     }
  2173   2174   
  2174   2175     /* Otherwise, the next key is found by following pointer up the tree until
  2175   2176     ** there is a key immediately to the left of the pointer followed to reach
  2176   2177     ** the sub-tree containing the current key. */
  2177   2178     else{
  2178   2179       do {
  2179   2180         iCell = pCsr->aiCell[pCsr->iNode]-1;
  2180   2181         if( iCell>=0 && pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[iCell] ) break;
  2181   2182       }while( (--pCsr->iNode)>=0 );
  2182         -    pCsr->aiCell[pCsr->iNode] = iCell;
         2183  +    pCsr->aiCell[pCsr->iNode] = (u8)iCell;
  2183   2184     }
  2184   2185   
  2185   2186   #ifndef NDEBUG
  2186   2187     if( pCsr->iNode>=0 ){
  2187   2188       TreeKey *pK2 = csrGetKey(pCsr, &pCsr->blob, &rc);
  2188   2189       assert( rc || treeKeycmp(TKV_KEY(pK2),pK2->nKey,TKV_KEY(pK1),pK1->nKey)<0 );
  2189   2190     }
................................................................................
  2220   2221         iCell = ((pNode->aiKeyPtr[2]==0) ? 2 : 3);
  2221   2222       }else{
  2222   2223         iCell = ((pNode->aiKeyPtr[0]==0) ? 1 : 0);
  2223   2224       }
  2224   2225       pCsr->iNode++;
  2225   2226       pCsr->apTreeNode[pCsr->iNode] = pNode;
  2226   2227   
  2227         -    if( pCsr->iNode<pRoot->nHeight-1 ){
         2228  +    if( (u32)pCsr->iNode<pRoot->nHeight-1 ){
  2228   2229         iNodePtr = getChildPtr(pNode, pRoot->iTransId, iCell);
  2229   2230       }else{
  2230   2231         iNodePtr = 0;
  2231   2232       }
  2232         -    pCsr->aiCell[pCsr->iNode] = iCell - (iNodePtr==0 && bLast);
         2233  +    pCsr->aiCell[pCsr->iNode] = (u8)(iCell - (iNodePtr==0 && bLast));
  2233   2234     }
  2234   2235   
  2235   2236     return rc;
  2236   2237   }
  2237   2238   
  2238   2239   int lsmTreeCursorFlags(TreeCursor *pCsr){
  2239   2240     int flags = 0;

Changes to ext/lsm1/lsm_varint.c.

   172    172     }
   173    173     if( z[0]==250 ){
   174    174       *piVal = (z[1]<<16) + (z[2]<<8) + z[3];
   175    175       return 4;
   176    176     }
   177    177   
   178    178     ret = lsmSqlite4GetVarint64(z, &i);
   179         -  *piVal = i;
          179  +  *piVal = (int)i;
   180    180     return ret;
   181    181   }
   182    182   
   183    183   int lsmVarintLen32(int n){
   184    184     u8 aData[9];
   185    185     return lsmVarintPut32(aData, n);
   186    186   }

Changes to ext/lsm1/lsm_vtab.c.

    40     40   struct lsm1_cursor {
    41     41     sqlite3_vtab_cursor base;  /* Base class - must be first */
    42     42     lsm_cursor *pLsmCur;       /* The LSM cursor */
    43     43     u8 isDesc;                 /* 0: scan forward.  1: scan reverse */
    44     44     u8 atEof;                  /* True if the scan is complete */
    45     45     u8 bUnique;                /* True if no more than one row of output */
    46     46   };
           47  +
           48  +/* Dequote the string */
           49  +static void lsm1Dequote(char *z){
           50  +  int j;
           51  +  char cQuote = z[0];
           52  +  size_t i, n;
           53  +
           54  +  if( cQuote!='\'' && cQuote!='"' ) return;
           55  +  n = strlen(z);
           56  +  if( n<2 || z[n-1]!=z[0] ) return;
           57  +  for(i=1, j=0; i<n-1; i++){
           58  +    if( z[i]==cQuote && z[i+1]==cQuote ) i++;
           59  +    z[j++] = z[i];
           60  +  }
           61  +  z[j] = 0;
           62  +}
           63  +
    47     64   
    48     65   /*
    49     66   ** The lsm1Connect() method is invoked to create a new
    50     67   ** lsm1_vtab that describes the virtual table.
    51     68   */
    52     69   static int lsm1Connect(
    53     70     sqlite3 *db,
................................................................................
    54     71     void *pAux,
    55     72     int argc, const char *const*argv,
    56     73     sqlite3_vtab **ppVtab,
    57     74     char **pzErr
    58     75   ){
    59     76     lsm1_vtab *pNew;
    60     77     int rc;
           78  +  char *zFilename;
    61     79   
    62     80     if( argc!=4 || argv[3]==0 || argv[3][0]==0 ){
    63     81       *pzErr = sqlite3_mprintf("filename argument missing");
    64     82       return SQLITE_ERROR;
    65     83     }
    66     84     *ppVtab = sqlite3_malloc( sizeof(*pNew) );
    67     85     pNew = (lsm1_vtab*)*ppVtab;
................................................................................
    71     89     memset(pNew, 0, sizeof(*pNew));
    72     90     rc = lsm_new(0, &pNew->pDb);
    73     91     if( rc ){
    74     92       *pzErr = sqlite3_mprintf("lsm_new failed with error code %d",  rc);
    75     93       rc = SQLITE_ERROR;
    76     94       goto connect_failed;
    77     95     }
    78         -  rc = lsm_open(pNew->pDb, argv[3]);
           96  +  zFilename = sqlite3_mprintf("%s", argv[3]);
           97  +  lsm1Dequote(zFilename);
           98  +  rc = lsm_open(pNew->pDb, zFilename);
           99  +  sqlite3_free(zFilename);
    79    100     if( rc ){
    80    101       *pzErr = sqlite3_mprintf("lsm_open failed with %d", rc);
    81    102       rc = SQLITE_ERROR;
    82    103       goto connect_failed;
    83    104     }
    84    105   
    85    106   /* Column numbers */
................................................................................
   153    174   
   154    175   
   155    176   /*
   156    177   ** Advance a lsm1_cursor to its next row of output.
   157    178   */
   158    179   static int lsm1Next(sqlite3_vtab_cursor *cur){
   159    180     lsm1_cursor *pCur = (lsm1_cursor*)cur;
   160         -  int rc;
          181  +  int rc = LSM_OK;
   161    182     if( pCur->bUnique ){
   162    183       pCur->atEof = 1;
   163    184     }else{
   164    185       if( pCur->isDesc ){
   165    186         rc = lsm_csr_prev(pCur->pLsmCur);
   166    187       }else{
   167    188         rc = lsm_csr_next(pCur->pLsmCur);
................................................................................
   364    385           pVal = (const void*)sqlite3_value_text(pValue);
   365    386           if( pVal==0 ) return SQLITE_NOMEM;
   366    387         }
   367    388         if( nVal+1>nSpace ){
   368    389           pSpace = sqlite3_malloc( nVal+1 );
   369    390           if( pSpace==0 ) return SQLITE_NOMEM;
   370    391         }
   371         -      pSpace[0] = eType;
          392  +      pSpace[0] = (unsigned char)eType;
   372    393         memcpy(&pSpace[1], pVal, nVal);
   373    394         *ppKey = pSpace;
   374    395         *pnKey = nVal+1;
   375    396         break;
   376    397       }
   377    398       case SQLITE_INTEGER: {
   378    399         sqlite3_int64 iVal = sqlite3_value_int64(pValue);
................................................................................
   381    402           if( iVal==0xffffffffffffffffLL ) return SQLITE_ERROR;
   382    403           uVal = *(sqlite3_uint64*)&iVal;
   383    404           eType = LSM1_TYPE_NEGATIVE;
   384    405         }else{
   385    406           uVal = iVal;
   386    407           eType = LSM1_TYPE_POSITIVE;
   387    408         }
   388         -      pSpace[0] = eType;
          409  +      pSpace[0] = (unsigned char)eType;
   389    410         *ppKey = pSpace;
   390    411         *pnKey = 1 + lsm1PutVarint64(&pSpace[1], uVal);
   391    412       }
   392    413     }
   393    414     return SQLITE_OK;
   394    415   }
   395    416   
................................................................................
   591    612     sqlite3_vtab *pVTab,
   592    613     int argc,
   593    614     sqlite3_value **argv,
   594    615     sqlite_int64 *pRowid
   595    616   ){
   596    617     lsm1_vtab *p = (lsm1_vtab*)pVTab;
   597    618     const void *pKey;
          619  +  void *pFree = 0;
   598    620     int nKey;
   599    621     int eType;
   600         -  int rc;
          622  +  int rc = LSM_OK;
   601    623     sqlite3_value *pValue;
   602    624     const unsigned char *pVal;
   603    625     unsigned char *pData;
   604    626     int nVal;
   605    627     unsigned char pSpace[100];
   606    628   
   607    629     if( argc==1 ){
................................................................................
   625    647       nKey = sqlite3_value_bytes(argv[2+LSM1_COLUMN_BLOBKEY]);
   626    648     }else{
   627    649       /* Use a key encoding that sorts in lexicographical order */
   628    650       rc = lsm1EncodeKey(argv[2+LSM1_COLUMN_KEY],
   629    651                          (unsigned char**)&pKey,&nKey,
   630    652                          pSpace,sizeof(pSpace));
   631    653       if( rc ) return rc;
          654  +    if( pKey!=(const void*)pSpace ) pFree = (void*)pKey;
   632    655     }
   633    656     if( sqlite3_value_type(argv[2+LSM1_COLUMN_BLOBVALUE])==SQLITE_BLOB ){
   634    657       pVal = sqlite3_value_blob(argv[2+LSM1_COLUMN_BLOBVALUE]);
   635    658       nVal = sqlite3_value_bytes(argv[2+LSM1_COLUMN_BLOBVALUE]);
   636    659       rc = lsm_insert(p->pDb, pKey, nKey, pVal, nVal);
   637    660     }else{
   638    661       pValue = argv[2+LSM1_COLUMN_VALUE];
................................................................................
   650    673             pVal = (unsigned char*)sqlite3_value_blob(pValue);
   651    674           }
   652    675           nVal = sqlite3_value_bytes(pValue);
   653    676           pData = sqlite3_malloc( nVal+1 );
   654    677           if( pData==0 ){
   655    678             rc = SQLITE_NOMEM;
   656    679           }else{
   657         -          pData[0] = eType;
          680  +          pData[0] = (unsigned char)eType;
   658    681             memcpy(&pData[1], pVal, nVal);
   659    682             rc = lsm_insert(p->pDb, pKey, nKey, pData, nVal+1);
   660    683             sqlite3_free(pData);
   661    684           }
   662    685           break;
   663    686         }
   664    687         case SQLITE_INTEGER:
................................................................................
   673    696             assert( sizeof(r)==sizeof(x) );
   674    697             memcpy(&x, &r, sizeof(r));
   675    698           }
   676    699           for(i=8; x>0 && i>=1; i--){
   677    700             aVal[i] = x & 0xff;
   678    701             x >>= 8;
   679    702           }
   680         -        aVal[i] = eType;
          703  +        aVal[i] = (unsigned char)eType;
   681    704           rc = lsm_insert(p->pDb, pKey, nKey, &aVal[i], 9-i);
   682    705           break;
   683    706         }
   684    707       }
   685    708     }
   686         -  if( pKey!=(const void*)pSpace ) sqlite3_free((void*)pKey);
          709  +  sqlite3_free(pFree);
   687    710     return rc==LSM_OK ? SQLITE_OK : SQLITE_ERROR;
   688    711   }      
   689    712   
   690    713   /* Begin a transaction
   691    714   */
   692    715   static int lsm1Begin(sqlite3_vtab *pVtab){
   693    716     lsm1_vtab *p = (lsm1_vtab*)pVtab;

Changes to ext/lsm1/lsm_win32.c.

    43     43     LPVOID pMap;                    /* Pointer to mapping of file fd */
    44     44     size_t nMap;                    /* Size of mapping at pMap in bytes */
    45     45     int nShm;                       /* Number of entries in ahShm[]/apShm[] */
    46     46     LPHANDLE ahShm;                 /* Array of handles for shared mappings */
    47     47     LPVOID *apShm;                  /* Array of 32K shared memory segments */
    48     48   };
    49     49   
    50         -static char *win32ShmFile(Win32File *p){
           50  +static char *win32ShmFile(Win32File *pWin32File){
    51     51     char *zShm;
    52         -  int nName = strlen(p->zName);
    53         -  zShm = (char *)lsmMallocZero(p->pEnv, nName+4+1);
           52  +  int nName = strlen(pWin32File->zName);
           53  +  zShm = (char *)lsmMallocZero(pWin32File->pEnv, nName+4+1);
    54     54     if( zShm ){
    55         -    memcpy(zShm, p->zName, nName);
           55  +    memcpy(zShm, pWin32File->zName, nName);
    56     56       memcpy(&zShm[nName], "-shm", 5);
    57     57     }
    58     58     return zShm;
    59     59   }
    60     60   
    61     61   static int win32Sleep(int us){
    62     62     Sleep((us + 999) / 1000);
................................................................................
   375    375   
   376    376     return rc;
   377    377   }
   378    378   
   379    379   static int lsmWin32OsSectorSize(lsm_file *pFile){
   380    380     return 512;
   381    381   }
          382  +
          383  +static void win32Unmap(Win32File *pWin32File){
          384  +  if( pWin32File->pMap!=NULL ){
          385  +    UnmapViewOfFile(pWin32File->pMap);
          386  +    pWin32File->pMap = NULL;
          387  +    pWin32File->nMap = 0;
          388  +  }
          389  +  if( pWin32File->hMap!=NULL ){
          390  +    CloseHandle(pWin32File->hMap);
          391  +    pWin32File->hMap = NULL;
          392  +  }
          393  +}
   382    394   
   383    395   static int lsmWin32OsRemap(
   384    396     lsm_file *pFile,
   385    397     lsm_i64 iMin,
   386    398     void **ppOut,
   387    399     lsm_i64 *pnOut
   388    400   ){
................................................................................
   389    401     Win32File *pWin32File = (Win32File *)pFile;
   390    402   
   391    403     /* If the file is between 0 and 2MB in size, extend it in chunks of 256K.
   392    404     ** Thereafter, in chunks of 1MB at a time.  */
   393    405     const int aIncrSz[] = {256*1024, 1024*1024};
   394    406     int nIncrSz = aIncrSz[iMin>(2*1024*1024)];
   395    407   
   396         -  if( pWin32File->pMap!=NULL ){
   397         -    UnmapViewOfFile(pWin32File->pMap);
   398         -    *ppOut = pWin32File->pMap = NULL;
   399         -    *pnOut = pWin32File->nMap = 0;
   400         -  }
   401         -  if( pWin32File->hMap!=NULL ){
   402         -    CloseHandle(pWin32File->hMap);
   403         -    pWin32File->hMap = NULL;
   404         -  }
          408  +  *ppOut = NULL;
          409  +  *pnOut = 0;
          410  +
          411  +  win32Unmap(pWin32File);
   405    412     if( iMin>=0 ){
   406    413       LARGE_INTEGER fileSize;
   407    414       DWORD dwSizeHigh;
   408    415       DWORD dwSizeLow;
   409    416       HANDLE hMap;
   410    417       LPVOID pMap;
   411    418       memset(&fileSize, 0, sizeof(LARGE_INTEGER));
................................................................................
   576    583   }
   577    584   
   578    585   #if !defined(win32IsLockBusy)
   579    586   #define win32IsLockBusy(a) (((a)==ERROR_LOCK_VIOLATION) || \
   580    587                               ((a)==ERROR_IO_PENDING))
   581    588   #endif
   582    589   
   583         -static int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){
   584         -  Win32File *pWin32File = (Win32File *)pFile;
          590  +static int win32LockFile(
          591  +  Win32File *pWin32File,
          592  +  int iLock,
          593  +  int nLock,
          594  +  int eType
          595  +){
   585    596     OVERLAPPED ovlp;
   586    597   
   587    598     assert( LSM_LOCK_UNLOCK==0 );
   588    599     assert( LSM_LOCK_SHARED==1 );
   589    600     assert( LSM_LOCK_EXCL==2 );
   590    601     assert( eType>=LSM_LOCK_UNLOCK && eType<=LSM_LOCK_EXCL );
          602  +  assert( nLock>=0 );
   591    603     assert( iLock>0 && iLock<=32 );
   592    604   
   593    605     memset(&ovlp, 0, sizeof(OVERLAPPED));
   594         -  ovlp.Offset = (4096-iLock);
          606  +  ovlp.Offset = (4096-iLock-nLock+1);
   595    607     if( eType>LSM_LOCK_UNLOCK ){
   596    608       DWORD flags = LOCKFILE_FAIL_IMMEDIATELY;
   597    609       if( eType>=LSM_LOCK_EXCL ) flags |= LOCKFILE_EXCLUSIVE_LOCK;
   598         -    if( !LockFileEx(pWin32File->hFile, flags, 0, 1, 0, &ovlp) ){
          610  +    if( !LockFileEx(pWin32File->hFile, flags, 0, (DWORD)nLock, 0, &ovlp) ){
   599    611         if( win32IsLockBusy(GetLastError()) ){
   600    612           return LSM_BUSY;
   601    613         }else{
   602    614           return LSM_IOERR_BKPT;
   603    615         }
   604    616       }
   605    617     }else{
   606         -    if( !UnlockFileEx(pWin32File->hFile, 0, 1, 0, &ovlp) ){
          618  +    if( !UnlockFileEx(pWin32File->hFile, 0, (DWORD)nLock, 0, &ovlp) ){
   607    619         return LSM_IOERR_BKPT;
   608    620       }
   609    621     }
   610    622     return LSM_OK;
   611    623   }
          624  +
          625  +static int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){
          626  +  Win32File *pWin32File = (Win32File *)pFile;
          627  +  return win32LockFile(pWin32File, iLock, 1, eType);
          628  +}
   612    629   
   613    630   static int lsmWin32OsTestLock(lsm_file *pFile, int iLock, int nLock, int eType){
          631  +  int rc;
   614    632     Win32File *pWin32File = (Win32File *)pFile;
   615         -  DWORD flags = LOCKFILE_FAIL_IMMEDIATELY;
   616         -  OVERLAPPED ovlp;
   617         -
   618         -  assert( LSM_LOCK_UNLOCK==0 );
   619         -  assert( LSM_LOCK_SHARED==1 );
   620         -  assert( LSM_LOCK_EXCL==2 );
   621         -  assert( eType==LSM_LOCK_SHARED || eType==LSM_LOCK_EXCL );
   622         -  assert( nLock>=0 );
   623         -  assert( iLock>0 && iLock<=32 );
   624         -
   625         -  if( eType>=LSM_LOCK_EXCL ) flags |= LOCKFILE_EXCLUSIVE_LOCK;
   626         -  memset(&ovlp, 0, sizeof(OVERLAPPED));
   627         -  ovlp.Offset = (4096-iLock-nLock+1);
   628         -  if( !LockFileEx(pWin32File->hFile, flags, 0, (DWORD)nLock, 0, &ovlp) ){
   629         -    if( win32IsLockBusy(GetLastError()) ){
   630         -      return LSM_BUSY;
   631         -    }else{
   632         -      return LSM_IOERR_BKPT;
   633         -    }
   634         -  }
   635         -  UnlockFileEx(pWin32File->hFile, 0, (DWORD)nLock, 0, &ovlp);
          633  +  rc = win32LockFile(pWin32File, iLock, nLock, eType);
          634  +  if( rc!=LSM_OK ) return rc;
          635  +  win32LockFile(pWin32File, iLock, nLock, LSM_LOCK_UNLOCK);
   636    636     return LSM_OK;
   637    637   }
   638    638   
   639    639   static int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){
   640    640     int rc;
   641    641     Win32File *pWin32File = (Win32File *)pFile;
   642    642     int iOffset = iChunk * sz;
................................................................................
   644    644     int nNew = iChunk + 1;
   645    645     lsm_i64 nReq = nNew * sz;
   646    646   
   647    647     *ppShm = NULL;
   648    648     assert( sz>=0 );
   649    649     assert( sz==LSM_SHM_CHUNK_SIZE );
   650    650     if( iChunk>=pWin32File->nShm ){
   651         -    int i;
   652    651       LPHANDLE ahNew;
   653    652       LPVOID *apNew;
   654    653       LARGE_INTEGER fileSize;
   655    654   
   656    655       /* If the shared-memory file has not been opened, open it now. */
   657    656       if( pWin32File->hShmFile==NULL ){
   658    657         char *zShm = win32ShmFile(pWin32File);
................................................................................
   674    673       if( fileSize.QuadPart<nReq ){
   675    674         rc = win32Truncate(pWin32File->hShmFile, nReq);
   676    675         if( rc!=LSM_OK ){
   677    676           return rc;
   678    677         }
   679    678       }
   680    679   
   681         -    ahNew = (LPHANDLE)lsmMallocZero(pWin32File->pEnv, sizeof(LPHANDLE) * nNew);
          680  +    ahNew = (LPHANDLE)lsmMallocZero(pWin32File->pEnv, sizeof(HANDLE) * nNew);
   682    681       if( !ahNew ) return LSM_NOMEM_BKPT;
   683    682       apNew = (LPVOID *)lsmMallocZero(pWin32File->pEnv, sizeof(LPVOID) * nNew);
   684    683       if( !apNew ){
   685    684         lsmFree(pWin32File->pEnv, ahNew);
   686    685         return LSM_NOMEM_BKPT;
   687    686       }
   688         -    memcpy(ahNew, pWin32File->ahShm, pWin32File->nShm);
   689         -    memcpy(apNew, pWin32File->apShm, pWin32File->nShm);
   690         -    for(i=pWin32File->nShm; i<nNew; i++){
   691         -      ahNew[i] = NULL;
   692         -      apNew[i] = NULL;
   693         -    }
          687  +    memcpy(ahNew, pWin32File->ahShm, sizeof(HANDLE) * pWin32File->nShm);
          688  +    memcpy(apNew, pWin32File->apShm, sizeof(LPVOID) * pWin32File->nShm);
   694    689       lsmFree(pWin32File->pEnv, pWin32File->ahShm);
   695    690       pWin32File->ahShm = ahNew;
   696    691       lsmFree(pWin32File->pEnv, pWin32File->apShm);
   697    692       pWin32File->apShm = apNew;
   698    693       pWin32File->nShm = nNew;
   699    694     }
   700    695   
................................................................................
   759    754   
   760    755   #define MX_CLOSE_ATTEMPT 3
   761    756   static int lsmWin32OsClose(lsm_file *pFile){
   762    757     int rc;
   763    758     int nRetry = 0;
   764    759     Win32File *pWin32File = (Win32File *)pFile;
   765    760     lsmWin32OsShmUnmap(pFile, 0);
   766         -  if( pWin32File->pMap!=NULL ){
   767         -    UnmapViewOfFile(pWin32File->pMap);
   768         -    pWin32File->pMap = NULL;
   769         -    pWin32File->nMap = 0;
   770         -  }
   771         -  if( pWin32File->hMap!=NULL ){
   772         -    CloseHandle(pWin32File->hMap);
   773         -    pWin32File->hMap = NULL;
   774         -  }
          761  +  win32Unmap(pWin32File);
   775    762     do{
   776    763       if( pWin32File->hFile==NULL ){
   777    764         rc = LSM_IOERR_BKPT;
   778    765         break;
   779    766       }
   780    767       rc = CloseHandle(pWin32File->hFile);
   781    768       if( rc ){
................................................................................
   952    939   }
   953    940   static int lsmWin32OsMutexNotHeld(lsm_mutex *p){
   954    941     Win32Mutex *pMutex = (Win32Mutex *)p;
   955    942     return pMutex ? pMutex->owner!=GetCurrentThreadId() : 1;
   956    943   }
   957    944   #endif
   958    945   /*
   959         -** End of pthreads mutex implementation.
          946  +** End of Win32 mutex implementation.
   960    947   *************************************************************************/
   961    948   #else
   962    949   /*************************************************************************
   963    950   ** Noop mutex implementation
   964    951   */
   965    952   typedef struct NoopMutex NoopMutex;
   966    953   struct NoopMutex {

Added ext/lsm1/test/lsm1_common.tcl.

            1  +# 2014 Dec 19
            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  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +
           18  +# Check if the lsm1 extension has been compiled.
           19  +if {$::tcl_platform(platform) == "windows"} {
           20  +  set lsm1 lsm.dll
           21  +} else {
           22  +  set lsm1 lsm.so
           23  +}
           24  +
           25  +if {[file exists [file join .. $lsm1]]} {
           26  +  proc return_if_no_lsm1 {} {}
           27  +} else {
           28  +  proc return_if_no_lsm1 {} {
           29  +    finish_test
           30  +    return -code return
           31  +  }
           32  +  return
           33  +}
           34  +
           35  +proc load_lsm1_vtab {db} {
           36  +  db enable_load_extension 1
           37  +  db eval {SELECT load_extension('../lsm')}
           38  +}

Added ext/lsm1/test/lsm1_simple.test.

            1  +# 2017 July 14
            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 implements regression tests for SQLite library.  The
           12  +# focus of this script is testing the lsm1 virtual table module.
           13  +#
           14  +
           15  +source [file join [file dirname [info script]] lsm1_common.tcl]
           16  +set testprefix lsm1_simple
           17  +return_if_no_lsm1
           18  +load_lsm1_vtab db
           19  +
           20  +forcedelete testlsm.db
           21  +
           22  +do_execsql_test 1.0 {
           23  +  CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db);
           24  +  PRAGMA table_info(x1);
           25  +} {
           26  +  0 key       {} 0 {} 0 
           27  +  1 blobkey   {} 0 {} 0 
           28  +  2 value     {} 0 {} 0 
           29  +  3 blobvalue {} 0 {} 0
           30  +}
           31  +
           32  +do_execsql_test 1.1 {
           33  +  INSERT INTO x1(blobkey, blobvalue) VALUES(x'abcd', x'1234');
           34  +  SELECT quote(blobkey), quote(blobvalue) FROM x1;
           35  +} {X'ABCD' X'1234'}
           36  +
           37  +do_catchsql_test 1.2 {
           38  +  UPDATE x1 SET blobvalue = x'7890' WHERE blobkey = x'abcd';
           39  +} {1 {cannot UPDATE}}
           40  +
           41  +do_catchsql_test 1.3 {
           42  +  DELETE FROM x1 WHERE blobkey = x'abcd'
           43  +} {1 {cannot DELETE}}
           44  +
           45  +do_test 1.4 {
           46  +  lsort [glob testlsm.db*]
           47  +} {testlsm.db testlsm.db-log testlsm.db-shm}
           48  +
           49  +db close
           50  +do_test 1.5 {
           51  +  lsort [glob testlsm.db*]
           52  +} {testlsm.db}
           53  +
           54  +finish_test
           55  +
           56  +

Changes to ext/misc/carray.c.

    13     13   ** This file demonstrates how to create a table-valued-function that
    14     14   ** returns the values in a C-language array.
    15     15   ** Examples:
    16     16   **
    17     17   **      SELECT * FROM carray($ptr,5)
    18     18   **
    19     19   ** The query above returns 5 integers contained in a C-language array
    20         -** at the address $ptr.  $ptr is a pointer to the array of integers that
    21         -** has been cast to an integer.
           20  +** at the address $ptr.  $ptr is a pointer to the array of integers.
           21  +** The pointer value must be assigned to $ptr using the
           22  +** sqlite3_bind_pointer() interface with a pointer type of "carray".
           23  +** For example:
           24  +**
           25  +**    static int aX[] = { 53, 9, 17, 2231, 4, 99 };
           26  +**    int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
           27  +**    sqlite3_bind_value(pStmt, i, aX, "carray");
    22     28   **
    23     29   ** There is an optional third parameter to determine the datatype of
    24     30   ** the C-language array.  Allowed values of the third parameter are
    25     31   ** 'int32', 'int64', 'double', 'char*'.  Example:
    26     32   **
    27     33   **      SELECT * FROM carray($ptr,10,'char*');
           34  +**
           35  +** The default value of the third parameter is 'int32'.
    28     36   **
    29     37   ** HOW IT WORKS
    30     38   **
    31     39   ** The carray "function" is really a virtual table with the
    32     40   ** following schema:
    33     41   **
    34     42   **     CREATE TABLE carray(
................................................................................
    69     77   ** serve as the underlying representation of a cursor that scans
    70     78   ** over rows of the result
    71     79   */
    72     80   typedef struct carray_cursor carray_cursor;
    73     81   struct carray_cursor {
    74     82     sqlite3_vtab_cursor base;  /* Base class - must be first */
    75     83     sqlite3_int64 iRowid;      /* The rowid */
    76         -  sqlite3_int64 iPtr;        /* Pointer to array of values */
           84  +  void *pPtr;                /* Pointer to the array of values */
    77     85     sqlite3_int64 iCnt;        /* Number of integers in the array */
    78     86     unsigned char eType;       /* One of the CARRAY_type values */
    79     87   };
    80     88   
    81     89   /*
    82     90   ** The carrayConnect() method is invoked to create a new
    83     91   ** carray_vtab that describes the carray virtual table.
................................................................................
   163    171     sqlite3_vtab_cursor *cur,   /* The cursor */
   164    172     sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
   165    173     int i                       /* Which column to return */
   166    174   ){
   167    175     carray_cursor *pCur = (carray_cursor*)cur;
   168    176     sqlite3_int64 x = 0;
   169    177     switch( i ){
   170         -    case CARRAY_COLUMN_POINTER:   x = pCur->iPtr;   break;
          178  +    case CARRAY_COLUMN_POINTER:   return SQLITE_OK;
   171    179       case CARRAY_COLUMN_COUNT:     x = pCur->iCnt;   break;
   172    180       case CARRAY_COLUMN_CTYPE: {
   173    181         sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC);
   174    182         return SQLITE_OK;
   175    183       }
   176    184       default: {
   177    185         switch( pCur->eType ){
   178    186           case CARRAY_INT32: {
   179         -          int *p = (int*)pCur->iPtr;
          187  +          int *p = (int*)pCur->pPtr;
   180    188             sqlite3_result_int(ctx, p[pCur->iRowid-1]);
   181    189             return SQLITE_OK;
   182    190           }
   183    191           case CARRAY_INT64: {
   184         -          sqlite3_int64 *p = (sqlite3_int64*)pCur->iPtr;
          192  +          sqlite3_int64 *p = (sqlite3_int64*)pCur->pPtr;
   185    193             sqlite3_result_int64(ctx, p[pCur->iRowid-1]);
   186    194             return SQLITE_OK;
   187    195           }
   188    196           case CARRAY_DOUBLE: {
   189         -          double *p = (double*)pCur->iPtr;
          197  +          double *p = (double*)pCur->pPtr;
   190    198             sqlite3_result_double(ctx, p[pCur->iRowid-1]);
   191    199             return SQLITE_OK;
   192    200           }
   193    201           case CARRAY_TEXT: {
   194         -          const char **p = (const char**)pCur->iPtr;
          202  +          const char **p = (const char**)pCur->pPtr;
   195    203             sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT);
   196    204             return SQLITE_OK;
   197    205           }
   198    206         }
   199    207       }
   200    208     }
   201    209     sqlite3_result_int64(ctx, x);
................................................................................
   228    236   static int carrayFilter(
   229    237     sqlite3_vtab_cursor *pVtabCursor, 
   230    238     int idxNum, const char *idxStr,
   231    239     int argc, sqlite3_value **argv
   232    240   ){
   233    241     carray_cursor *pCur = (carray_cursor *)pVtabCursor;
   234    242     if( idxNum ){
   235         -    pCur->iPtr = sqlite3_value_int64(argv[0]);
   236         -    pCur->iCnt = sqlite3_value_int64(argv[1]);
          243  +    pCur->pPtr = sqlite3_value_pointer(argv[0], "carray");
          244  +    pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0;
   237    245       if( idxNum<3 ){
   238    246         pCur->eType = CARRAY_INT32;
   239    247       }else{
   240    248         unsigned char i;
   241    249         const char *zType = (const char*)sqlite3_value_text(argv[2]);
   242    250         for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
   243    251           if( sqlite3_stricmp(zType, azType[i])==0 ) break;
................................................................................
   247    255             "unknown datatype: %Q", zType);
   248    256           return SQLITE_ERROR;
   249    257         }else{
   250    258           pCur->eType = i;
   251    259         }
   252    260       }
   253    261     }else{
   254         -    pCur->iPtr = 0;
          262  +    pCur->pPtr = 0;
   255    263       pCur->iCnt = 0;
   256    264     }
   257    265     pCur->iRowid = 1;
   258    266     return SQLITE_OK;
   259    267   }
   260    268   
   261    269   /*
................................................................................
   341    349     0,                         /* xSync */
   342    350     0,                         /* xCommit */
   343    351     0,                         /* xRollback */
   344    352     0,                         /* xFindMethod */
   345    353     0,                         /* xRename */
   346    354   };
   347    355   
          356  +/*
          357  +** For testing purpose in the TCL test harness, we need a method for
          358  +** setting the pointer value.  The inttoptr(X) SQL function accomplishes
          359  +** this.  Tcl script will bind an integer to X and the inttoptr() SQL
          360  +** function will use sqlite3_result_pointer() to convert that integer into
          361  +** a pointer.
          362  +**
          363  +** This is for testing on TCL only.
          364  +*/
          365  +#ifdef SQLITE_TEST
          366  +static void inttoptrFunc(
          367  +  sqlite3_context *context,
          368  +  int argc,
          369  +  sqlite3_value **argv
          370  +){
          371  +  void *p;
          372  +  sqlite3_int64 i64;
          373  +  i64 = sqlite3_value_int64(argv[0]);
          374  +  if( sizeof(i64)==sizeof(p) ){
          375  +    memcpy(&p, &i64, sizeof(p));
          376  +  }else{
          377  +    int i32 = i64 & 0xffffffff;
          378  +    memcpy(&p, &i32, sizeof(p));
          379  +  }
          380  +  sqlite3_result_pointer(context, p, "carray");
          381  +}
          382  +#endif /* SQLITE_TEST */
          383  +
   348    384   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   349    385   
   350    386   #ifdef _WIN32
   351    387   __declspec(dllexport)
   352    388   #endif
   353    389   int sqlite3_carray_init(
   354    390     sqlite3 *db, 
................................................................................
   355    391     char **pzErrMsg, 
   356    392     const sqlite3_api_routines *pApi
   357    393   ){
   358    394     int rc = SQLITE_OK;
   359    395     SQLITE_EXTENSION_INIT2(pApi);
   360    396   #ifndef SQLITE_OMIT_VIRTUALTABLE
   361    397     rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
   362         -#endif
          398  +#ifdef SQLITE_TEST
          399  +  if( rc==SQLITE_OK ){
          400  +    rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0,
          401  +                                 inttoptrFunc, 0, 0);
          402  +  }
          403  +#endif /* SQLITE_TEST */
          404  +#endif /* SQLITE_OMIT_VIRTUALTABLE */
   363    405     return rc;
   364    406   }

Added ext/misc/completion.c.

            1  +/*
            2  +** 2017-07-10
            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 implements an eponymous virtual table that returns suggested
           14  +** completions for a partial SQL input.
           15  +**
           16  +** Suggested usage:
           17  +**
           18  +**     SELECT DISTINCT candidate COLLATE nocase
           19  +**       FROM completion($prefix,$wholeline)
           20  +**      ORDER BY 1;
           21  +**
           22  +** The two query parameters are optional.  $prefix is the text of the
           23  +** current word being typed and that is to be completed.  $wholeline is
           24  +** the complete input line, used for context.
           25  +**
           26  +** The raw completion() table might return the same candidate multiple
           27  +** times, for example if the same column name is used to two or more
           28  +** tables.  And the candidates are returned in an arbitrary order.  Hence,
           29  +** the DISTINCT and ORDER BY are recommended.
           30  +**
           31  +** This virtual table operates at the speed of human typing, and so there
           32  +** is no attempt to make it fast.  Even a slow implementation will be much
           33  +** faster than any human can type.
           34  +**
           35  +*/
           36  +#include "sqlite3ext.h"
           37  +SQLITE_EXTENSION_INIT1
           38  +#include <assert.h>
           39  +#include <string.h>
           40  +#include <ctype.h>
           41  +
           42  +#ifndef SQLITE_OMIT_VIRTUALTABLE
           43  +
           44  +/* completion_vtab is a subclass of sqlite3_vtab which will
           45  +** serve as the underlying representation of a completion virtual table
           46  +*/
           47  +typedef struct completion_vtab completion_vtab;
           48  +struct completion_vtab {
           49  +  sqlite3_vtab base;  /* Base class - must be first */
           50  +  sqlite3 *db;        /* Database connection for this completion vtab */
           51  +};
           52  +
           53  +/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
           54  +** serve as the underlying representation of a cursor that scans
           55  +** over rows of the result
           56  +*/
           57  +typedef struct completion_cursor completion_cursor;
           58  +struct completion_cursor {
           59  +  sqlite3_vtab_cursor base;  /* Base class - must be first */
           60  +  sqlite3 *db;               /* Database connection for this cursor */
           61  +  int nPrefix, nLine;        /* Number of bytes in zPrefix and zLine */
           62  +  char *zPrefix;             /* The prefix for the word we want to complete */
           63  +  char *zLine;               /* The whole that we want to complete */
           64  +  const char *zCurrentRow;   /* Current output row */
           65  +  sqlite3_stmt *pStmt;       /* Current statement */
           66  +  sqlite3_int64 iRowid;      /* The rowid */
           67  +  int ePhase;                /* Current phase */
           68  +  int j;                     /* inter-phase counter */
           69  +};
           70  +
           71  +/* Values for ePhase:
           72  +*/
           73  +#define COMPLETION_FIRST_PHASE   1
           74  +#define COMPLETION_KEYWORDS      1
           75  +#define COMPLETION_PRAGMAS       2
           76  +#define COMPLETION_FUNCTIONS     3
           77  +#define COMPLETION_COLLATIONS    4
           78  +#define COMPLETION_INDEXES       5
           79  +#define COMPLETION_TRIGGERS      6
           80  +#define COMPLETION_DATABASES     7
           81  +#define COMPLETION_TABLES        8
           82  +#define COMPLETION_COLUMNS       9
           83  +#define COMPLETION_MODULES       10
           84  +#define COMPLETION_EOF           11
           85  +
           86  +/*
           87  +** The completionConnect() method is invoked to create a new
           88  +** completion_vtab that describes the completion virtual table.
           89  +**
           90  +** Think of this routine as the constructor for completion_vtab objects.
           91  +**
           92  +** All this routine needs to do is:
           93  +**
           94  +**    (1) Allocate the completion_vtab object and initialize all fields.
           95  +**
           96  +**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
           97  +**        result set of queries against completion will look like.
           98  +*/
           99  +static int completionConnect(
          100  +  sqlite3 *db,
          101  +  void *pAux,
          102  +  int argc, const char *const*argv,
          103  +  sqlite3_vtab **ppVtab,
          104  +  char **pzErr
          105  +){
          106  +  completion_vtab *pNew;
          107  +  int rc;
          108  +
          109  +  (void)(pAux);    /* Unused parameter */
          110  +  (void)(argc);    /* Unused parameter */
          111  +  (void)(argv);    /* Unused parameter */
          112  +  (void)(pzErr);   /* Unused parameter */
          113  +
          114  +/* Column numbers */
          115  +#define COMPLETION_COLUMN_CANDIDATE 0  /* Suggested completion of the input */
          116  +#define COMPLETION_COLUMN_PREFIX    1  /* Prefix of the word to be completed */
          117  +#define COMPLETION_COLUMN_WHOLELINE 2  /* Entire line seen so far */
          118  +#define COMPLETION_COLUMN_PHASE     3  /* ePhase - used for debugging only */
          119  +
          120  +  rc = sqlite3_declare_vtab(db,
          121  +      "CREATE TABLE x("
          122  +      "  candidate TEXT,"
          123  +      "  prefix TEXT HIDDEN,"
          124  +      "  wholeline TEXT HIDDEN,"
          125  +      "  phase INT HIDDEN"        /* Used for debugging only */
          126  +      ")");
          127  +  if( rc==SQLITE_OK ){
          128  +    pNew = sqlite3_malloc( sizeof(*pNew) );
          129  +    *ppVtab = (sqlite3_vtab*)pNew;
          130  +    if( pNew==0 ) return SQLITE_NOMEM;
          131  +    memset(pNew, 0, sizeof(*pNew));
          132  +    pNew->db = db;
          133  +  }
          134  +  return rc;
          135  +}
          136  +
          137  +/*
          138  +** This method is the destructor for completion_cursor objects.
          139  +*/
          140  +static int completionDisconnect(sqlite3_vtab *pVtab){
          141  +  sqlite3_free(pVtab);
          142  +  return SQLITE_OK;
          143  +}
          144  +
          145  +/*
          146  +** Constructor for a new completion_cursor object.
          147  +*/
          148  +static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
          149  +  completion_cursor *pCur;
          150  +  pCur = sqlite3_malloc( sizeof(*pCur) );
          151  +  if( pCur==0 ) return SQLITE_NOMEM;
          152  +  memset(pCur, 0, sizeof(*pCur));
          153  +  pCur->db = ((completion_vtab*)p)->db;
          154  +  *ppCursor = &pCur->base;
          155  +  return SQLITE_OK;
          156  +}
          157  +
          158  +/*
          159  +** Reset the completion_cursor.
          160  +*/
          161  +static void completionCursorReset(completion_cursor *pCur){
          162  +  sqlite3_free(pCur->zPrefix);   pCur->zPrefix = 0;  pCur->nPrefix = 0;
          163  +  sqlite3_free(pCur->zLine);     pCur->zLine = 0;    pCur->nLine = 0;
          164  +  sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
          165  +  pCur->j = 0;
          166  +}
          167  +
          168  +/*
          169  +** Destructor for a completion_cursor.
          170  +*/
          171  +static int completionClose(sqlite3_vtab_cursor *cur){
          172  +  completionCursorReset((completion_cursor*)cur);
          173  +  sqlite3_free(cur);
          174  +  return SQLITE_OK;
          175  +}
          176  +
          177  +/*
          178  +** All SQL keywords understood by SQLite
          179  +*/
          180  +static const char *completionKwrds[] = {
          181  +  "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
          182  +  "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
          183  +  "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
          184  +  "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
          185  +  "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
          186  +  "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
          187  +  "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
          188  +  "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
          189  +  "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
          190  +  "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
          191  +  "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
          192  +  "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
          193  +  "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
          194  +  "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
          195  +  "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
          196  +  "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
          197  +  "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
          198  +  "WITH", "WITHOUT",
          199  +};
          200  +#define completionKwCount \
          201  +   (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0]))
          202  +
          203  +/*
          204  +** Advance a completion_cursor to its next row of output.
          205  +**
          206  +** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
          207  +** record the current state of the scan.  This routine sets ->zCurrentRow
          208  +** to the current row of output and then returns.  If no more rows remain,
          209  +** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
          210  +** table that has reached the end of its scan.
          211  +**
          212  +** The current implementation just lists potential identifiers and
          213  +** keywords and filters them by zPrefix.  Future enhancements should
          214  +** take zLine into account to try to restrict the set of identifiers and
          215  +** keywords based on what would be legal at the current point of input.
          216  +*/
          217  +static int completionNext(sqlite3_vtab_cursor *cur){
          218  +  completion_cursor *pCur = (completion_cursor*)cur;
          219  +  int eNextPhase = 0;  /* Next phase to try if current phase reaches end */
          220  +  int iCol = -1;       /* If >=0, step pCur->pStmt and use the i-th column */
          221  +  pCur->iRowid++;
          222  +  while( pCur->ePhase!=COMPLETION_EOF ){
          223  +    switch( pCur->ePhase ){
          224  +      case COMPLETION_KEYWORDS: {
          225  +        if( pCur->j >= completionKwCount ){
          226  +          pCur->zCurrentRow = 0;
          227  +          pCur->ePhase = COMPLETION_DATABASES;
          228  +        }else{
          229  +          pCur->zCurrentRow = completionKwrds[pCur->j++];
          230  +        }
          231  +        iCol = -1;
          232  +        break;
          233  +      }
          234  +      case COMPLETION_DATABASES: {
          235  +        if( pCur->pStmt==0 ){
          236  +          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
          237  +                             &pCur->pStmt, 0);
          238  +        }
          239  +        iCol = 1;
          240  +        eNextPhase = COMPLETION_TABLES;
          241  +        break;
          242  +      }
          243  +      case COMPLETION_TABLES: {
          244  +        if( pCur->pStmt==0 ){
          245  +          sqlite3_stmt *pS2;
          246  +          char *zSql = 0;
          247  +          const char *zSep = "";
          248  +          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
          249  +          while( sqlite3_step(pS2)==SQLITE_ROW ){
          250  +            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
          251  +            zSql = sqlite3_mprintf(
          252  +               "%z%s"
          253  +               "SELECT name FROM \"%w\".sqlite_master"
          254  +               " WHERE type='table'",
          255  +               zSql, zSep, zDb
          256  +            );
          257  +            if( zSql==0 ) return SQLITE_NOMEM;
          258  +            zSep = " UNION ";
          259  +          }
          260  +          sqlite3_finalize(pS2);
          261  +          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
          262  +          sqlite3_free(zSql);
          263  +        }
          264  +        iCol = 0;
          265  +        eNextPhase = COMPLETION_COLUMNS;
          266  +        break;
          267  +      }
          268  +      case COMPLETION_COLUMNS: {
          269  +        if( pCur->pStmt==0 ){
          270  +          sqlite3_stmt *pS2;
          271  +          char *zSql = 0;
          272  +          const char *zSep = "";
          273  +          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
          274  +          while( sqlite3_step(pS2)==SQLITE_ROW ){
          275  +            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
          276  +            zSql = sqlite3_mprintf(
          277  +               "%z%s"
          278  +               "SELECT pti.name FROM \"%w\".sqlite_master AS sm"
          279  +                       " JOIN pragma_table_info(sm.name,%Q) AS pti"
          280  +               " WHERE sm.type='table'",
          281  +               zSql, zSep, zDb, zDb
          282  +            );
          283  +            if( zSql==0 ) return SQLITE_NOMEM;
          284  +            zSep = " UNION ";
          285  +          }
          286  +          sqlite3_finalize(pS2);
          287  +          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
          288  +          sqlite3_free(zSql);
          289  +        }
          290  +        iCol = 0;
          291  +        eNextPhase = COMPLETION_EOF;
          292  +        break;
          293  +      }
          294  +    }
          295  +    if( iCol<0 ){
          296  +      /* This case is when the phase presets zCurrentRow */
          297  +      if( pCur->zCurrentRow==0 ) continue;
          298  +    }else{
          299  +      if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
          300  +        /* Extract the next row of content */
          301  +        pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
          302  +      }else{
          303  +        /* When all rows are finished, advance to the next phase */
          304  +        sqlite3_finalize(pCur->pStmt);
          305  +        pCur->pStmt = 0;
          306  +        pCur->ePhase = eNextPhase;
          307  +        continue;
          308  +      }
          309  +    }
          310  +    if( pCur->nPrefix==0 ) break;
          311  +    if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){
          312  +      break;
          313  +    }
          314  +  }
          315  +
          316  +  return SQLITE_OK;
          317  +}
          318  +
          319  +/*
          320  +** Return values of columns for the row at which the completion_cursor
          321  +** is currently pointing.
          322  +*/
          323  +static int completionColumn(
          324  +  sqlite3_vtab_cursor *cur,   /* The cursor */
          325  +  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
          326  +  int i                       /* Which column to return */
          327  +){
          328  +  completion_cursor *pCur = (completion_cursor*)cur;
          329  +  switch( i ){
          330  +    case COMPLETION_COLUMN_CANDIDATE: {
          331  +      sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT);
          332  +      break;
          333  +    }
          334  +    case COMPLETION_COLUMN_PREFIX: {
          335  +      sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
          336  +      break;
          337  +    }
          338  +    case COMPLETION_COLUMN_WHOLELINE: {
          339  +      sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
          340  +      break;
          341  +    }
          342  +    case COMPLETION_COLUMN_PHASE: {
          343  +      sqlite3_result_int(ctx, pCur->ePhase);
          344  +      break;
          345  +    }
          346  +  }
          347  +  return SQLITE_OK;
          348  +}
          349  +
          350  +/*
          351  +** Return the rowid for the current row.  In this implementation, the
          352  +** rowid is the same as the output value.
          353  +*/
          354  +static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          355  +  completion_cursor *pCur = (completion_cursor*)cur;
          356  +  *pRowid = pCur->iRowid;
          357  +  return SQLITE_OK;
          358  +}
          359  +
          360  +/*
          361  +** Return TRUE if the cursor has been moved off of the last
          362  +** row of output.
          363  +*/
          364  +static int completionEof(sqlite3_vtab_cursor *cur){
          365  +  completion_cursor *pCur = (completion_cursor*)cur;
          366  +  return pCur->ePhase >= COMPLETION_EOF;
          367  +}
          368  +
          369  +/*
          370  +** This method is called to "rewind" the completion_cursor object back
          371  +** to the first row of output.  This method is always called at least
          372  +** once prior to any call to completionColumn() or completionRowid() or 
          373  +** completionEof().
          374  +*/
          375  +static int completionFilter(
          376  +  sqlite3_vtab_cursor *pVtabCursor, 
          377  +  int idxNum, const char *idxStr,
          378  +  int argc, sqlite3_value **argv
          379  +){
          380  +  completion_cursor *pCur = (completion_cursor *)pVtabCursor;
          381  +  int iArg = 0;
          382  +  (void)(idxStr);   /* Unused parameter */
          383  +  (void)(argc);     /* Unused parameter */
          384  +  completionCursorReset(pCur);
          385  +  if( idxNum & 1 ){
          386  +    pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
          387  +    if( pCur->nPrefix>0 ){
          388  +      pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
          389  +      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
          390  +    }
          391  +    iArg++;
          392  +  }
          393  +  if( idxNum & 2 ){
          394  +    pCur->nLine = sqlite3_value_bytes(argv[iArg]);
          395  +    if( pCur->nLine>0 ){
          396  +      pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
          397  +      if( pCur->zLine==0 ) return SQLITE_NOMEM;
          398  +    }
          399  +    iArg++;
          400  +  }
          401  +  if( pCur->zLine!=0 && pCur->zPrefix==0 ){
          402  +    int i = pCur->nLine;
          403  +    while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
          404  +      i--;
          405  +    }
          406  +    pCur->nPrefix = pCur->nLine - i;
          407  +    if( pCur->nPrefix>0 ){
          408  +      pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
          409  +      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
          410  +    }
          411  +  }
          412  +  pCur->iRowid = 0;
          413  +  pCur->ePhase = COMPLETION_FIRST_PHASE;
          414  +  return completionNext(pVtabCursor);
          415  +}
          416  +
          417  +/*
          418  +** SQLite will invoke this method one or more times while planning a query
          419  +** that uses the completion virtual table.  This routine needs to create
          420  +** a query plan for each invocation and compute an estimated cost for that
          421  +** plan.
          422  +**
          423  +** There are two hidden parameters that act as arguments to the table-valued
          424  +** function:  "prefix" and "wholeline".  Bit 0 of idxNum is set if "prefix"
          425  +** is available and bit 1 is set if "wholeline" is available.
          426  +*/
          427  +static int completionBestIndex(
          428  +  sqlite3_vtab *tab,
          429  +  sqlite3_index_info *pIdxInfo
          430  +){
          431  +  int i;                 /* Loop over constraints */
          432  +  int idxNum = 0;        /* The query plan bitmask */
          433  +  int prefixIdx = -1;    /* Index of the start= constraint, or -1 if none */
          434  +  int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
          435  +  int nArg = 0;          /* Number of arguments that completeFilter() expects */
          436  +  const struct sqlite3_index_constraint *pConstraint;
          437  +
          438  +  (void)(tab);    /* Unused parameter */
          439  +  pConstraint = pIdxInfo->aConstraint;
          440  +  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
          441  +    if( pConstraint->usable==0 ) continue;
          442  +    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
          443  +    switch( pConstraint->iColumn ){
          444  +      case COMPLETION_COLUMN_PREFIX:
          445  +        prefixIdx = i;
          446  +        idxNum |= 1;
          447  +        break;
          448  +      case COMPLETION_COLUMN_WHOLELINE:
          449  +        wholelineIdx = i;
          450  +        idxNum |= 2;
          451  +        break;
          452  +    }
          453  +  }
          454  +  if( prefixIdx>=0 ){
          455  +    pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
          456  +    pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
          457  +  }
          458  +  if( wholelineIdx>=0 ){
          459  +    pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
          460  +    pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
          461  +  }
          462  +  pIdxInfo->idxNum = idxNum;
          463  +  pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
          464  +  pIdxInfo->estimatedRows = 500 - 100*nArg;
          465  +  return SQLITE_OK;
          466  +}
          467  +
          468  +/*
          469  +** This following structure defines all the methods for the 
          470  +** completion virtual table.
          471  +*/
          472  +static sqlite3_module completionModule = {
          473  +  0,                         /* iVersion */
          474  +  0,                         /* xCreate */
          475  +  completionConnect,         /* xConnect */
          476  +  completionBestIndex,       /* xBestIndex */
          477  +  completionDisconnect,      /* xDisconnect */
          478  +  0,                         /* xDestroy */
          479  +  completionOpen,            /* xOpen - open a cursor */
          480  +  completionClose,           /* xClose - close a cursor */
          481  +  completionFilter,          /* xFilter - configure scan constraints */
          482  +  completionNext,            /* xNext - advance a cursor */
          483  +  completionEof,             /* xEof - check for end of scan */
          484  +  completionColumn,          /* xColumn - read data */
          485  +  completionRowid,           /* xRowid - read data */
          486  +  0,                         /* xUpdate */
          487  +  0,                         /* xBegin */
          488  +  0,                         /* xSync */
          489  +  0,                         /* xCommit */
          490  +  0,                         /* xRollback */
          491  +  0,                         /* xFindMethod */
          492  +  0,                         /* xRename */
          493  +  0,                         /* xSavepoint */
          494  +  0,                         /* xRelease */
          495  +  0                          /* xRollbackTo */
          496  +};
          497  +
          498  +#endif /* SQLITE_OMIT_VIRTUALTABLE */
          499  +
          500  +int sqlite3CompletionVtabInit(sqlite3 *db){
          501  +  int rc = SQLITE_OK;
          502  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          503  +  rc = sqlite3_create_module(db, "completion", &completionModule, 0);
          504  +#endif
          505  +  return rc;
          506  +}
          507  +
          508  +#ifdef _WIN32
          509  +__declspec(dllexport)
          510  +#endif
          511  +int sqlite3_completion_init(
          512  +  sqlite3 *db, 
          513  +  char **pzErrMsg, 
          514  +  const sqlite3_api_routines *pApi
          515  +){
          516  +  int rc = SQLITE_OK;
          517  +  SQLITE_EXTENSION_INIT2(pApi);
          518  +  (void)(pzErrMsg);  /* Unused parameter */
          519  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          520  +  rc = sqlite3CompletionVtabInit(db);
          521  +#endif
          522  +  return rc;
          523  +}

Changes to ext/misc/fileio.c.

    28     28     sqlite3_value **argv
    29     29   ){
    30     30     const char *zName;
    31     31     FILE *in;
    32     32     long nIn;
    33     33     void *pBuf;
    34     34   
           35  +  (void)(argc);  /* Unused parameter */
    35     36     zName = (const char*)sqlite3_value_text(argv[0]);
    36     37     if( zName==0 ) return;
    37     38     in = fopen(zName, "rb");
    38     39     if( in==0 ) return;
    39     40     fseek(in, 0, SEEK_END);
    40     41     nIn = ftell(in);
    41     42     rewind(in);
................................................................................
    60     61     sqlite3_value **argv
    61     62   ){
    62     63     FILE *out;
    63     64     const char *z;
    64     65     sqlite3_int64 rc;
    65     66     const char *zFile;
    66     67   
           68  +  (void)(argc);  /* Unused parameter */
    67     69     zFile = (const char*)sqlite3_value_text(argv[0]);
    68     70     if( zFile==0 ) return;
    69     71     out = fopen(zFile, "wb");
    70     72     if( out==0 ) return;
    71     73     z = (const char*)sqlite3_value_blob(argv[1]);
    72     74     if( z==0 ){
    73     75       rc = 0;

Changes to ext/misc/remember.c.

    17     17   **
    18     18   ** This allows, for example, a counter to incremented and the original
    19     19   ** value retrieved, atomically, using a single statement:
    20     20   **
    21     21   **    UPDATE counterTab SET cnt=remember(cnt,$PTR)+1 WHERE id=$ID
    22     22   **
    23     23   ** Prepare the above statement once.  Then to use it, bind the address
    24         -** of the output variable to $PTR and the id of the counter to $ID and
           24  +** of the output variable to $PTR using sqlite3_bind_pointer() with a
           25  +** pointer type of "carray" and bind the id of the counter to $ID and
    25     26   ** run the prepared statement.
    26     27   **
           28  +** This implementation of the remember() function uses a "carray"
           29  +** pointer so that it can share pointers with the carray() extension.
           30  +**
    27     31   ** One can imagine doing similar things with floating-point values and
    28     32   ** strings, but this demonstration extension will stick to using just
    29     33   ** integers.
    30     34   */
    31     35   #include "sqlite3ext.h"
    32     36   SQLITE_EXTENSION_INIT1
    33     37   #include <assert.h>
................................................................................
    40     44   */
    41     45   static void rememberFunc(
    42     46     sqlite3_context *pCtx,
    43     47     int argc,
    44     48     sqlite3_value **argv
    45     49   ){
    46     50     sqlite3_int64 v;
    47         -  sqlite3_int64 ptr;
           51  +  sqlite3_int64 *ptr;
    48     52     assert( argc==2 );
    49     53     v = sqlite3_value_int64(argv[0]);
    50         -  ptr = sqlite3_value_int64(argv[1]);
    51         -  *((sqlite3_int64*)ptr) = v;
           54  +  ptr = sqlite3_value_pointer(argv[1], "carray");
           55  +  if( ptr ) *ptr = v;
    52     56     sqlite3_result_int64(pCtx, v);
    53     57   }
    54     58   
    55     59   #ifdef _WIN32
    56     60   __declspec(dllexport)
    57     61   #endif
    58     62   int sqlite3_remember_init(

Changes to ext/misc/stmt.c.

    25     25   #include "sqlite3ext.h"
    26     26   #endif
    27     27   SQLITE_EXTENSION_INIT1
    28     28   #include <assert.h>
    29     29   #include <string.h>
    30     30   
    31     31   #ifndef SQLITE_OMIT_VIRTUALTABLE
    32         -
    33         -/*
    34         -** The following macros are used to cast pointers to integers.
    35         -** The way you do this varies from one compiler
    36         -** to the next, so we have developed the following set of #if statements
    37         -** to generate appropriate macros for a wide range of compilers.
    38         -*/
    39         -#if defined(__PTRDIFF_TYPE__)  /* This case should work for GCC */
    40         -# define SQLITE_PTR_TO_INT64(X)  ((sqlite3_int64)(__PTRDIFF_TYPE__)(X))
    41         -#elif !defined(__GNUC__)       /* Works for compilers other than LLVM */
    42         -# define SQLITE_PTR_TO_INT64(X)  ((sqlite3_int64)(((char*)X)-(char*)0))
    43         -#elif defined(HAVE_STDINT_H)   /* Use this case if we have ANSI headers */
    44         -# define SQLITE_PTR_TO_INT64(X)  ((sqlite3_int64)(intptr_t)(X))
    45         -#else                          /* Generates a warning - but it always works */
    46         -# define SQLITE_PTR_TO_INT64(X)  ((sqlite3_int64)(X))
    47         -#endif
    48         -
    49     32   
    50     33   /* stmt_vtab is a subclass of sqlite3_vtab which will
    51     34   ** serve as the underlying representation of a stmt virtual table
    52     35   */
    53     36   typedef struct stmt_vtab stmt_vtab;
    54     37   struct stmt_vtab {
    55     38     sqlite3_vtab base;  /* Base class - must be first */
................................................................................
    66     49     sqlite3 *db;               /* Database connection for this cursor */
    67     50     sqlite3_stmt *pStmt;       /* Statement cursor is currently pointing at */
    68     51     sqlite3_int64 iRowid;      /* The rowid */
    69     52   };
    70     53   
    71     54   /*
    72     55   ** The stmtConnect() method is invoked to create a new
    73         -** stmt_vtab that describes the generate_stmt virtual table.
           56  +** stmt_vtab that describes the stmt virtual table.
    74     57   **
    75     58   ** Think of this routine as the constructor for stmt_vtab objects.
    76     59   **
    77     60   ** All this routine needs to do is:
    78     61   **
    79     62   **    (1) Allocate the stmt_vtab object and initialize all fields.
    80     63   **
    81     64   **    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
    82         -**        result set of queries against generate_stmt will look like.
           65  +**        result set of queries against stmt will look like.
    83     66   */
    84     67   static int stmtConnect(
    85     68     sqlite3 *db,
    86     69     void *pAux,
    87     70     int argc, const char *const*argv,
    88     71     sqlite3_vtab **ppVtab,
    89     72     char **pzErr
    90     73   ){
    91     74     stmt_vtab *pNew;
    92     75     int rc;
    93     76   
    94     77   /* Column numbers */
    95         -#define STMT_COLUMN_PTR     0   /* Numeric value of the statement pointer */
    96         -#define STMT_COLUMN_SQL     1   /* SQL for the statement */
    97         -#define STMT_COLUMN_NCOL    2   /* Number of result columns */
    98         -#define STMT_COLUMN_RO      3   /* True if read-only */
    99         -#define STMT_COLUMN_BUSY    4   /* True if currently busy */
   100         -#define STMT_COLUMN_NSCAN   5   /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
   101         -#define STMT_COLUMN_NSORT   6   /* SQLITE_STMTSTATUS_SORT */
   102         -#define STMT_COLUMN_NAIDX   7   /* SQLITE_STMTSTATUS_AUTOINDEX */
   103         -#define STMT_COLUMN_NSTEP   8   /* SQLITE_STMTSTATUS_VM_STEP */
   104         -#define STMT_COLUMN_REPREP  9   /* SQLITE_STMTSTATUS_REPREPARE */
   105         -#define STMT_COLUMN_RUN    10   /* SQLITE_STMTSTATUS_RUN */
   106         -#define STMT_COLUMN_MEM    11   /* SQLITE_STMTSTATUS_MEMUSED */
           78  +#define STMT_COLUMN_SQL     0   /* SQL for the statement */
           79  +#define STMT_COLUMN_NCOL    1   /* Number of result columns */
           80  +#define STMT_COLUMN_RO      2   /* True if read-only */
           81  +#define STMT_COLUMN_BUSY    3   /* True if currently busy */
           82  +#define STMT_COLUMN_NSCAN   4   /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
           83  +#define STMT_COLUMN_NSORT   5   /* SQLITE_STMTSTATUS_SORT */
           84  +#define STMT_COLUMN_NAIDX   6   /* SQLITE_STMTSTATUS_AUTOINDEX */
           85  +#define STMT_COLUMN_NSTEP   7   /* SQLITE_STMTSTATUS_VM_STEP */
           86  +#define STMT_COLUMN_REPREP  8   /* SQLITE_STMTSTATUS_REPREPARE */
           87  +#define STMT_COLUMN_RUN     9   /* SQLITE_STMTSTATUS_RUN */
           88  +#define STMT_COLUMN_MEM    10   /* SQLITE_STMTSTATUS_MEMUSED */
   107     89   
   108     90   
   109     91     rc = sqlite3_declare_vtab(db,
   110         -     "CREATE TABLE x(ptr,sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
           92  +     "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
   111     93                       "reprep,run,mem)");
   112     94     if( rc==SQLITE_OK ){
   113     95       pNew = sqlite3_malloc( sizeof(*pNew) );
   114     96       *ppVtab = (sqlite3_vtab*)pNew;
   115     97       if( pNew==0 ) return SQLITE_NOMEM;
   116     98       memset(pNew, 0, sizeof(*pNew));
   117     99       pNew->db = db;
................................................................................
   166    148   static int stmtColumn(
   167    149     sqlite3_vtab_cursor *cur,   /* The cursor */
   168    150     sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
   169    151     int i                       /* Which column to return */
   170    152   ){
   171    153     stmt_cursor *pCur = (stmt_cursor*)cur;
   172    154     switch( i ){
   173         -    case STMT_COLUMN_PTR: {
   174         -      sqlite3_result_int64(ctx, SQLITE_PTR_TO_INT64(pCur->pStmt));
   175         -      break;
   176         -    }
   177    155       case STMT_COLUMN_SQL: {
   178    156         sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
   179    157         break;
   180    158       }
   181    159       case STMT_COLUMN_NCOL: {
   182    160         sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
   183    161         break;
................................................................................
   243    221     pCur->pStmt = 0;
   244    222     pCur->iRowid = 0;
   245    223     return stmtNext(pVtabCursor);
   246    224   }
   247    225   
   248    226   /*
   249    227   ** SQLite will invoke this method one or more times while planning a query
   250         -** that uses the generate_stmt virtual table.  This routine needs to create
          228  +** that uses the stmt virtual table.  This routine needs to create
   251    229   ** a query plan for each invocation and compute an estimated cost for that
   252    230   ** plan.
   253    231   */
   254    232   static int stmtBestIndex(
   255    233     sqlite3_vtab *tab,
   256    234     sqlite3_index_info *pIdxInfo
   257    235   ){
................................................................................
   258    236     pIdxInfo->estimatedCost = (double)500;
   259    237     pIdxInfo->estimatedRows = 500;
   260    238     return SQLITE_OK;
   261    239   }
   262    240   
   263    241   /*
   264    242   ** This following structure defines all the methods for the 
   265         -** generate_stmt virtual table.
          243  +** stmt virtual table.
   266    244   */
   267    245   static sqlite3_module stmtModule = {
   268    246     0,                         /* iVersion */
   269    247     0,                         /* xCreate */
   270    248     stmtConnect,               /* xConnect */
   271    249     stmtBestIndex,             /* xBestIndex */
   272    250     stmtDisconnect,            /* xDisconnect */
................................................................................
   281    259     0,                         /* xUpdate */
   282    260     0,                         /* xBegin */
   283    261     0,                         /* xSync */
   284    262     0,                         /* xCommit */
   285    263     0,                         /* xRollback */
   286    264     0,                         /* xFindMethod */
   287    265     0,                         /* xRename */
          266  +  0,                         /* xSavepoint */
          267  +  0,                         /* xRelease */
          268  +  0,                         /* xRollbackTo */
   288    269   };
   289    270   
   290    271   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   291    272   
   292    273   int sqlite3StmtVtabInit(sqlite3 *db){
   293    274     int rc = SQLITE_OK;
   294    275   #ifndef SQLITE_OMIT_VIRTUALTABLE
   295         -  rc = sqlite3_create_module(db, "stmt", &stmtModule, 0);
          276  +  rc = sqlite3_create_module(db, "sqlite_stmt", &stmtModule, 0);
   296    277   #endif
   297    278     return rc;
   298    279   }
   299    280   
   300    281   #ifndef SQLITE_CORE
   301    282   #ifdef _WIN32
   302    283   __declspec(dllexport)

Added ext/misc/unionvtab.c.

            1  +/*
            2  +** 2017 July 15
            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 the "unionvtab" virtual
           14  +** table. This module provides read-only access to multiple tables, 
           15  +** possibly in multiple database files, via a single database object.
           16  +** The source tables must have the following characteristics:
           17  +**
           18  +**   * They must all be rowid tables (not VIRTUAL or WITHOUT ROWID
           19  +**     tables or views).
           20  +**
           21  +**   * Each table must have the same set of columns, declared in
           22  +**     the same order and with the same declared types.
           23  +**
           24  +**   * The tables must not feature a user-defined column named "_rowid_".
           25  +**
           26  +**   * Each table must contain a distinct range of rowid values.
           27  +**
           28  +** A "unionvtab" virtual table is created as follows:
           29  +**
           30  +**   CREATE VIRTUAL TABLE <name> USING unionvtab(<sql statement>);
           31  +**
           32  +** The implementation evalutes <sql statement> whenever a unionvtab virtual
           33  +** table is created or opened. It should return one row for each source
           34  +** database table. The four columns required of each row are:
           35  +**
           36  +**   1. The name of the database containing the table ("main" or "temp" or
           37  +**      the name of an attached database). Or NULL to indicate that all
           38  +**      databases should be searched for the table in the usual fashion.
           39  +**
           40  +**   2. The name of the database table.
           41  +**
           42  +**   3. The smallest rowid in the range of rowids that may be stored in the
           43  +**      database table (an integer).
           44  +**
           45  +**   4. The largest rowid in the range of rowids that may be stored in the
           46  +**      database table (an integer).
           47  +**
           48  +*/
           49  +
           50  +#include "sqlite3ext.h"
           51  +SQLITE_EXTENSION_INIT1
           52  +#include <assert.h>
           53  +#include <string.h>
           54  +
           55  +#ifndef SQLITE_OMIT_VIRTUALTABLE
           56  +
           57  +/*
           58  +** Largest and smallest possible 64-bit signed integers. These macros
           59  +** copied from sqliteInt.h.
           60  +*/
           61  +#ifndef LARGEST_INT64
           62  +# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
           63  +#endif
           64  +#ifndef SMALLEST_INT64
           65  +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
           66  +#endif
           67  +
           68  +typedef struct UnionCsr UnionCsr;
           69  +typedef struct UnionTab UnionTab;
           70  +typedef struct UnionSrc UnionSrc;
           71  +
           72  +/*
           73  +** Each source table (row returned by the initialization query) is 
           74  +** represented by an instance of the following structure stored in the
           75  +** UnionTab.aSrc[] array.
           76  +*/
           77  +struct UnionSrc {
           78  +  char *zDb;                      /* Database containing source table */
           79  +  char *zTab;                     /* Source table name */
           80  +  sqlite3_int64 iMin;             /* Minimum rowid */
           81  +  sqlite3_int64 iMax;             /* Maximum rowid */
           82  +};
           83  +
           84  +/*
           85  +** Virtual table  type for union vtab.
           86  +*/
           87  +struct UnionTab {
           88  +  sqlite3_vtab base;              /* Base class - must be first */
           89  +  sqlite3 *db;                    /* Database handle */
           90  +  int iPK;                        /* INTEGER PRIMARY KEY column, or -1 */
           91  +  int nSrc;                       /* Number of elements in the aSrc[] array */
           92  +  UnionSrc *aSrc;                 /* Array of source tables, sorted by rowid */
           93  +};
           94  +
           95  +/*
           96  +** Virtual table cursor type for union vtab.
           97  +*/
           98  +struct UnionCsr {
           99  +  sqlite3_vtab_cursor base;       /* Base class - must be first */
          100  +  sqlite3_stmt *pStmt;            /* SQL statement to run */
          101  +};
          102  +
          103  +/*
          104  +** If *pRc is other than SQLITE_OK when this function is called, it
          105  +** always returns NULL. Otherwise, it attempts to allocate and return
          106  +** a pointer to nByte bytes of zeroed memory. If the memory allocation
          107  +** is attempted but fails, NULL is returned and *pRc is set to 
          108  +** SQLITE_NOMEM.
          109  +*/
          110  +static void *unionMalloc(int *pRc, int nByte){
          111  +  void *pRet;
          112  +  assert( nByte>0 );
          113  +  if( *pRc==SQLITE_OK ){
          114  +    pRet = sqlite3_malloc(nByte);
          115  +    if( pRet ){
          116  +      memset(pRet, 0, nByte);
          117  +    }else{
          118  +      *pRc = SQLITE_NOMEM;
          119  +    }
          120  +  }else{
          121  +    pRet = 0;
          122  +  }
          123  +  return pRet;
          124  +}
          125  +
          126  +/*
          127  +** If *pRc is other than SQLITE_OK when this function is called, it
          128  +** always returns NULL. Otherwise, it attempts to allocate and return
          129  +** a copy of the nul-terminated string passed as the second argument.
          130  +** If the allocation is attempted but fails, NULL is returned and *pRc is 
          131  +** set to SQLITE_NOMEM.
          132  +*/
          133  +static char *unionStrdup(int *pRc, const char *zIn){
          134  +  char *zRet = 0;
          135  +  if( zIn ){
          136  +    int nByte = (int)strlen(zIn) + 1;
          137  +    zRet = unionMalloc(pRc, nByte);
          138  +    if( zRet ){
          139  +      memcpy(zRet, zIn, nByte);
          140  +    }
          141  +  }
          142  +  return zRet;
          143  +}
          144  +
          145  +/*
          146  +** If the first character of the string passed as the only argument to this
          147  +** function is one of the 4 that may be used as an open quote character
          148  +** in SQL, this function assumes that the input is a well-formed quoted SQL 
          149  +** string. In this case the string is dequoted in place.
          150  +**
          151  +** If the first character of the input is not an open quote, then this
          152  +** function is a no-op.
          153  +*/
          154  +static void unionDequote(char *z){
          155  +  if( z ){
          156  +    char q = z[0];
          157  +
          158  +    /* Set stack variable q to the close-quote character */
          159  +    if( q=='[' || q=='\'' || q=='"' || q=='`' ){
          160  +      int iIn = 1;
          161  +      int iOut = 0;
          162  +      if( q=='[' ) q = ']';  
          163  +      while( z[iIn] ){
          164  +        if( z[iIn]==q ){
          165  +          if( z[iIn+1]!=q ){
          166  +            /* Character iIn was the close quote. */
          167  +            iIn++;
          168  +            break;
          169  +          }else{
          170  +            /* Character iIn and iIn+1 form an escaped quote character. Skip
          171  +            ** the input cursor past both and copy a single quote character 
          172  +            ** to the output buffer. */
          173  +            iIn += 2;
          174  +            z[iOut++] = q;
          175  +          }
          176  +        }else{
          177  +          z[iOut++] = z[iIn++];
          178  +        }
          179  +      }
          180  +      z[iOut] = '\0';
          181  +    }
          182  +  }
          183  +}
          184  +
          185  +/*
          186  +** This function is a no-op if *pRc is set to other than SQLITE_OK when it
          187  +** is called. NULL is returned in this case.
          188  +**
          189  +** Otherwise, the SQL statement passed as the third argument is prepared
          190  +** against the database handle passed as the second. If the statement is
          191  +** successfully prepared, a pointer to the new statement handle is 
          192  +** returned. It is the responsibility of the caller to eventually free the
          193  +** statement by calling sqlite3_finalize(). Alternatively, if statement
          194  +** compilation fails, NULL is returned, *pRc is set to an SQLite error
          195  +** code and *pzErr may be set to an error message buffer allocated by
          196  +** sqlite3_malloc().
          197  +*/
          198  +static sqlite3_stmt *unionPrepare(
          199  +  int *pRc,                       /* IN/OUT: Error code */
          200  +  sqlite3 *db,                    /* Database handle */
          201  +  const char *zSql,               /* SQL statement to prepare */
          202  +  char **pzErr                    /* OUT: Error message */
          203  +){
          204  +  sqlite3_stmt *pRet = 0;
          205  +  if( *pRc==SQLITE_OK ){
          206  +    int rc = sqlite3_prepare_v2(db, zSql, -1, &pRet, 0);
          207  +    if( rc!=SQLITE_OK ){
          208  +      *pzErr = sqlite3_mprintf("sql error: %s", sqlite3_errmsg(db));
          209  +      *pRc = rc;
          210  +    }
          211  +  }
          212  +  return pRet;
          213  +}
          214  +
          215  +/*
          216  +** Like unionPrepare(), except prepare the results of vprintf(zFmt, ...)
          217  +** instead of a constant SQL string.
          218  +*/
          219  +static sqlite3_stmt *unionPreparePrintf(
          220  +  int *pRc,                       /* IN/OUT: Error code */
          221  +  char **pzErr,                   /* OUT: Error message */
          222  +  sqlite3 *db,                    /* Database handle */
          223  +  const char *zFmt,               /* printf() format string */
          224  +  ...                             /* Trailing printf args */
          225  +){
          226  +  sqlite3_stmt *pRet = 0;
          227  +  char *zSql;
          228  +  va_list ap;
          229  +  va_start(ap, zFmt);
          230  +
          231  +  zSql = sqlite3_vmprintf(zFmt, ap);
          232  +  if( *pRc==SQLITE_OK ){
          233  +    if( zSql==0 ){
          234  +      *pRc = SQLITE_NOMEM;
          235  +    }else{
          236  +      pRet = unionPrepare(pRc, db, zSql, pzErr);
          237  +    }
          238  +  }
          239  +  sqlite3_free(zSql);
          240  +
          241  +  va_end(ap);
          242  +  return pRet;
          243  +}
          244  +
          245  +
          246  +/*
          247  +** Call sqlite3_reset() on SQL statement pStmt. If *pRc is set to 
          248  +** SQLITE_OK when this function is called, then it is set to the
          249  +** value returned by sqlite3_reset() before this function exits.
          250  +** In this case, *pzErr may be set to point to an error message
          251  +** buffer allocated by sqlite3_malloc().
          252  +*/
          253  +static void unionReset(int *pRc, sqlite3_stmt *pStmt, char **pzErr){
          254  +  int rc = sqlite3_reset(pStmt);
          255  +  if( *pRc==SQLITE_OK ){
          256  +    *pRc = rc;
          257  +    if( rc ){
          258  +      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt)));
          259  +    }
          260  +  }
          261  +}
          262  +
          263  +/*
          264  +** Call sqlite3_finalize() on SQL statement pStmt. If *pRc is set to 
          265  +** SQLITE_OK when this function is called, then it is set to the
          266  +** value returned by sqlite3_finalize() before this function exits.
          267  +*/
          268  +static void unionFinalize(int *pRc, sqlite3_stmt *pStmt){
          269  +  int rc = sqlite3_finalize(pStmt);
          270  +  if( *pRc==SQLITE_OK ) *pRc = rc;
          271  +}
          272  +
          273  +/*
          274  +** xDisconnect method.
          275  +*/
          276  +static int unionDisconnect(sqlite3_vtab *pVtab){
          277  +  if( pVtab ){
          278  +    UnionTab *pTab = (UnionTab*)pVtab;
          279  +    int i;
          280  +    for(i=0; i<pTab->nSrc; i++){
          281  +      sqlite3_free(pTab->aSrc[i].zDb);
          282  +      sqlite3_free(pTab->aSrc[i].zTab);
          283  +    }
          284  +    sqlite3_free(pTab->aSrc);
          285  +    sqlite3_free(pTab);
          286  +  }
          287  +  return SQLITE_OK;
          288  +}
          289  +
          290  +/*
          291  +** This function is a no-op if *pRc is other than SQLITE_OK when it is
          292  +** called. In this case it returns NULL.
          293  +**
          294  +** Otherwise, this function checks that the source table passed as the
          295  +** second argument (a) exists, (b) is not a view and (c) has a column 
          296  +** named "_rowid_" of type "integer" that is the primary key.
          297  +** If this is not the case, *pRc is set to SQLITE_ERROR and NULL is
          298  +** returned.
          299  +**
          300  +** Finally, if the source table passes the checks above, a nul-terminated
          301  +** string describing the column names and types belonging to the source
          302  +** table is returned. Tables with the same set of column names and types 
          303  +** cause this function to return identical strings. Is is the responsibility
          304  +** of the caller to free the returned string using sqlite3_free() when
          305  +** it is no longer required.
          306  +*/
          307  +static char *unionSourceToStr(
          308  +  int *pRc,                       /* IN/OUT: Error code */
          309  +  sqlite3 *db,                    /* Database handle */
          310  +  UnionSrc *pSrc,                 /* Source table to test */
          311  +  sqlite3_stmt *pStmt,
          312  +  char **pzErr                    /* OUT: Error message */
          313  +){
          314  +  char *zRet = 0;
          315  +  if( *pRc==SQLITE_OK ){
          316  +    int bPk = 0;
          317  +    const char *zType = 0;
          318  +    int rc;
          319  +
          320  +    sqlite3_table_column_metadata(
          321  +        db, pSrc->zDb, pSrc->zTab, "_rowid_", &zType, 0, 0, &bPk, 0
          322  +    );
          323  +    rc = sqlite3_errcode(db);
          324  +    if( rc==SQLITE_ERROR 
          325  +     || (rc==SQLITE_OK && (!bPk || sqlite3_stricmp("integer", zType)))
          326  +    ){
          327  +      rc = SQLITE_ERROR;
          328  +      *pzErr = sqlite3_mprintf("no such rowid table: %s%s%s",
          329  +          (pSrc->zDb ? pSrc->zDb : ""),
          330  +          (pSrc->zDb ? "." : ""),
          331  +          pSrc->zTab
          332  +      );
          333  +    }
          334  +
          335  +    if( rc==SQLITE_OK ){
          336  +      sqlite3_bind_text(pStmt, 1, pSrc->zTab, -1, SQLITE_STATIC);
          337  +      sqlite3_bind_text(pStmt, 2, pSrc->zDb, -1, SQLITE_STATIC);
          338  +      if( SQLITE_ROW==sqlite3_step(pStmt) ){
          339  +        zRet = unionStrdup(&rc, (const char*)sqlite3_column_text(pStmt, 0));
          340  +      }
          341  +      unionReset(&rc, pStmt, pzErr);
          342  +    }
          343  +
          344  +    *pRc = rc;
          345  +  }
          346  +
          347  +  return zRet;
          348  +}
          349  +
          350  +/*
          351  +** Check that all configured source tables exist and have the same column
          352  +** names and datatypes. If this is not the case, or if some other error
          353  +** occurs, return an SQLite error code. In this case *pzErr may be set
          354  +** to point to an error message buffer allocated by sqlite3_mprintf().
          355  +** Or, if no problems regarding the source tables are detected and no
          356  +** other error occurs, SQLITE_OK is returned.
          357  +*/
          358  +static int unionSourceCheck(UnionTab *pTab, char **pzErr){
          359  +  const char *zSql = 
          360  +      "SELECT group_concat(quote(name) || '.' || quote(type)) "
          361  +      "FROM pragma_table_info(?, ?)";
          362  +  int rc = SQLITE_OK;
          363  +
          364  +  if( pTab->nSrc==0 ){
          365  +    *pzErr = sqlite3_mprintf("no source tables configured");
          366  +    rc = SQLITE_ERROR;
          367  +  }else{
          368  +    sqlite3_stmt *pStmt = 0;
          369  +    char *z0 = 0;
          370  +    int i;
          371  +
          372  +    pStmt = unionPrepare(&rc, pTab->db, zSql, pzErr);
          373  +    if( rc==SQLITE_OK ){
          374  +      z0 = unionSourceToStr(&rc, pTab->db, &pTab->aSrc[0], pStmt, pzErr);
          375  +    }
          376  +    for(i=1; i<pTab->nSrc; i++){
          377  +      char *z = unionSourceToStr(&rc, pTab->db, &pTab->aSrc[i], pStmt, pzErr);
          378  +      if( rc==SQLITE_OK && sqlite3_stricmp(z, z0) ){
          379  +        *pzErr = sqlite3_mprintf("source table schema mismatch");
          380  +        rc = SQLITE_ERROR;
          381  +      }
          382  +      sqlite3_free(z);
          383  +    }
          384  +
          385  +    unionFinalize(&rc, pStmt);
          386  +    sqlite3_free(z0);
          387  +  }
          388  +  return rc;
          389  +}
          390  +
          391  +/* 
          392  +** xConnect/xCreate method.
          393  +**
          394  +** The argv[] array contains the following:
          395  +**
          396  +**   argv[0]   -> module name  ("unionvtab")
          397  +**   argv[1]   -> database name
          398  +**   argv[2]   -> table name
          399  +**   argv[3]   -> SQL statement
          400  +*/
          401  +static int unionConnect(
          402  +  sqlite3 *db,
          403  +  void *pAux,
          404  +  int argc, const char *const*argv,
          405  +  sqlite3_vtab **ppVtab,
          406  +  char **pzErr
          407  +){
          408  +  UnionTab *pTab = 0;
          409  +  int rc = SQLITE_OK;
          410  +
          411  +  (void)pAux;   /* Suppress harmless 'unused parameter' warning */
          412  +  if( sqlite3_stricmp("temp", argv[1]) ){
          413  +    /* unionvtab tables may only be created in the temp schema */
          414  +    *pzErr = sqlite3_mprintf("unionvtab tables must be created in TEMP schema");
          415  +    rc = SQLITE_ERROR;
          416  +  }else if( argc!=4 ){
          417  +    *pzErr = sqlite3_mprintf("wrong number of arguments for unionvtab");
          418  +    rc = SQLITE_ERROR;
          419  +  }else{
          420  +    int nAlloc = 0;               /* Allocated size of pTab->aSrc[] */
          421  +    sqlite3_stmt *pStmt = 0;      /* Argument statement */
          422  +    char *zArg = unionStrdup(&rc, argv[3]);      /* Copy of argument to CVT */
          423  +
          424  +    /* Prepare the SQL statement. Instead of executing it directly, sort
          425  +    ** the results by the "minimum rowid" field. This makes it easier to
          426  +    ** check that there are no rowid range overlaps between source tables 
          427  +    ** and that the UnionTab.aSrc[] array is always sorted by rowid.  */
          428  +    unionDequote(zArg);
          429  +    pStmt = unionPreparePrintf(&rc, pzErr, db, 
          430  +        "SELECT * FROM (%z) ORDER BY 3", zArg
          431  +    );
          432  +
          433  +    /* Allocate the UnionTab structure */
          434  +    pTab = unionMalloc(&rc, sizeof(UnionTab));
          435  +
          436  +    /* Iterate through the rows returned by the SQL statement specified
          437  +    ** as an argument to the CREATE VIRTUAL TABLE statement. */
          438  +    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
          439  +      const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
          440  +      const char *zTab = (const char*)sqlite3_column_text(pStmt, 1);
          441  +      sqlite3_int64 iMin = sqlite3_column_int64(pStmt, 2);
          442  +      sqlite3_int64 iMax = sqlite3_column_int64(pStmt, 3);
          443  +      UnionSrc *pSrc;
          444  +
          445  +      /* Grow the pTab->aSrc[] array if required. */
          446  +      if( nAlloc<=pTab->nSrc ){
          447  +        int nNew = nAlloc ? nAlloc*2 : 8;
          448  +        UnionSrc *aNew = (UnionSrc*)sqlite3_realloc(
          449  +            pTab->aSrc, nNew*sizeof(UnionSrc)
          450  +        );
          451  +        if( aNew==0 ){
          452  +          rc = SQLITE_NOMEM;
          453  +          break;
          454  +        }else{
          455  +          memset(&aNew[pTab->nSrc], 0, (nNew-pTab->nSrc)*sizeof(UnionSrc));
          456  +          pTab->aSrc = aNew;
          457  +          nAlloc = nNew;
          458  +        }
          459  +      }
          460  +
          461  +      /* Check for problems with the specified range of rowids */
          462  +      if( iMax<iMin || (pTab->nSrc>0 && iMin<=pTab->aSrc[pTab->nSrc-1].iMax) ){
          463  +        *pzErr = sqlite3_mprintf("rowid range mismatch error");
          464  +        rc = SQLITE_ERROR;
          465  +      }
          466  +
          467  +      pSrc = &pTab->aSrc[pTab->nSrc++];
          468  +      pSrc->zDb = unionStrdup(&rc, zDb);
          469  +      pSrc->zTab = unionStrdup(&rc, zTab);
          470  +      pSrc->iMin = iMin;
          471  +      pSrc->iMax = iMax;
          472  +    }
          473  +    unionFinalize(&rc, pStmt);
          474  +    pStmt = 0;
          475  +
          476  +    /* Verify that all source tables exist and have compatible schemas. */
          477  +    if( rc==SQLITE_OK ){
          478  +      pTab->db = db;
          479  +      rc = unionSourceCheck(pTab, pzErr);
          480  +    }
          481  +
          482  +    /* Compose a CREATE TABLE statement and pass it to declare_vtab() */
          483  +    if( rc==SQLITE_OK ){
          484  +      pStmt = unionPreparePrintf(&rc, pzErr, db, "SELECT "
          485  +          "'CREATE TABLE xyz('"
          486  +          "    || group_concat(quote(name) || ' ' || type, ', ')"
          487  +          "    || ')',"
          488  +          "max((cid+1) * (type='INTEGER' COLLATE nocase AND pk=1))-1 "
          489  +          "FROM pragma_table_info(%Q, ?)", 
          490  +          pTab->aSrc[0].zTab, pTab->aSrc[0].zDb
          491  +      );
          492  +    }
          493  +    if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
          494  +      const char *zDecl = (const char*)sqlite3_column_text(pStmt, 0);
          495  +      rc = sqlite3_declare_vtab(db, zDecl);
          496  +      pTab->iPK = sqlite3_column_int(pStmt, 1);
          497  +    }
          498  +
          499  +    unionFinalize(&rc, pStmt);
          500  +  }
          501  +
          502  +  if( rc!=SQLITE_OK ){
          503  +    unionDisconnect((sqlite3_vtab*)pTab);
          504  +    pTab = 0;
          505  +  }
          506  +
          507  +  *ppVtab = (sqlite3_vtab*)pTab;
          508  +  return rc;
          509  +}
          510  +
          511  +
          512  +/*
          513  +** xOpen
          514  +*/
          515  +static int unionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
          516  +  UnionCsr *pCsr;
          517  +  int rc = SQLITE_OK;
          518  +  (void)p;  /* Suppress harmless warning */
          519  +  pCsr = (UnionCsr*)unionMalloc(&rc, sizeof(UnionCsr));
          520  +  *ppCursor = &pCsr->base;
          521  +  return rc;
          522  +}
          523  +
          524  +/*
          525  +** xClose
          526  +*/
          527  +static int unionClose(sqlite3_vtab_cursor *cur){
          528  +  UnionCsr *pCsr = (UnionCsr*)cur;
          529  +  sqlite3_finalize(pCsr->pStmt);
          530  +  sqlite3_free(pCsr);
          531  +  return SQLITE_OK;
          532  +}
          533  +
          534  +
          535  +/*
          536  +** xNext
          537  +*/
          538  +static int unionNext(sqlite3_vtab_cursor *cur){
          539  +  UnionCsr *pCsr = (UnionCsr*)cur;
          540  +  int rc;
          541  +  assert( pCsr->pStmt );
          542  +  if( sqlite3_step(pCsr->pStmt)!=SQLITE_ROW ){
          543  +    rc = sqlite3_finalize(pCsr->pStmt);
          544  +    pCsr->pStmt = 0;
          545  +  }else{
          546  +    rc = SQLITE_OK;
          547  +  }
          548  +  return rc;
          549  +}
          550  +
          551  +/*
          552  +** xColumn
          553  +*/
          554  +static int unionColumn(
          555  +  sqlite3_vtab_cursor *cur,
          556  +  sqlite3_context *ctx,
          557  +  int i
          558  +){
          559  +  UnionCsr *pCsr = (UnionCsr*)cur;
          560  +  sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, i+1));
          561  +  return SQLITE_OK;
          562  +}
          563  +
          564  +/*
          565  +** xRowid
          566  +*/
          567  +static int unionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          568  +  UnionCsr *pCsr = (UnionCsr*)cur;
          569  +  *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
          570  +  return SQLITE_OK;
          571  +}
          572  +
          573  +/*
          574  +** xEof
          575  +*/
          576  +static int unionEof(sqlite3_vtab_cursor *cur){
          577  +  UnionCsr *pCsr = (UnionCsr*)cur;
          578  +  return pCsr->pStmt==0;
          579  +}
          580  +
          581  +/*
          582  +** xFilter
          583  +*/
          584  +static int unionFilter(
          585  +  sqlite3_vtab_cursor *pVtabCursor, 
          586  +  int idxNum, const char *idxStr,
          587  +  int argc, sqlite3_value **argv
          588  +){
          589  +  UnionTab *pTab = (UnionTab*)(pVtabCursor->pVtab);
          590  +  UnionCsr *pCsr = (UnionCsr*)pVtabCursor;
          591  +  int rc = SQLITE_OK;
          592  +  int i;
          593  +  char *zSql = 0;
          594  +  int bZero = 0;
          595  +
          596  +  sqlite3_int64 iMin = SMALLEST_INT64;
          597  +  sqlite3_int64 iMax = LARGEST_INT64;
          598  +
          599  +  assert( idxNum==0 
          600  +       || idxNum==SQLITE_INDEX_CONSTRAINT_EQ
          601  +       || idxNum==SQLITE_INDEX_CONSTRAINT_LE
          602  +       || idxNum==SQLITE_INDEX_CONSTRAINT_GE
          603  +       || idxNum==SQLITE_INDEX_CONSTRAINT_LT
          604  +       || idxNum==SQLITE_INDEX_CONSTRAINT_GT
          605  +       || idxNum==(SQLITE_INDEX_CONSTRAINT_GE|SQLITE_INDEX_CONSTRAINT_LE)
          606  +  );
          607  +
          608  +  (void)idxStr;  /* Suppress harmless warning */
          609  +  
          610  +  if( idxNum==SQLITE_INDEX_CONSTRAINT_EQ ){
          611  +    assert( argc==1 );
          612  +    iMin = iMax = sqlite3_value_int64(argv[0]);
          613  +  }else{
          614  +
          615  +    if( idxNum & (SQLITE_INDEX_CONSTRAINT_LE|SQLITE_INDEX_CONSTRAINT_LT) ){
          616  +      assert( argc>=1 );
          617  +      iMax = sqlite3_value_int64(argv[0]);
          618  +      if( idxNum & SQLITE_INDEX_CONSTRAINT_LT ){
          619  +        if( iMax==SMALLEST_INT64 ){
          620  +          bZero = 1;
          621  +        }else{
          622  +          iMax--;
          623  +        }
          624  +      }
          625  +    }
          626  +
          627  +    if( idxNum & (SQLITE_INDEX_CONSTRAINT_GE|SQLITE_INDEX_CONSTRAINT_GT) ){
          628  +      assert( argc>=1 );
          629  +      iMin = sqlite3_value_int64(argv[argc-1]);
          630  +      if( idxNum & SQLITE_INDEX_CONSTRAINT_GT ){
          631  +        if( iMin==LARGEST_INT64 ){
          632  +          bZero = 1;
          633  +        }else{
          634  +          iMin++;
          635  +        }
          636  +      }
          637  +    }
          638  +  }
          639  +
          640  +  sqlite3_finalize(pCsr->pStmt);
          641  +  pCsr->pStmt = 0;
          642  +  if( bZero ){
          643  +    return SQLITE_OK;
          644  +  }
          645  +
          646  +  for(i=0; i<pTab->nSrc; i++){
          647  +    UnionSrc *pSrc = &pTab->aSrc[i];
          648  +    if( iMin>pSrc->iMax || iMax<pSrc->iMin ){
          649  +      continue;
          650  +    }
          651  +
          652  +    zSql = sqlite3_mprintf("%z%sSELECT rowid, * FROM %s%q%s%Q"
          653  +        , zSql
          654  +        , (zSql ? " UNION ALL " : "")
          655  +        , (pSrc->zDb ? "'" : "")
          656  +        , (pSrc->zDb ? pSrc->zDb : "")
          657  +        , (pSrc->zDb ? "'." : "")
          658  +        , pSrc->zTab
          659  +    );
          660  +    if( zSql==0 ){
          661  +      rc = SQLITE_NOMEM;
          662  +      break;
          663  +    }
          664  +
          665  +    if( iMin==iMax ){
          666  +      zSql = sqlite3_mprintf("%z WHERE rowid=%lld", zSql, iMin);
          667  +    }else{
          668  +      const char *zWhere = "WHERE";
          669  +      if( iMin!=SMALLEST_INT64 && iMin>pSrc->iMin ){
          670  +        zSql = sqlite3_mprintf("%z WHERE rowid>=%lld", zSql, iMin);
          671  +        zWhere = "AND";
          672  +      }
          673  +      if( iMax!=LARGEST_INT64 && iMax<pSrc->iMax ){
          674  +        zSql = sqlite3_mprintf("%z %s rowid<=%lld", zSql, zWhere, iMax);
          675  +      }
          676  +    }
          677  +  }
          678  +
          679  +
          680  +  if( zSql==0 ) return rc;
          681  +  pCsr->pStmt = unionPrepare(&rc, pTab->db, zSql, &pTab->base.zErrMsg);
          682  +  sqlite3_free(zSql);
          683  +  if( rc!=SQLITE_OK ) return rc;
          684  +  return unionNext(pVtabCursor);
          685  +}
          686  +
          687  +/*
          688  +** xBestIndex.
          689  +**
          690  +** This implementation searches for constraints on the rowid field. EQ, 
          691  +** LE, LT, GE and GT are handled.
          692  +**
          693  +** If there is an EQ comparison, then idxNum is set to INDEX_CONSTRAINT_EQ.
          694  +** In this case the only argument passed to xFilter is the rhs of the ==
          695  +** operator.
          696  +**
          697  +** Otherwise, if an LE or LT constraint is found, then the INDEX_CONSTRAINT_LE
          698  +** or INDEX_CONSTRAINT_LT (but not both) bit is set in idxNum. The first
          699  +** argument to xFilter is the rhs of the <= or < operator.  Similarly, if 
          700  +** an GE or GT constraint is found, then the INDEX_CONSTRAINT_GE or
          701  +** INDEX_CONSTRAINT_GT bit is set in idxNum. The rhs of the >= or > operator
          702  +** is passed as either the first or second argument to xFilter, depending
          703  +** on whether or not there is also a LT|LE constraint.
          704  +*/
          705  +static int unionBestIndex(
          706  +  sqlite3_vtab *tab,
          707  +  sqlite3_index_info *pIdxInfo
          708  +){
          709  +  UnionTab *pTab = (UnionTab*)tab;
          710  +  int iEq = -1;
          711  +  int iLt = -1;
          712  +  int iGt = -1;
          713  +  int i;
          714  +
          715  +  for(i=0; i<pIdxInfo->nConstraint; i++){
          716  +    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
          717  +    if( p->usable && (p->iColumn<0 || p->iColumn==pTab->iPK) ){
          718  +      switch( p->op ){
          719  +        case SQLITE_INDEX_CONSTRAINT_EQ:
          720  +          iEq = i;
          721  +          break;
          722  +        case SQLITE_INDEX_CONSTRAINT_LE:
          723  +        case SQLITE_INDEX_CONSTRAINT_LT:
          724  +          iLt = i;
          725  +          break;
          726  +        case SQLITE_INDEX_CONSTRAINT_GE:
          727  +        case SQLITE_INDEX_CONSTRAINT_GT:
          728  +          iGt = i;
          729  +          break;
          730  +      }
          731  +    }
          732  +  }
          733  +
          734  +  if( iEq>=0 ){
          735  +    pIdxInfo->estimatedRows = 1;
          736  +    pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
          737  +    pIdxInfo->estimatedCost = 3.0;
          738  +    pIdxInfo->idxNum = SQLITE_INDEX_CONSTRAINT_EQ;
          739  +    pIdxInfo->aConstraintUsage[iEq].argvIndex = 1;
          740  +    pIdxInfo->aConstraintUsage[iEq].omit = 1;
          741  +  }else{
          742  +    int iCons = 1;
          743  +    int idxNum = 0;
          744  +    sqlite3_int64 nRow = 1000000;
          745  +    if( iLt>=0 ){
          746  +      nRow = nRow / 2;
          747  +      pIdxInfo->aConstraintUsage[iLt].argvIndex = iCons++;
          748  +      pIdxInfo->aConstraintUsage[iLt].omit = 1;
          749  +      idxNum |= pIdxInfo->aConstraint[iLt].op;
          750  +    }
          751  +    if( iGt>=0 ){
          752  +      nRow = nRow / 2;
          753  +      pIdxInfo->aConstraintUsage[iGt].argvIndex = iCons++;
          754  +      pIdxInfo->aConstraintUsage[iGt].omit = 1;
          755  +      idxNum |= pIdxInfo->aConstraint[iGt].op;
          756  +    }
          757  +    pIdxInfo->estimatedRows = nRow;
          758  +    pIdxInfo->estimatedCost = 3.0 * (double)nRow;
          759  +    pIdxInfo->idxNum = idxNum;
          760  +  }
          761  +
          762  +  return SQLITE_OK;
          763  +}
          764  +
          765  +/*
          766  +** Register the unionvtab virtual table module with database handle db.
          767  +*/
          768  +static int createUnionVtab(sqlite3 *db){
          769  +  static sqlite3_module unionModule = {
          770  +    0,                            /* iVersion */
          771  +    unionConnect,
          772  +    unionConnect,
          773  +    unionBestIndex,               /* xBestIndex - query planner */
          774  +    unionDisconnect, 
          775  +    unionDisconnect,
          776  +    unionOpen,                    /* xOpen - open a cursor */
          777  +    unionClose,                   /* xClose - close a cursor */
          778  +    unionFilter,                  /* xFilter - configure scan constraints */
          779  +    unionNext,                    /* xNext - advance a cursor */
          780  +    unionEof,                     /* xEof - check for end of scan */
          781  +    unionColumn,                  /* xColumn - read data */
          782  +    unionRowid,                   /* xRowid - read data */
          783  +    0,                            /* xUpdate */
          784  +    0,                            /* xBegin */
          785  +    0,                            /* xSync */
          786  +    0,                            /* xCommit */
          787  +    0,                            /* xRollback */
          788  +    0,                            /* xFindMethod */
          789  +    0,                            /* xRename */
          790  +    0,                            /* xSavepoint */
          791  +    0,                            /* xRelease */
          792  +    0                             /* xRollbackTo */
          793  +  };
          794  +
          795  +  return sqlite3_create_module(db, "unionvtab", &unionModule, 0);
          796  +}
          797  +
          798  +#endif /* SQLITE_OMIT_VIRTUALTABLE */
          799  +
          800  +#ifdef _WIN32
          801  +__declspec(dllexport)
          802  +#endif
          803  +int sqlite3_unionvtab_init(
          804  +  sqlite3 *db, 
          805  +  char **pzErrMsg, 
          806  +  const sqlite3_api_routines *pApi
          807  +){
          808  +  int rc = SQLITE_OK;
          809  +  SQLITE_EXTENSION_INIT2(pApi);
          810  +  (void)pzErrMsg;  /* Suppress harmless warning */
          811  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          812  +  rc = createUnionVtab(db);
          813  +#endif
          814  +  return rc;
          815  +}

Changes to ext/rbu/rbuA.test.

    66     66     rbu close
    67     67   } {SQLITE_OK}
    68     68   
    69     69   do_test 2.1 {
    70     70     sqlite3 db test.db
    71     71     db eval {PRAGMA journal_mode = wal}
    72     72     db close
    73         -  breakpoint
    74     73     sqlite3rbu rbu test.db rbu.db
    75     74     rbu step
    76     75   } {SQLITE_ERROR}
    77     76   
    78     77   do_test 2.2 {
    79     78     list [catch { rbu close } msg] $msg
    80     79   } {1 {SQLITE_ERROR - cannot update wal mode database}}
    81     80   
    82     81   
    83     82   finish_test
    84     83   

Changes to ext/rbu/rbucrash.test.

    49     49   # update using many calls to sqlite3rbu_step() on a single rbu handle
    50     50   # as required to apply it using a series of rbu handles, on each of 
    51     51   # which sqlite3rbu_step() is called once.
    52     52   #
    53     53   do_test 1.1 {
    54     54     db_restore
    55     55     sqlite3rbu rbu test.db test.db2
    56         -  breakpoint
    57     56     set nStep 0
    58     57     while {[rbu step]=="SQLITE_OK"} { incr nStep }
    59     58     rbu close
    60     59   } {SQLITE_DONE}
    61     60   set rbu_num_steps $nStep
    62     61   do_test 1.2 {
    63     62     db_restore

Changes to ext/rtree/rtree1.test.

   334    334   
   335    335   # An error midway through a rename operation.
   336    336   do_test rtree-7.2.1 {
   337    337     execsql { 
   338    338       CREATE TABLE t4_node(a);
   339    339     }
   340    340     catchsql { ALTER TABLE "abc 123" RENAME TO t4 }
   341         -} {1 {SQL logic error or missing database}}
          341  +} {1 {SQL logic error}}
   342    342   do_test rtree-7.2.2 {
   343    343     execsql_intout { SELECT * FROM "abc 123" }
   344    344   } {1 2 3 4 5 6 7}
   345    345   do_test rtree-7.2.3 {
   346    346     execsql { 
   347    347       DROP TABLE t4_node;
   348    348       CREATE TABLE t4_rowid(a);
   349    349     }
   350    350     catchsql { ALTER TABLE "abc 123" RENAME TO t4 }
   351         -} {1 {SQL logic error or missing database}}
          351  +} {1 {SQL logic error}}
   352    352   do_test rtree-7.2.4 {
   353    353     db close
   354    354     sqlite3 db test.db
   355    355     execsql_intout { SELECT * FROM "abc 123" }
   356    356   } {1 2 3 4 5 6 7}
   357    357   do_test rtree-7.2.5 {
   358    358     execsql { DROP TABLE t4_rowid }
................................................................................
   600    600     CREATE VIRTUAL TABLE rt USING rtree(id, x1,x2, y1,y2);
   601    601     CREATE TEMP TABLE t13(a, b, c);
   602    602   }
   603    603   do_execsql_test 15.1 {
   604    604     BEGIN;
   605    605     INSERT INTO rt VALUES(1,2,3,4,5);
   606    606   }
   607         -breakpoint
   608    607   do_execsql_test 15.2 {
   609    608     DROP TABLE t13;
   610    609     COMMIT;
   611    610   }
   612    611   
   613    612   finish_test

Changes to ext/rtree/rtree8.test.

   125    125   #-------------------------------------------------------------------------
   126    126   # Test that trying to use the MATCH operator with the r-tree module does
   127    127   # not confuse it. 
   128    128   #
   129    129   populate_t1 10
   130    130   do_catchsql_test rtree8-3.1 { 
   131    131     SELECT * FROM t1 WHERE x1 MATCH '1234'
   132         -} {1 {SQL logic error or missing database}}
          132  +} {1 {SQL logic error}}
   133    133   
   134    134   #-------------------------------------------------------------------------
   135    135   # Test a couple of invalid arguments to rtreedepth().
   136    136   #
   137    137   do_catchsql_test rtree8-4.1 {
   138    138     SELECT rtreedepth('hello world')
   139    139   } {1 {Invalid argument to rtreedepth()}}

Changes to ext/rtree/rtree9.test.

    65     65   do_execsql_test rtree9-3.3 {
    66     66     SELECT id FROM rt32 WHERE id MATCH cube(5.5, 5.5, 5.5, 1, 1, 1) ORDER BY id;
    67     67   } {555 556 565 566 655 656 665 666}
    68     68   
    69     69   
    70     70   do_catchsql_test rtree9-4.1 {
    71     71     SELECT id FROM rt32 WHERE id MATCH cube(5.5, 5.5, 1, 1, 1) ORDER BY id;
    72         -} {1 {SQL logic error or missing database}}
           72  +} {1 {SQL logic error}}
    73     73   for {set x 2} {$x<200} {incr x 2} {
    74     74     do_catchsql_test rtree9-4.2.[expr $x/2] {
    75     75       SELECT id FROM rt WHERE id MATCH randomblob($x)
    76         -  } {1 {SQL logic error or missing database}}
           76  +  } {1 {SQL logic error}}
    77     77   }
    78     78   do_catchsql_test rtree9-4.3 {
    79     79     SELECT id FROM rt WHERE id MATCH CAST( 
    80     80       (cube(5.5, 5.5, 5.5, 1, 1, 1) || X'1234567812345678') AS blob 
    81     81     )
    82         -} {1 {SQL logic error or missing database}}
           82  +} {1 {SQL logic error}}
    83     83   
    84     84   
    85     85   #-------------------------------------------------------------------------
    86     86   # Test the example 2d "circle" geometry callback.
    87     87   #
    88     88   register_circle_geom db
    89     89   

Changes to ext/rtree/rtreeD.test.

    49     49   
    50     50     do_test 1.$tn.4 {
    51     51       list [catch { sql2 { SELECT * FROM rt } } msg] $msg
    52     52     } {1 {database is locked}}
    53     53   }
    54     54   
    55     55   finish_test
    56         -
    57         -

Changes to ext/session/session1.test.

   532    532     sqlite3session S db main
   533    533     S attach $tblname
   534    534     execsql " 
   535    535       INSERT INTO $tblname VALUES('uvw', 'abc');
   536    536       DELETE FROM $tblname WHERE a = 'xyz';
   537    537     "
   538    538   } {}
   539         -breakpoint
   540    539   do_changeset_test $tn.10.1.2 S "
   541    540     {INSERT $tblname 0 X. {} {t uvw t abc}}
   542    541     {DELETE $tblname 0 X. {t xyz t def} {}}
   543    542   "
   544    543   do_test $tn.10.1.4 { S delete } {}
   545    544   
   546    545   #---------------------------------------------------------------
................................................................................
   573    572     sqlite3session S db main
   574    573     S attach $tblname
   575    574     execsql " 
   576    575       INSERT INTO $tblname VALUES('uvw', 'abc');
   577    576       DELETE FROM $tblname WHERE a = 'xyz';
   578    577     "
   579    578   } {}
   580         -breakpoint
   581    579   do_changeset_test $tn.10.1.2 S "
   582    580     {INSERT $tblname 0 X. {} {t uvw t abc}}
   583    581     {DELETE $tblname 0 X. {t xyz t def} {}}
   584    582   "
   585    583   do_test $tn.10.1.4 { S delete } {}
   586    584   
   587    585   #-------------------------------------------------------------------------

Changes to ext/session/sessionE.test.

    38     38   do_execsql_test 1.0 {
    39     39     CREATE TABLE t1(a, b);
    40     40     CREATE TABLE t2(a PRIMARY KEY, b);
    41     41   }
    42     42   do_test 1.1 {
    43     43     sqlite3session S db main
    44     44     S attach *
    45         -  breakpoint
    46     45     execsql {
    47     46       INSERT INTO t1 VALUES(1, 2);
    48     47       INSERT INTO t2 VALUES(1, 2);
    49     48     }
    50     49   } {}
    51     50   do_changeset_test 1.2 S {
    52     51     {INSERT t2 0 X. {} {i 1 i 2}}
................................................................................
    58     57     CREATE TABLE t1(a, b);
    59     58     CREATE TABLE t2(a PRIMARY KEY, b);
    60     59   }
    61     60   do_test 2.1 {
    62     61     sqlite3session S db main
    63     62     S attach t1
    64     63     S attach t2
    65         -  breakpoint
    66     64     execsql {
    67     65       INSERT INTO t1 VALUES(3, 4);
    68     66       INSERT INTO t2 VALUES(3, 4);
    69     67       INSERT INTO t1 VALUES(5, 6);
    70     68       INSERT INTO t2 VALUES(5, 6);
    71     69     }
    72     70   } {}

Changes to main.mk.

   340    340     $(TOP)/ext/misc/nextchar.c \
   341    341     $(TOP)/ext/misc/percentile.c \
   342    342     $(TOP)/ext/misc/regexp.c \
   343    343     $(TOP)/ext/misc/remember.c \
   344    344     $(TOP)/ext/misc/series.c \
   345    345     $(TOP)/ext/misc/spellfix.c \
   346    346     $(TOP)/ext/misc/totype.c \
          347  +  $(TOP)/ext/misc/unionvtab.c \
   347    348     $(TOP)/ext/misc/wholenumber.c \
   348    349     $(TOP)/ext/misc/vfslog.c \
   349    350     $(TOP)/ext/fts5/fts5_tcl.c \
   350    351     $(TOP)/ext/fts5/fts5_test_mi.c \
   351    352     $(TOP)/ext/fts5/fts5_test_tok.c 
   352    353   
   353    354   

Changes to src/btree.c.

  1645   1645     assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
  1646   1646     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  1647   1647     assert( iSize>=4 );   /* Minimum cell size is 4 */
  1648   1648     assert( iStart<=iLast );
  1649   1649   
  1650   1650     /* Overwrite deleted information with zeros when the secure_delete
  1651   1651     ** option is enabled */
  1652         -  if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
         1652  +  if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
  1653   1653       memset(&data[iStart], 0, iSize);
  1654   1654     }
  1655   1655   
  1656   1656     /* The list of freeblocks must be in ascending order.  Find the 
  1657   1657     ** spot on the list where iStart should be inserted.
  1658   1658     */
  1659   1659     hdr = pPage->hdrOffset;
................................................................................
  1936   1936     u16 first;
  1937   1937   
  1938   1938     assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
  1939   1939     assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
  1940   1940     assert( sqlite3PagerGetData(pPage->pDbPage) == data );
  1941   1941     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  1942   1942     assert( sqlite3_mutex_held(pBt->mutex) );
  1943         -  if( pBt->btsFlags & BTS_SECURE_DELETE ){
         1943  +  if( pBt->btsFlags & BTS_FAST_SECURE ){
  1944   1944       memset(&data[hdr], 0, pBt->usableSize - hdr);
  1945   1945     }
  1946   1946     data[hdr] = (char)flags;
  1947   1947     first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8);
  1948   1948     memset(&data[hdr+1], 0, 4);
  1949   1949     data[hdr+7] = 0;
  1950   1950     put2byte(&data[hdr+5], pBt->usableSize);
................................................................................
  2359   2359       pBt->db = db;
  2360   2360       sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
  2361   2361       p->pBt = pBt;
  2362   2362     
  2363   2363       pBt->pCursor = 0;
  2364   2364       pBt->pPage1 = 0;
  2365   2365       if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY;
  2366         -#ifdef SQLITE_SECURE_DELETE
         2366  +#if defined(SQLITE_SECURE_DELETE)
  2367   2367       pBt->btsFlags |= BTS_SECURE_DELETE;
         2368  +#elif defined(SQLITE_FAST_SECURE_DELETE)
         2369  +    pBt->btsFlags |= BTS_OVERWRITE;
  2368   2370   #endif
  2369   2371       /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
  2370   2372       ** determined by the 2-byte integer located at an offset of 16 bytes from
  2371   2373       ** the beginning of the database file. */
  2372   2374       pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
  2373   2375       if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
  2374   2376            || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
................................................................................
  2808   2810     sqlite3BtreeEnter(p);
  2809   2811     n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage);
  2810   2812     sqlite3BtreeLeave(p);
  2811   2813     return n;
  2812   2814   }
  2813   2815   
  2814   2816   /*
  2815         -** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1.  If newFlag is -1,
  2816         -** then make no changes.  Always return the value of the BTS_SECURE_DELETE
  2817         -** setting after the change.
         2817  +** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags:
         2818  +**
         2819  +**    newFlag==0       Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared
         2820  +**    newFlag==1       BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared
         2821  +**    newFlag==2       BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set
         2822  +**    newFlag==(-1)    No changes
         2823  +**
         2824  +** This routine acts as a query if newFlag is less than zero
         2825  +**
         2826  +** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but
         2827  +** freelist leaf pages are not written back to the database.  Thus in-page
         2828  +** deleted content is cleared, but freelist deleted content is not.
         2829  +**
         2830  +** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition
         2831  +** that freelist leaf pages are written back into the database, increasing
         2832  +** the amount of disk I/O.
  2818   2833   */
  2819   2834   int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
  2820   2835     int b;
  2821   2836     if( p==0 ) return 0;
  2822   2837     sqlite3BtreeEnter(p);
         2838  +  assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 );
         2839  +  assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) );
  2823   2840     if( newFlag>=0 ){
  2824         -    p->pBt->btsFlags &= ~BTS_SECURE_DELETE;
  2825         -    if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE;
  2826         -  } 
  2827         -  b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0;
         2841  +    p->pBt->btsFlags &= ~BTS_FAST_SECURE;
         2842  +    p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag;
         2843  +  }
         2844  +  b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE;
  2828   2845     sqlite3BtreeLeave(p);
  2829   2846     return b;
  2830   2847   }
  2831   2848   
  2832   2849   /*
  2833   2850   ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
  2834   2851   ** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
................................................................................
  5446   5463   **
  5447   5464   ** The main entry point is sqlite3BtreeNext().  That routine is optimized
  5448   5465   ** for the common case of merely incrementing the cell counter BtCursor.aiIdx
  5449   5466   ** to the next cell on the current page.  The (slower) btreeNext() helper
  5450   5467   ** routine is called when it is necessary to move to a different page or
  5451   5468   ** to restore the cursor.
  5452   5469   **
  5453         -** If bit 0x01 of the flags argument is 1, then the cursor corresponds to
  5454         -** an SQL index and this routine could have been skipped if the SQL index
  5455         -** had been a unique index.  The flags argument is a hint to the implement.
  5456         -** SQLite btree implementation does not use this hint, but COMDB2 does.
         5470  +** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the
         5471  +** cursor corresponds to an SQL index and this routine could have been
         5472  +** skipped if the SQL index had been a unique index.  The F argument
         5473  +** is a hint to the implement.  SQLite btree implementation does not use
         5474  +** this hint, but COMDB2 does.
  5457   5475   */
  5458         -static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int flags){
         5476  +static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
  5459   5477     int rc;
  5460   5478     int idx;
  5461   5479     MemPage *pPage;
  5462   5480   
  5463   5481     assert( cursorOwnsBtShared(pCur) );
  5464   5482     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  5465         -  assert( flags==0 );
  5466   5483     if( pCur->eState!=CURSOR_VALID ){
  5467   5484       assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
  5468   5485       rc = restoreCursorPosition(pCur);
  5469   5486       if( rc!=SQLITE_OK ){
  5470   5487         return rc;
  5471   5488       }
  5472   5489       if( CURSOR_INVALID==pCur->eState ){
................................................................................
  5505   5522           pCur->eState = CURSOR_INVALID;
  5506   5523           return SQLITE_DONE;
  5507   5524         }
  5508   5525         moveToParent(pCur);
  5509   5526         pPage = pCur->apPage[pCur->iPage];
  5510   5527       }while( pCur->ix>=pPage->nCell );
  5511   5528       if( pPage->intKey ){
  5512         -      return sqlite3BtreeNext(pCur, flags);
         5529  +      return sqlite3BtreeNext(pCur, 0);
  5513   5530       }else{
  5514   5531         return SQLITE_OK;
  5515   5532       }
  5516   5533     }
  5517   5534     if( pPage->leaf ){
  5518   5535       return SQLITE_OK;
  5519   5536     }else{
  5520   5537       return moveToLeftmost(pCur);
  5521   5538     }
  5522   5539   }
  5523   5540   int sqlite3BtreeNext(BtCursor *pCur, int flags){
  5524   5541     MemPage *pPage;
         5542  +  UNUSED_PARAMETER( flags );  /* Used in COMDB2 but not native SQLite */
  5525   5543     assert( cursorOwnsBtShared(pCur) );
  5526   5544     assert( flags==0 || flags==1 );
  5527   5545     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  5528   5546     pCur->info.nSize = 0;
  5529   5547     pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
  5530         -  if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, 0);
         5548  +  if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
  5531   5549     pPage = pCur->apPage[pCur->iPage];
  5532   5550     if( (++pCur->ix)>=pPage->nCell ){
  5533   5551       pCur->ix--;
  5534         -    return btreeNext(pCur, 0);
         5552  +    return btreeNext(pCur);
  5535   5553     }
  5536   5554     if( pPage->leaf ){
  5537   5555       return SQLITE_OK;
  5538   5556     }else{
  5539   5557       return moveToLeftmost(pCur);
  5540   5558     }
  5541   5559   }
................................................................................
  5550   5568   **
  5551   5569   ** The main entry point is sqlite3BtreePrevious().  That routine is optimized
  5552   5570   ** for the common case of merely decrementing the cell counter BtCursor.aiIdx
  5553   5571   ** to the previous cell on the current page.  The (slower) btreePrevious()
  5554   5572   ** helper routine is called when it is necessary to move to a different page
  5555   5573   ** or to restore the cursor.
  5556   5574   **
  5557         -**
  5558         -** If bit 0x01 of the flags argument is 1, then the cursor corresponds to
  5559         -** an SQL index and this routine could have been skipped if the SQL index
  5560         -** had been a unique index.  The flags argument is a hint to the implement.
  5561         -** SQLite btree implementation does not use this hint, but COMDB2 does.
         5575  +** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then
         5576  +** the cursor corresponds to an SQL index and this routine could have been
         5577  +** skipped if the SQL index had been a unique index.  The F argument is a
         5578  +** hint to the implement.  The native SQLite btree implementation does not
         5579  +** use this hint, but COMDB2 does.
  5562   5580   */
  5563         -static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int flags){
         5581  +static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
  5564   5582     int rc;
  5565   5583     MemPage *pPage;
  5566   5584   
  5567   5585     assert( cursorOwnsBtShared(pCur) );
  5568         -  assert( flags==0 );
  5569   5586     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  5570   5587     assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
  5571   5588     assert( pCur->info.nSize==0 );
  5572   5589     if( pCur->eState!=CURSOR_VALID ){
  5573   5590       rc = restoreCursorPosition(pCur);
  5574   5591       if( rc!=SQLITE_OK ){
  5575   5592         return rc;
................................................................................
  5605   5622       }
  5606   5623       assert( pCur->info.nSize==0 );
  5607   5624       assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
  5608   5625   
  5609   5626       pCur->ix--;
  5610   5627       pPage = pCur->apPage[pCur->iPage];
  5611   5628       if( pPage->intKey && !pPage->leaf ){
  5612         -      rc = sqlite3BtreePrevious(pCur, flags);
         5629  +      rc = sqlite3BtreePrevious(pCur, 0);
  5613   5630       }else{
  5614   5631         rc = SQLITE_OK;
  5615   5632       }
  5616   5633     }
  5617   5634     return rc;
  5618   5635   }
  5619   5636   int sqlite3BtreePrevious(BtCursor *pCur, int flags){
  5620   5637     assert( cursorOwnsBtShared(pCur) );
  5621   5638     assert( flags==0 || flags==1 );
  5622   5639     assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
         5640  +  UNUSED_PARAMETER( flags );  /* Used in COMDB2 but not native SQLite */
  5623   5641     pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
  5624   5642     pCur->info.nSize = 0;
  5625   5643     if( pCur->eState!=CURSOR_VALID
  5626   5644      || pCur->ix==0
  5627   5645      || pCur->apPage[pCur->iPage]->leaf==0
  5628   5646     ){
  5629         -    return btreePrevious(pCur, 0);
         5647  +    return btreePrevious(pCur);
  5630   5648     }
  5631   5649     pCur->ix--;
  5632   5650     return SQLITE_OK;
  5633   5651   }
  5634   5652   
  5635   5653   #ifdef SQLITE_SERVER_EDITION
  5636   5654   
................................................................................
  7482   7500         ** later on.  
  7483   7501         **
  7484   7502         ** But not if we are in secure-delete mode. In secure-delete mode,
  7485   7503         ** the dropCell() routine will overwrite the entire cell with zeroes.
  7486   7504         ** In this case, temporarily copy the cell into the aOvflSpace[]
  7487   7505         ** buffer. It will be copied out again as soon as the aSpace[] buffer
  7488   7506         ** is allocated.  */
  7489         -      if( pBt->btsFlags & BTS_SECURE_DELETE ){
         7507  +      if( pBt->btsFlags & BTS_FAST_SECURE ){
  7490   7508           int iOff;
  7491   7509   
  7492   7510           iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
  7493   7511           if( (iOff+szNew[i])>(int)pBt->usableSize ){
  7494   7512             rc = SQLITE_CORRUPT_BKPT;
  7495   7513             memset(apOld, 0, (i+1)*sizeof(MemPage*));
  7496   7514             goto balance_cleanup;

Changes to src/btreeInt.h.

   444    444   
   445    445   /*
   446    446   ** Allowed values for BtShared.btsFlags
   447    447   */
   448    448   #define BTS_READ_ONLY        0x0001   /* Underlying file is readonly */
   449    449   #define BTS_PAGESIZE_FIXED   0x0002   /* Page size can no longer be changed */
   450    450   #define BTS_SECURE_DELETE    0x0004   /* PRAGMA secure_delete is enabled */
   451         -#define BTS_INITIALLY_EMPTY  0x0008   /* Database was empty at trans start */
   452         -#define BTS_NO_WAL           0x0010   /* Do not open write-ahead-log files */
   453         -#define BTS_EXCLUSIVE        0x0020   /* pWriter has an exclusive lock */
   454         -#define BTS_PENDING          0x0040   /* Waiting for read-locks to clear */
          451  +#define BTS_OVERWRITE        0x0008   /* Overwrite deleted content with zeros */
          452  +#define BTS_FAST_SECURE      0x000c   /* Combination of the previous two */
          453  +#define BTS_INITIALLY_EMPTY  0x0010   /* Database was empty at trans start */
          454  +#define BTS_NO_WAL           0x0020   /* Do not open write-ahead-log files */
          455  +#define BTS_EXCLUSIVE        0x0040   /* pWriter has an exclusive lock */
          456  +#define BTS_PENDING          0x0080   /* Waiting for read-locks to clear */
   455    457   
   456    458   /*
   457    459   ** An instance of the following structure is used to hold information
   458    460   ** about a cell.  The parseCellPtr() function fills in this structure
   459    461   ** based on information extract from the raw disk page.
   460    462   */
   461    463   struct CellInfo {

Changes to src/dbstat.c.

   690    690       0,                            /* xUpdate */
   691    691       0,                            /* xBegin */
   692    692       0,                            /* xSync */
   693    693       0,                            /* xCommit */
   694    694       0,                            /* xRollback */
   695    695       0,                            /* xFindMethod */
   696    696       0,                            /* xRename */
          697  +    0,                            /* xSavepoint */
          698  +    0,                            /* xRelease */
          699  +    0,                            /* xRollbackTo */
   697    700     };
   698    701     return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
   699    702   }
   700    703   #elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
   701    704   int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
   702    705   #endif /* SQLITE_ENABLE_DBSTAT_VTAB */

Changes to src/expr.c.

  5251   5251   ** iFirst..iLast, inclusive.  This routine is only call from within assert()
  5252   5252   ** statements.
  5253   5253   */
  5254   5254   #ifdef SQLITE_DEBUG
  5255   5255   int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
  5256   5256     int i;
  5257   5257     if( pParse->nRangeReg>0
  5258         -   && pParse->iRangeReg+pParse->nRangeReg<iLast
  5259         -   && pParse->iRangeReg>=iFirst
         5258  +   && pParse->iRangeReg+pParse->nRangeReg > iFirst
         5259  +   && pParse->iRangeReg <= iLast
  5260   5260     ){
  5261   5261        return 0;
  5262   5262     }
  5263   5263     for(i=0; i<pParse->nTempReg; i++){
  5264   5264       if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){
  5265   5265         return 0;
  5266   5266       }
  5267   5267     }
  5268   5268     return 1;
  5269   5269   }
  5270   5270   #endif /* SQLITE_DEBUG */

Changes to src/func.c.

    81     81     UNUSED_PARAMETER(NotUsed);
    82     82     assert( i>=0 && i<ArraySize(azType) );
    83     83     assert( SQLITE_INTEGER==1 );
    84     84     assert( SQLITE_FLOAT==2 );
    85     85     assert( SQLITE_TEXT==3 );
    86     86     assert( SQLITE_BLOB==4 );
    87     87     assert( SQLITE_NULL==5 );
           88  +  /* EVIDENCE-OF: R-01470-60482 The sqlite3_value_type(V) interface returns
           89  +  ** the datatype code for the initial datatype of the sqlite3_value object
           90  +  ** V. The returned value is one of SQLITE_INTEGER, SQLITE_FLOAT,
           91  +  ** SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. */
    88     92     sqlite3_result_text(context, azType[i], -1, SQLITE_STATIC);
    89     93   }
    90     94   
    91     95   
    92     96   /*
    93     97   ** Implementation of the length() function
    94     98   */

Changes to src/loadext.c.

    47     47   # define sqlite3_complete16             0
    48     48   # define sqlite3_create_collation16     0
    49     49   # define sqlite3_create_function16      0
    50     50   # define sqlite3_errmsg16               0
    51     51   # define sqlite3_open16                 0
    52     52   # define sqlite3_prepare16              0
    53     53   # define sqlite3_prepare16_v2           0
           54  +# define sqlite3_prepare16_v3           0
    54     55   # define sqlite3_result_error16         0
    55     56   # define sqlite3_result_text16          0
    56     57   # define sqlite3_result_text16be        0
    57     58   # define sqlite3_result_text16le        0
    58     59   # define sqlite3_value_text16           0
    59     60   # define sqlite3_value_text16be         0
    60     61   # define sqlite3_value_text16le         0
................................................................................
   419    420     sqlite3_db_cacheflush,
   420    421     /* Version 3.12.0 and later */
   421    422     sqlite3_system_errno,
   422    423     /* Version 3.14.0 and later */
   423    424     sqlite3_trace_v2,
   424    425     sqlite3_expanded_sql,
   425    426     /* Version 3.18.0 and later */
   426         -  sqlite3_set_last_insert_rowid
          427  +  sqlite3_set_last_insert_rowid,
          428  +  /* Version 3.20.0 and later */
          429  +  sqlite3_prepare_v3,
          430  +  sqlite3_prepare16_v3,
          431  +  sqlite3_bind_pointer,
          432  +  sqlite3_result_pointer,
          433  +  sqlite3_value_pointer
   427    434   };
   428    435   
   429    436   /*
   430    437   ** Attempt to load an SQLite extension library contained in the file
   431    438   ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
   432    439   ** default entry point name (sqlite3_extension_init) is used.  Use
   433    440   ** of the default name is recommended.

Changes to src/main.c.

   789    789   */
   790    790   int sqlite3_db_config(sqlite3 *db, int op, ...){
   791    791     va_list ap;
   792    792     int rc;
   793    793     va_start(ap, op);
   794    794     switch( op ){
   795    795       case SQLITE_DBCONFIG_MAINDBNAME: {
          796  +      /* IMP: R-06824-28531 */
          797  +      /* IMP: R-36257-52125 */
   796    798         db->aDb[0].zDbSName = va_arg(ap,char*);
   797    799         rc = SQLITE_OK;
   798    800         break;
   799    801       }
   800    802       case SQLITE_DBCONFIG_LOOKASIDE: {
   801    803         void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
   802    804         int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
................................................................................
  1400   1402   /*
  1401   1403   ** Return a static string that describes the kind of error specified in the
  1402   1404   ** argument.
  1403   1405   */
  1404   1406   const char *sqlite3ErrStr(int rc){
  1405   1407     static const char* const aMsg[] = {
  1406   1408       /* SQLITE_OK          */ "not an error",
  1407         -    /* SQLITE_ERROR       */ "SQL logic error or missing database",
         1409  +    /* SQLITE_ERROR       */ "SQL logic error",
  1408   1410       /* SQLITE_INTERNAL    */ 0,
  1409   1411       /* SQLITE_PERM        */ "access permission denied",
  1410         -    /* SQLITE_ABORT       */ "callback requested query abort",
         1412  +    /* SQLITE_ABORT       */ "query aborted",
  1411   1413       /* SQLITE_BUSY        */ "database is locked",
  1412   1414       /* SQLITE_LOCKED      */ "database table is locked",
  1413   1415       /* SQLITE_NOMEM       */ "out of memory",
  1414   1416       /* SQLITE_READONLY    */ "attempt to write a readonly database",
  1415   1417       /* SQLITE_INTERRUPT   */ "interrupted",
  1416   1418       /* SQLITE_IOERR       */ "disk I/O error",
  1417   1419       /* SQLITE_CORRUPT     */ "database disk image is malformed",
  1418   1420       /* SQLITE_NOTFOUND    */ "unknown operation",
  1419   1421       /* SQLITE_FULL        */ "database or disk is full",
  1420   1422       /* SQLITE_CANTOPEN    */ "unable to open database file",
  1421   1423       /* SQLITE_PROTOCOL    */ "locking protocol",
  1422         -    /* SQLITE_EMPTY       */ "table contains no data",
         1424  +    /* SQLITE_EMPTY       */ 0,
  1423   1425       /* SQLITE_SCHEMA      */ "database schema has changed",
  1424   1426       /* SQLITE_TOOBIG      */ "string or blob too big",
  1425   1427       /* SQLITE_CONSTRAINT  */ "constraint failed",
  1426   1428       /* SQLITE_MISMATCH    */ "datatype mismatch",
  1427         -    /* SQLITE_MISUSE      */ "library routine called out of sequence",
         1429  +    /* SQLITE_MISUSE      */ "bad parameter or other API misuse",
         1430  +#ifdef SQLITE_DISABLE_LFS
  1428   1431       /* SQLITE_NOLFS       */ "large file support is disabled",
         1432  +#else
         1433  +    /* SQLITE_NOLFS       */ 0,
         1434  +#endif
  1429   1435       /* SQLITE_AUTH        */ "authorization denied",
  1430         -    /* SQLITE_FORMAT      */ "auxiliary database format error",
  1431         -    /* SQLITE_RANGE       */ "bind or column index out of range",
  1432         -    /* SQLITE_NOTADB      */ "file is encrypted or is not a database",
         1436  +    /* SQLITE_FORMAT      */ 0,
         1437  +    /* SQLITE_RANGE       */ "column index out of range",
         1438  +    /* SQLITE_NOTADB      */ "file is not a database",
  1433   1439     };
  1434   1440     const char *zErr = "unknown error";
  1435   1441     switch( rc ){
  1436   1442       case SQLITE_ABORT_ROLLBACK: {
  1437   1443         zErr = "abort due to ROLLBACK";
  1438   1444         break;
  1439   1445       }
................................................................................
  2265   2271   ** error.
  2266   2272   */
  2267   2273   const void *sqlite3_errmsg16(sqlite3 *db){
  2268   2274     static const u16 outOfMem[] = {
  2269   2275       'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
  2270   2276     };
  2271   2277     static const u16 misuse[] = {
  2272         -    'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', 
  2273         -    'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', 
  2274         -    'c', 'a', 'l', 'l', 'e', 'd', ' ', 
  2275         -    'o', 'u', 't', ' ', 
  2276         -    'o', 'f', ' ', 
  2277         -    's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0
         2278  +    'b', 'a', 'd', ' ', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', ' ',
         2279  +    'o', 'r', ' ', 'o', 't', 'h', 'e', 'r', ' ', 'A', 'P', 'I', ' ',
         2280  +    'm', 'i', 's', 'u', 's', 'e', 0
  2278   2281     };
  2279   2282   
  2280   2283     const void *z;
  2281   2284     if( !db ){
  2282   2285       return (void *)outOfMem;
  2283   2286     }
  2284   2287     if( !sqlite3SafetyCheckSickOrOk(db) ){
................................................................................
  2805   2808   #endif
  2806   2809     *ppDb = 0;
  2807   2810   #ifndef SQLITE_OMIT_AUTOINIT
  2808   2811     rc = sqlite3_initialize();
  2809   2812     if( rc ) return rc;
  2810   2813   #endif
  2811   2814   
  2812         -  /* Only allow sensible combinations of bits in the flags argument.  
  2813         -  ** Throw an error if any non-sense combination is used.  If we
  2814         -  ** do not block illegal combinations here, it could trigger
  2815         -  ** assert() statements in deeper layers.  Sensible combinations
  2816         -  ** are:
  2817         -  **
  2818         -  **  1:  SQLITE_OPEN_READONLY
  2819         -  **  2:  SQLITE_OPEN_READWRITE
  2820         -  **  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
  2821         -  */
  2822         -  assert( SQLITE_OPEN_READONLY  == 0x01 );
  2823         -  assert( SQLITE_OPEN_READWRITE == 0x02 );
  2824         -  assert( SQLITE_OPEN_CREATE    == 0x04 );
  2825         -  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
  2826         -  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
  2827         -  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
  2828         -  if( ((1<<(flags&7)) & 0x46)==0 ){
  2829         -    return SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */
  2830         -  }
  2831         -
  2832   2815     if( sqlite3GlobalConfig.bCoreMutex==0 ){
  2833   2816       isThreadsafe = 0;
  2834   2817     }else if( flags & SQLITE_OPEN_NOMUTEX ){
  2835   2818       isThreadsafe = 0;
  2836   2819     }else if( flags & SQLITE_OPEN_FULLMUTEX ){
  2837   2820       isThreadsafe = 1;
  2838   2821     }else{
................................................................................
  2946   2929     }
  2947   2930     /* EVIDENCE-OF: R-08308-17224 The default collating function for all
  2948   2931     ** strings is BINARY. 
  2949   2932     */
  2950   2933     db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
  2951   2934     assert( db->pDfltColl!=0 );
  2952   2935   
  2953         -  /* Parse the filename/URI argument. */
         2936  +  /* Parse the filename/URI argument
         2937  +  **
         2938  +  ** Only allow sensible combinations of bits in the flags argument.  
         2939  +  ** Throw an error if any non-sense combination is used.  If we
         2940  +  ** do not block illegal combinations here, it could trigger
         2941  +  ** assert() statements in deeper layers.  Sensible combinations
         2942  +  ** are:
         2943  +  **
         2944  +  **  1:  SQLITE_OPEN_READONLY
         2945  +  **  2:  SQLITE_OPEN_READWRITE
         2946  +  **  6:  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
         2947  +  */
  2954   2948     db->openFlags = flags;
  2955         -  rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
         2949  +  assert( SQLITE_OPEN_READONLY  == 0x01 );
         2950  +  assert( SQLITE_OPEN_READWRITE == 0x02 );
         2951  +  assert( SQLITE_OPEN_CREATE    == 0x04 );
         2952  +  testcase( (1<<(flags&7))==0x02 ); /* READONLY */
         2953  +  testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
         2954  +  testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
         2955  +  if( ((1<<(flags&7)) & 0x46)==0 ){
         2956  +    rc = SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */
         2957  +  }else{
         2958  +    rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
         2959  +  }
  2956   2960     if( rc!=SQLITE_OK ){
  2957   2961       if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
  2958   2962       sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
  2959   2963       sqlite3_free(zErrMsg);
  2960   2964       goto opendb_out;
  2961   2965     }
  2962   2966   

Changes to src/parse.y.

   872    872       pOut->zEnd = &t.z[t.n];
   873    873     }
   874    874   }
   875    875   
   876    876   expr(A) ::= term(A).
   877    877   expr(A) ::= LP(B) expr(X) RP(E).
   878    878               {spanSet(&A,&B,&E); /*A-overwrites-B*/  A.pExpr = X.pExpr;}
   879         -term(A) ::= NULL(X).        {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
   880    879   expr(A) ::= id(X).          {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
   881    880   expr(A) ::= JOIN_KW(X).     {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
   882    881   expr(A) ::= nm(X) DOT nm(Y). {
   883    882     Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
   884    883     Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1);
   885    884     spanSet(&A,&X,&Y); /*A-overwrites-X*/
   886    885     A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
................................................................................
   889    888     Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
   890    889     Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1);
   891    890     Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &Z, 1);
   892    891     Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
   893    892     spanSet(&A,&X,&Z); /*A-overwrites-X*/
   894    893     A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
   895    894   }
   896         -term(A) ::= FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
   897         -term(A) ::= STRING(X).     {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
          895  +term(A) ::= NULL|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/}
          896  +term(A) ::= STRING(X).          {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/}
   898    897   term(A) ::= INTEGER(X). {
   899    898     A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
   900    899     A.zStart = X.z;
   901    900     A.zEnd = X.z + X.n;
   902         -  if( A.pExpr ) A.pExpr->flags |= EP_Leaf|EP_Resolved;
   903    901   }
   904    902   expr(A) ::= VARIABLE(X).     {
   905    903     if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
   906    904       u32 n = X.n;
   907    905       spanExpr(&A, pParse, TK_VARIABLE, X);
   908    906       sqlite3ExprAssignVarNumber(pParse, A.pExpr, n);
   909    907     }else{

Changes to src/pragma.c.

   511    511         }
   512    512       }
   513    513       break;
   514    514     }
   515    515   
   516    516     /*
   517    517     **  PRAGMA [schema.]secure_delete
   518         -  **  PRAGMA [schema.]secure_delete=ON/OFF
          518  +  **  PRAGMA [schema.]secure_delete=ON/OFF/FAST
   519    519     **
   520    520     ** The first form reports the current setting for the
   521    521     ** secure_delete flag.  The second form changes the secure_delete
   522         -  ** flag setting and reports thenew value.
          522  +  ** flag setting and reports the new value.
   523    523     */
   524    524     case PragTyp_SECURE_DELETE: {
   525    525       Btree *pBt = pDb->pBt;
   526    526       int b = -1;
   527    527       assert( pBt!=0 );
   528    528       if( zRight ){
   529         -      b = sqlite3GetBoolean(zRight, 0);
          529  +      if( sqlite3_stricmp(zRight, "fast")==0 ){
          530  +        b = 2;
          531  +      }else{
          532  +        b = sqlite3GetBoolean(zRight, 0);
          533  +      }
   530    534       }
   531    535       if( pId2->n==0 && b>=0 ){
   532    536         int ii;
   533    537         for(ii=0; ii<db->nDb; ii++){
   534    538           sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b);
   535    539         }
   536    540       }
................................................................................
  1243   1247       pParse->nMem = 2;
  1244   1248       for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
  1245   1249         CollSeq *pColl = (CollSeq *)sqliteHashData(p);
  1246   1250         sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
  1247   1251       }
  1248   1252     }
  1249   1253     break;
         1254  +
         1255  +#ifdef SQLITE_INTROSPECTION_PRAGMAS
         1256  +  case PragTyp_FUNCTION_LIST: {
         1257  +    int i;
         1258  +    HashElem *j;
         1259  +    FuncDef *p;
         1260  +    pParse->nMem = 2;
         1261  +    for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
         1262  +      for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
         1263  +        sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
         1264  +        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
         1265  +      }
         1266  +    }
         1267  +    for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
         1268  +      p = (FuncDef*)sqliteHashData(j);
         1269  +      sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0);
         1270  +      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
         1271  +    }
         1272  +  }
         1273  +  break;
         1274  +
         1275  +#ifndef SQLITE_OMIT_VIRTUALTABLE
         1276  +  case PragTyp_MODULE_LIST: {
         1277  +    HashElem *j;
         1278  +    pParse->nMem = 1;
         1279  +    for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){
         1280  +      Module *pMod = (Module*)sqliteHashData(j);
         1281  +      sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName);
         1282  +      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
         1283  +    }
         1284  +  }
         1285  +  break;
         1286  +#endif /* SQLITE_OMIT_VIRTUALTABLE */
         1287  +
         1288  +  case PragTyp_PRAGMA_LIST: {
         1289  +    int i;
         1290  +    for(i=0; i<ArraySize(aPragmaName); i++){
         1291  +      sqlite3VdbeMultiLoad(v, 1, "s", aPragmaName[i].zName);
         1292  +      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
         1293  +    }
         1294  +  }
         1295  +  break;
         1296  +#endif /* SQLITE_INTROSPECTION_PRAGMAS */
         1297  +
  1250   1298   #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
  1251   1299   
  1252   1300   #ifndef SQLITE_OMIT_FOREIGN_KEY
  1253   1301     case PragTyp_FOREIGN_KEY_LIST: if( zRight ){
  1254   1302       FKey *pFK;
  1255   1303       Table *pTab;
  1256   1304       pTab = sqlite3FindTable(db, zRight, zDb);
................................................................................
  1503   1551             aRoot[cnt++] = pIdx->tnum;
  1504   1552           }
  1505   1553         }
  1506   1554         aRoot[cnt] = 0;
  1507   1555   
  1508   1556         /* Make sure sufficient number of registers have been allocated */
  1509   1557         pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
         1558  +      sqlite3ClearTempRegCache(pParse);
  1510   1559   
  1511   1560         /* Do the b-tree integrity checks */
  1512   1561         sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
  1513   1562         sqlite3VdbeChangeP5(v, (u8)i);
  1514   1563         addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
  1515   1564         sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
  1516   1565            sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
................................................................................
  1917   1966     **              information from the current session in the
  1918   1967     **              database file so that it will be available to "optimize"
  1919   1968     **              pragmas run by future database connections.
  1920   1969     **
  1921   1970     **    0x0008    (Not yet implemented) Create indexes that might have
  1922   1971     **              been helpful to recent queries
  1923   1972     **
  1924         -  ** The default MASK is and always shall be 0xfffe.  0xfffe means perform all    ** of the optimizations listed above except Debug Mode, including new
         1973  +  ** The default MASK is and always shall be 0xfffe.  0xfffe means perform all
         1974  +  ** of the optimizations listed above except Debug Mode, including new
  1925   1975     ** optimizations that have not yet been invented.  If new optimizations are
  1926   1976     ** ever added that should be off by default, those off-by-default 
  1927   1977     ** optimizations will have bitmasks of 0x10000 or larger.
  1928   1978     **
  1929   1979     ** DETERMINATION OF WHEN TO RUN ANALYZE
  1930   1980     **
  1931   1981     ** In the current implementation, a table is analyzed if only if all of
................................................................................
  2344   2394     char *zSql;
  2345   2395   
  2346   2396     UNUSED_PARAMETER(idxNum);
  2347   2397     UNUSED_PARAMETER(idxStr);
  2348   2398     pragmaVtabCursorClear(pCsr);
  2349   2399     j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1;
  2350   2400     for(i=0; i<argc; i++, j++){
         2401  +    const char *zText = (const char*)sqlite3_value_text(argv[i]);
  2351   2402       assert( j<ArraySize(pCsr->azArg) );
  2352         -    pCsr->azArg[j] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i]));
  2353         -    if( pCsr->azArg[j]==0 ){
  2354         -      return SQLITE_NOMEM;
         2403  +    assert( pCsr->azArg[j]==0 );
         2404  +    if( zText ){
         2405  +      pCsr->azArg[j] = sqlite3_mprintf("%s", zText);
         2406  +      if( pCsr->azArg[j]==0 ){
         2407  +        return SQLITE_NOMEM;
         2408  +      }
  2355   2409       }
  2356   2410     }
  2357   2411     sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
  2358   2412     sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
  2359   2413     if( pCsr->azArg[1] ){
  2360   2414       sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
  2361   2415     }

Changes to src/pragma.h.

    17     17   #define PragTyp_DATA_STORE_DIRECTORY           9
    18     18   #define PragTyp_DATABASE_LIST                 10
    19     19   #define PragTyp_DEFAULT_CACHE_SIZE            11
    20     20   #define PragTyp_ENCODING                      12
    21     21   #define PragTyp_FOREIGN_KEY_CHECK             13
    22     22   #define PragTyp_FOREIGN_KEY_LIST              14
    23     23   #define PragTyp_FREELIST_FORMAT               15
    24         -#define PragTyp_INCREMENTAL_VACUUM            16
    25         -#define PragTyp_INDEX_INFO                    17
    26         -#define PragTyp_INDEX_LIST                    18
    27         -#define PragTyp_INTEGRITY_CHECK               19
    28         -#define PragTyp_JOURNAL_MODE                  20
    29         -#define PragTyp_JOURNAL_SIZE_LIMIT            21
    30         -#define PragTyp_LOCK_PROXY_FILE               22
    31         -#define PragTyp_LOCKING_MODE                  23
    32         -#define PragTyp_PAGE_COUNT                    24
    33         -#define PragTyp_MMAP_SIZE                     25
    34         -#define PragTyp_OPTIMIZE                      26
    35         -#define PragTyp_PAGE_SIZE                     27
    36         -#define PragTyp_SECURE_DELETE                 28
    37         -#define PragTyp_SHRINK_MEMORY                 29
    38         -#define PragTyp_SOFT_HEAP_LIMIT               30
    39         -#define PragTyp_SYNCHRONOUS                   31
    40         -#define PragTyp_TABLE_INFO                    32
    41         -#define PragTyp_TEMP_STORE                    33
    42         -#define PragTyp_TEMP_STORE_DIRECTORY          34
    43         -#define PragTyp_THREADS                       35
    44         -#define PragTyp_WAL_AUTOCHECKPOINT            36
    45         -#define PragTyp_WAL_CHECKPOINT                37
    46         -#define PragTyp_ACTIVATE_EXTENSIONS           38
    47         -#define PragTyp_HEXKEY                        39
    48         -#define PragTyp_KEY                           40
    49         -#define PragTyp_REKEY                         41
    50         -#define PragTyp_LOCK_STATUS                   42
    51         -#define PragTyp_PARSER_TRACE                  43
    52         -#define PragTyp_STATS                         44
           24  +#define PragTyp_FUNCTION_LIST                 16
           25  +#define PragTyp_INCREMENTAL_VACUUM            17
           26  +#define PragTyp_INDEX_INFO                    18
           27  +#define PragTyp_INDEX_LIST                    19
           28  +#define PragTyp_INTEGRITY_CHECK               20
           29  +#define PragTyp_JOURNAL_MODE                  21
           30  +#define PragTyp_JOURNAL_SIZE_LIMIT            22
           31  +#define PragTyp_LOCK_PROXY_FILE               23
           32  +#define PragTyp_LOCKING_MODE                  24
           33  +#define PragTyp_PAGE_COUNT                    25
           34  +#define PragTyp_MMAP_SIZE                     26
           35  +#define PragTyp_MODULE_LIST                   27
           36  +#define PragTyp_OPTIMIZE                      28
           37  +#define PragTyp_PAGE_SIZE                     29
           38  +#define PragTyp_PRAGMA_LIST                   30
           39  +#define PragTyp_SECURE_DELETE                 31
           40  +#define PragTyp_SHRINK_MEMORY                 32
           41  +#define PragTyp_SOFT_HEAP_LIMIT               33
           42  +#define PragTyp_SYNCHRONOUS                   34
           43  +#define PragTyp_TABLE_INFO                    35
           44  +#define PragTyp_TEMP_STORE                    36
           45  +#define PragTyp_TEMP_STORE_DIRECTORY          37
           46  +#define PragTyp_THREADS                       38
           47  +#define PragTyp_WAL_AUTOCHECKPOINT            39
           48  +#define PragTyp_WAL_CHECKPOINT                40
           49  +#define PragTyp_ACTIVATE_EXTENSIONS           41
           50  +#define PragTyp_HEXKEY                        42
           51  +#define PragTyp_KEY                           43
           52  +#define PragTyp_REKEY                         44
           53  +#define PragTyp_LOCK_STATUS                   45
           54  +#define PragTyp_PARSER_TRACE                  46
           55  +#define PragTyp_STATS                         47
    53     56   
    54     57   /* Property flags associated with various pragma. */
    55     58   #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
    56     59   #define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
    57     60   #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
    58     61   #define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
    59     62   #define PragFlg_Result0    0x10 /* Acts as query when no argument */
................................................................................
    91     94     /*  22 */ "name",       
    92     95     /*  23 */ "unique",     
    93     96     /*  24 */ "origin",     
    94     97     /*  25 */ "partial",    
    95     98     /*  26 */ "seq",         /* Used by: database_list */
    96     99     /*  27 */ "name",       
    97    100     /*  28 */ "file",       
    98         -  /*  29 */ "seq",         /* Used by: collation_list */
    99         -  /*  30 */ "name",       
   100         -  /*  31 */ "id",          /* Used by: foreign_key_list */
   101         -  /*  32 */ "seq",        
   102         -  /*  33 */ "table",      
   103         -  /*  34 */ "from",       
   104         -  /*  35 */ "to",         
   105         -  /*  36 */ "on_update",  
   106         -  /*  37 */ "on_delete",  
   107         -  /*  38 */ "match",      
   108         -  /*  39 */ "table",       /* Used by: foreign_key_check */
   109         -  /*  40 */ "rowid",      
   110         -  /*  41 */ "parent",     
   111         -  /*  42 */ "fkid",       
   112         -  /*  43 */ "busy",        /* Used by: wal_checkpoint */
   113         -  /*  44 */ "log",        
   114         -  /*  45 */ "checkpointed",
   115         -  /*  46 */ "timeout",     /* Used by: busy_timeout */
   116         -  /*  47 */ "database",    /* Used by: lock_status */
   117         -  /*  48 */ "status",     
          101  +  /*  29 */ "name",        /* Used by: function_list */
          102  +  /*  30 */ "builtin",    
          103  +  /*  31 */ "name",        /* Used by: module_list pragma_list */
          104  +  /*  32 */ "seq",         /* Used by: collation_list */
          105  +  /*  33 */ "name",       
          106  +  /*  34 */ "id",          /* Used by: foreign_key_list */
          107  +  /*  35 */ "seq",        
          108  +  /*  36 */ "table",      
          109  +  /*  37 */ "from",       
          110  +  /*  38 */ "to",         
          111  +  /*  39 */ "on_update",  
          112  +  /*  40 */ "on_delete",  
          113  +  /*  41 */ "match",      
          114  +  /*  42 */ "table",       /* Used by: foreign_key_check */
          115  +  /*  43 */ "rowid",      
          116  +  /*  44 */ "parent",     
          117  +  /*  45 */ "fkid",       
          118  +  /*  46 */ "busy",        /* Used by: wal_checkpoint */
          119  +  /*  47 */ "log",        
          120  +  /*  48 */ "checkpointed",
          121  +  /*  49 */ "timeout",     /* Used by: busy_timeout */
          122  +  /*  50 */ "database",    /* Used by: lock_status */
          123  +  /*  51 */ "status",     
   118    124   };
   119    125   
   120    126   /* Definitions of all built-in pragmas */
   121    127   typedef struct PragmaName {
   122    128     const char *const zName; /* Name of pragma */
   123    129     u8 ePragTyp;             /* PragTyp_XXX value */
   124    130     u8 mPragFlg;             /* Zero or more PragFlg_XXX values */
................................................................................
   156    162     /* ColNames:  */ 0, 0,
   157    163     /* iArg:      */ SQLITE_AutoIndex },
   158    164   #endif
   159    165   #endif
   160    166    {/* zName:     */ "busy_timeout",
   161    167     /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
   162    168     /* ePragFlg:  */ PragFlg_Result0,
   163         -  /* ColNames:  */ 46, 1,
          169  +  /* ColNames:  */ 49, 1,
   164    170     /* iArg:      */ 0 },
   165    171   #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
   166    172    {/* zName:     */ "cache_size",
   167    173     /* ePragTyp:  */ PragTyp_CACHE_SIZE,
   168    174     /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
   169    175     /* ColNames:  */ 0, 0,
   170    176     /* iArg:      */ 0 },
................................................................................
   193    199     /* ColNames:  */ 0, 0,
   194    200     /* iArg:      */ SQLITE_CkptFullFSync },
   195    201   #endif
   196    202   #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
   197    203    {/* zName:     */ "collation_list",
   198    204     /* ePragTyp:  */ PragTyp_COLLATION_LIST,
   199    205     /* ePragFlg:  */ PragFlg_Result0,
   200         -  /* ColNames:  */ 29, 2,
          206  +  /* ColNames:  */ 32, 2,
   201    207     /* iArg:      */ 0 },
   202    208   #endif
   203    209   #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
   204    210    {/* zName:     */ "compile_options",
   205    211     /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS,
   206    212     /* ePragFlg:  */ PragFlg_Result0,
   207    213     /* ColNames:  */ 0, 0,
................................................................................
   265    271     /* ColNames:  */ 0, 0,
   266    272     /* iArg:      */ 0 },
   267    273   #endif
   268    274   #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
   269    275    {/* zName:     */ "foreign_key_check",
   270    276     /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
   271    277     /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
   272         -  /* ColNames:  */ 39, 4,
          278  +  /* ColNames:  */ 42, 4,
   273    279     /* iArg:      */ 0 },
   274    280   #endif
   275    281   #if !defined(SQLITE_OMIT_FOREIGN_KEY)
   276    282    {/* zName:     */ "foreign_key_list",
   277    283     /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
   278    284     /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
   279         -  /* ColNames:  */ 31, 8,
          285  +  /* ColNames:  */ 34, 8,
   280    286     /* iArg:      */ 0 },
   281    287   #endif
   282    288   #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
   283    289   #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
   284    290    {/* zName:     */ "foreign_keys",
   285    291     /* ePragTyp:  */ PragTyp_FLAG,
   286    292     /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
................................................................................
   309    315     /* ColNames:  */ 0, 0,
   310    316     /* iArg:      */ SQLITE_FullColNames },
   311    317    {/* zName:     */ "fullfsync",
   312    318     /* ePragTyp:  */ PragTyp_FLAG,
   313    319     /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   314    320     /* ColNames:  */ 0, 0,
   315    321     /* iArg:      */ SQLITE_FullFSync },
          322  +#endif
          323  +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
          324  +#if defined(SQLITE_INTROSPECTION_PRAGMAS)
          325  + {/* zName:     */ "function_list",
          326  +  /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
          327  +  /* ePragFlg:  */ PragFlg_Result0,
          328  +  /* ColNames:  */ 29, 2,
          329  +  /* iArg:      */ 0 },
          330  +#endif
   316    331   #endif
   317    332   #if defined(SQLITE_HAS_CODEC)
   318    333    {/* zName:     */ "hexkey",
   319    334     /* ePragTyp:  */ PragTyp_HEXKEY,
   320    335     /* ePragFlg:  */ 0,
   321    336     /* ColNames:  */ 0, 0,
   322    337     /* iArg:      */ 0 },
................................................................................
   399    414     /* ColNames:  */ 0, 0,
   400    415     /* iArg:      */ 0 },
   401    416   #endif
   402    417   #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   403    418    {/* zName:     */ "lock_status",
   404    419     /* ePragTyp:  */ PragTyp_LOCK_STATUS,
   405    420     /* ePragFlg:  */ PragFlg_Result0,
   406         -  /* ColNames:  */ 47, 2,
          421  +  /* ColNames:  */ 50, 2,
   407    422     /* iArg:      */ 0 },
   408    423   #endif
   409    424   #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
   410    425    {/* zName:     */ "locking_mode",
   411    426     /* ePragTyp:  */ PragTyp_LOCKING_MODE,
   412    427     /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
   413    428     /* ColNames:  */ 0, 0,
................................................................................
   418    433     /* ColNames:  */ 0, 0,
   419    434     /* iArg:      */ 0 },
   420    435    {/* zName:     */ "mmap_size",
   421    436     /* ePragTyp:  */ PragTyp_MMAP_SIZE,
   422    437     /* ePragFlg:  */ 0,
   423    438     /* ColNames:  */ 0, 0,
   424    439     /* iArg:      */ 0 },
          440  +#endif
          441  +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
          442  +#if !defined(SQLITE_OMIT_VIRTUALTABLE)
          443  +#if defined(SQLITE_INTROSPECTION_PRAGMAS)
          444  + {/* zName:     */ "module_list",
          445  +  /* ePragTyp:  */ PragTyp_MODULE_LIST,
          446  +  /* ePragFlg:  */ PragFlg_Result0,
          447  +  /* ColNames:  */ 31, 1,
          448  +  /* iArg:      */ 0 },
          449  +#endif
          450  +#endif
   425    451   #endif
   426    452    {/* zName:     */ "optimize",
   427    453     /* ePragTyp:  */ PragTyp_OPTIMIZE,
   428    454     /* ePragFlg:  */ PragFlg_Result1|PragFlg_NeedSchema,
   429    455     /* ColNames:  */ 0, 0,
   430    456     /* iArg:      */ 0 },
   431    457   #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
................................................................................
   442    468   #endif
   443    469   #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
   444    470    {/* zName:     */ "parser_trace",
   445    471     /* ePragTyp:  */ PragTyp_PARSER_TRACE,
   446    472     /* ePragFlg:  */ 0,
   447    473     /* ColNames:  */ 0, 0,
   448    474     /* iArg:      */ 0 },
          475  +#endif
          476  +#if defined(SQLITE_INTROSPECTION_PRAGMAS)
          477  + {/* zName:     */ "pragma_list",
          478  +  /* ePragTyp:  */ PragTyp_PRAGMA_LIST,
          479  +  /* ePragFlg:  */ PragFlg_Result0,
          480  +  /* ColNames:  */ 31, 1,
          481  +  /* iArg:      */ 0 },
   449    482   #endif
   450    483   #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
   451    484    {/* zName:     */ "query_only",
   452    485     /* ePragTyp:  */ PragTyp_FLAG,
   453    486     /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   454    487     /* ColNames:  */ 0, 0,
   455    488     /* iArg:      */ SQLITE_QueryOnly },
................................................................................
   606    639     /* ePragTyp:  */ PragTyp_WAL_AUTOCHECKPOINT,
   607    640     /* ePragFlg:  */ 0,
   608    641     /* ColNames:  */ 0, 0,
   609    642     /* iArg:      */ 0 },
   610    643    {/* zName:     */ "wal_checkpoint",
   611    644     /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
   612    645     /* ePragFlg:  */ PragFlg_NeedSchema,
   613         -  /* ColNames:  */ 43, 3,
          646  +  /* ColNames:  */ 46, 3,
   614    647     /* iArg:      */ 0 },
   615    648   #endif
   616    649   #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
   617    650    {/* zName:     */ "writable_schema",
   618    651     /* ePragTyp:  */ PragTyp_FLAG,
   619    652     /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   620    653     /* ColNames:  */ 0, 0,
   621    654     /* iArg:      */ SQLITE_WriteSchema },
   622    655   #endif
   623    656   };
   624         -/* Number of pragmas: 60 on by default, 75 total. */
          657  +/* Number of pragmas: 60 on by default, 78 total. */

Changes to src/prepare.c.

   761    761     sqlite3 *db,              /* Database handle. */
   762    762     const char *zSql,         /* UTF-8 encoded SQL statement. */
   763    763     int nBytes,               /* Length of zSql in bytes. */
   764    764     sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
   765    765     const char **pzTail       /* OUT: End of parsed string */
   766    766   ){
   767    767     int rc;
          768  +  /* EVIDENCE-OF: R-37923-12173 The sqlite3_prepare_v2() interface works
          769  +  ** exactly the same as sqlite3_prepare_v3() with a zero prepFlags
          770  +  ** parameter.
          771  +  **
          772  +  ** Proof in that the 5th parameter to sqlite3LockAndPrepare is 0 */
   768    773     rc = sqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0,
   769    774                                ppStmt,pzTail);
   770         -  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
          775  +  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
   771    776     return rc;
   772    777   }
   773    778   int sqlite3_prepare_v3(
   774    779     sqlite3 *db,              /* Database handle. */
   775    780     const char *zSql,         /* UTF-8 encoded SQL statement. */
   776    781     int nBytes,               /* Length of zSql in bytes. */
   777    782     unsigned int prepFlags,   /* Zero or more SQLITE_PREPARE_* flags */
   778    783     sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
   779    784     const char **pzTail       /* OUT: End of parsed string */
   780    785   ){
   781    786     int rc;
          787  +  /* EVIDENCE-OF: R-56861-42673 sqlite3_prepare_v3() differs from
          788  +  ** sqlite3_prepare_v2() only in having the extra prepFlags parameter,
          789  +  ** which is a bit array consisting of zero or more of the
          790  +  ** SQLITE_PREPARE_* flags.
          791  +  **
          792  +  ** Proof by comparison to the implementation of sqlite3_prepare_v2()
          793  +  ** directly above. */
   782    794     rc = sqlite3LockAndPrepare(db,zSql,nBytes,
   783    795                    SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK),
   784    796                    0,ppStmt,pzTail);
   785         -  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
          797  +  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );
   786    798     return rc;
   787    799   }
   788    800   
   789    801   
   790    802   #ifndef SQLITE_OMIT_UTF16
   791    803   /*
   792    804   ** Compile the UTF-16 encoded SQL statement zSql into a statement handle.

Changes to src/resolve.c.

   513    513         p->iColumn = -1;
   514    514       }else{
   515    515         p->iColumn = (ynVar)iCol;
   516    516         testcase( iCol==BMS );
   517    517         testcase( iCol==BMS-1 );
   518    518         pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
   519    519       }
   520         -    ExprSetProperty(p, EP_Resolved);
   521    520     }
   522    521     return p;
   523    522   }
   524    523   
   525    524   /*
   526    525   ** Report an error that an expression is not valid for some set of
   527    526   ** pNC->ncFlags values determined by validMask.
................................................................................
   573    572     Parse *pParse;
   574    573   
   575    574     pNC = pWalker->u.pNC;
   576    575     assert( pNC!=0 );
   577    576     pParse = pNC->pParse;
   578    577     assert( pParse==pWalker->pParse );
   579    578   
   580         -  if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune;
   581         -  ExprSetProperty(pExpr, EP_Resolved);
   582    579   #ifndef NDEBUG
   583    580     if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
   584    581       SrcList *pSrcList = pNC->pSrcList;
   585    582       int i;
   586    583       for(i=0; i<pNC->pSrcList->nSrc; i++){
   587    584         assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
   588    585       }

Changes to src/select.c.

  1564   1564       if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab;
  1565   1565     }
  1566   1566     return 0;
  1567   1567   }
  1568   1568   
  1569   1569   
  1570   1570   /*
  1571         -** Generate code that will tell the VDBE the names of columns
  1572         -** in the result set.  This information is used to provide the
  1573         -** azCol[] values in the callback.
         1571  +** Compute the column names for a SELECT statement.
         1572  +**
         1573  +** The only guarantee that SQLite makes about column names is that if the
         1574  +** column has an AS clause assigning it a name, that will be the name used.
         1575  +** That is the only documented guarantee.  However, countless applications
         1576  +** developed over the years have made baseless assumptions about column names
         1577  +** and will break if those assumptions changes.  Hence, use extreme caution
         1578  +** when modifying this routine to avoid breaking legacy.
         1579  +**
         1580  +** See Also: sqlite3ColumnsFromExprList()
         1581  +**
         1582  +** The PRAGMA short_column_names and PRAGMA full_column_names settings are
         1583  +** deprecated.  The default setting is short=ON, full=OFF.  99.9% of all
         1584  +** applications should operate this way.  Nevertheless, we need to support the
         1585  +** other modes for legacy:
         1586  +**
         1587  +**    short=OFF, full=OFF:      Column name is the text of the expression has it
         1588  +**                              originally appears in the SELECT statement.  In
         1589  +**                              other words, the zSpan of the result expression.
         1590  +**
         1591  +**    short=ON, full=OFF:       (This is the default setting).  If the result
         1592  +**                              refers directly to a table column, then the result
         1593  +**                              column name is just the table column name: COLUMN. 
         1594  +**                              Otherwise use zSpan.
         1595  +**
         1596  +**    full=ON, short=ANY:       If the result refers directly to a table column,
         1597  +**                              then the result column name with the table name
         1598  +**                              prefix, ex: TABLE.COLUMN.  Otherwise use zSpan.
  1574   1599   */
  1575   1600   static void generateColumnNames(
  1576   1601     Parse *pParse,      /* Parser context */
  1577         -  SrcList *pTabList,  /* List of tables */
         1602  +  SrcList *pTabList,  /* The FROM clause of the SELECT */
  1578   1603     ExprList *pEList    /* Expressions defining the result set */
  1579   1604   ){
  1580   1605     Vdbe *v = pParse->pVdbe;
  1581   1606     int i;
  1582   1607     Table *pTab;
  1583   1608     sqlite3 *db = pParse->db;
  1584         -  int fullNames, shortNames;
         1609  +  int fullName;      /* TABLE.COLUMN if no AS clause and is a direct table ref */
         1610  +  int srcName;       /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
  1585   1611   
  1586   1612   #ifndef SQLITE_OMIT_EXPLAIN
  1587   1613     /* If this is an EXPLAIN, skip this step */
  1588   1614     if( pParse->explain ){
  1589   1615       return;
  1590   1616     }
  1591   1617   #endif
  1592   1618   
  1593   1619     if( pParse->colNamesSet || db->mallocFailed ) return;
  1594   1620     assert( v!=0 );
  1595   1621     assert( pTabList!=0 );
  1596   1622     pParse->colNamesSet = 1;
  1597         -  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  1598         -  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
         1623  +  fullName = (db->flags & SQLITE_FullColNames)!=0;
         1624  +  srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName;
  1599   1625     sqlite3VdbeSetNumCols(v, pEList->nExpr);
  1600   1626     for(i=0; i<pEList->nExpr; i++){
  1601         -    Expr *p;
  1602         -    p = pEList->a[i].pExpr;
  1603         -    if( NEVER(p==0) ) continue;
         1627  +    Expr *p = pEList->a[i].pExpr;
         1628  +
         1629  +    assert( p!=0 );
  1604   1630       if( pEList->a[i].zName ){
         1631  +      /* An AS clause always takes first priority */
  1605   1632         char *zName = pEList->a[i].zName;
  1606   1633         sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
  1607         -    }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN)
         1634  +    }else if( srcName
         1635  +           && (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN)
  1608   1636              && (pTab = tableWithCursor(pTabList, p->iTable))!=0
  1609   1637       ){
  1610   1638         char *zCol;
  1611   1639         int iCol = p->iColumn;
  1612   1640         if( iCol<0 ) iCol = pTab->iPKey;
  1613   1641         assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
  1614   1642         if( iCol<0 ){
  1615   1643           zCol = "rowid";
  1616   1644         }else{
  1617   1645           zCol = pTab->aCol[iCol].zName;
  1618   1646         }
  1619         -      if( !shortNames && !fullNames ){
  1620         -        sqlite3VdbeSetColName(v, i, COLNAME_NAME, 
  1621         -            sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
  1622         -      }else if( fullNames ){
         1647  +      if( fullName ){
  1623   1648           char *zName = 0;
  1624   1649           zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
  1625   1650           sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
  1626   1651         }else{
  1627   1652           sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
  1628   1653         }
  1629   1654       }else{
................................................................................
  1643   1668   ** All column names will be unique.
  1644   1669   **
  1645   1670   ** Only the column names are computed.  Column.zType, Column.zColl,
  1646   1671   ** and other fields of Column are zeroed.
  1647   1672   **
  1648   1673   ** Return SQLITE_OK on success.  If a memory allocation error occurs,
  1649   1674   ** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
         1675  +**
         1676  +** The only guarantee that SQLite makes about column names is that if the
         1677  +** column has an AS clause assigning it a name, that will be the name used.
         1678  +** That is the only documented guarantee.  However, countless applications
         1679  +** developed over the years have made baseless assumptions about column names
         1680  +** and will break if those assumptions changes.  Hence, use extreme caution
         1681  +** when modifying this routine to avoid breaking legacy.
         1682  +**
         1683  +** See Also: generateColumnNames()
  1650   1684   */
  1651   1685   int sqlite3ColumnsFromExprList(
  1652   1686     Parse *pParse,          /* Parsing context */
  1653   1687     ExprList *pEList,       /* Expr list from which to derive column names */
  1654   1688     i16 *pnCol,             /* Write the number of columns here */
  1655   1689     Column **paCol          /* Write the new column list here */
  1656   1690   ){
  1657   1691     sqlite3 *db = pParse->db;   /* Database connection */
  1658   1692     int i, j;                   /* Loop counters */
  1659   1693     u32 cnt;                    /* Index added to make the name unique */
  1660   1694     Column *aCol, *pCol;        /* For looping over result columns */
  1661   1695     int nCol;                   /* Number of columns in the result set */
  1662         -  Expr *p;                    /* Expression for a single result column */
  1663   1696     char *zName;                /* Column name */
  1664   1697     int nName;                  /* Size of name in zName[] */
  1665   1698     Hash ht;                    /* Hash table of column names */
  1666   1699   
  1667   1700     sqlite3HashInit(&ht);
  1668   1701     if( pEList ){
  1669   1702       nCol = pEList->nExpr;
................................................................................
  1676   1709     assert( nCol==(i16)nCol );
  1677   1710     *pnCol = nCol;
  1678   1711     *paCol = aCol;
  1679   1712   
  1680   1713     for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
  1681   1714       /* Get an appropriate name for the column
  1682   1715       */
  1683         -    p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
  1684   1716       if( (zName = pEList->a[i].zName)!=0 ){
  1685   1717         /* If the column contains an "AS <name>" phrase, use <name> as the name */
  1686   1718       }else{
  1687         -      Expr *pColExpr = p;  /* The expression that is the result column name */
  1688         -      Table *pTab;         /* Table associated with this expression */
         1719  +      Expr *pColExpr = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
  1689   1720         while( pColExpr->op==TK_DOT ){
  1690   1721           pColExpr = pColExpr->pRight;
  1691   1722           assert( pColExpr!=0 );
  1692   1723         }
  1693   1724         if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){
  1694   1725           /* For columns use the column name name */
  1695   1726           int iCol = pColExpr->iColumn;
  1696         -        pTab = pColExpr->pTab;
         1727  +        Table *pTab = pColExpr->pTab;
  1697   1728           if( iCol<0 ) iCol = pTab->iPKey;
  1698   1729           zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
  1699   1730         }else if( pColExpr->op==TK_ID ){
  1700   1731           assert( !ExprHasProperty(pColExpr, EP_IntValue) );
  1701   1732           zName = pColExpr->u.zToken;
  1702   1733         }else{
  1703   1734           /* Use the original text of the column expression as its name */
  1704   1735           zName = pEList->a[i].zSpan;
  1705   1736         }
  1706   1737       }
  1707         -    zName = sqlite3MPrintf(db, "%s", zName);
         1738  +    if( zName ){
         1739  +      zName = sqlite3DbStrDup(db, zName);
         1740  +    }else{
         1741  +      zName = sqlite3MPrintf(db,"column%d",i+1);
         1742  +    }
  1708   1743   
  1709   1744       /* Make sure the column name is unique.  If the name is not unique,
  1710   1745       ** append an integer to the name so that it becomes unique.
  1711   1746       */
  1712   1747       cnt = 0;
  1713   1748       while( zName && sqlite3HashFind(&ht, zName)!=0 ){
  1714   1749         nName = sqlite3Strlen30(zName);
................................................................................
  3300   3335   **
  3301   3336   **   (2)  The subquery is not an aggregate or (2a) the outer query is not a join
  3302   3337   **        and (2b) the outer query does not use subqueries other than the one
  3303   3338   **        FROM-clause subquery that is a candidate for flattening.  (2b is
  3304   3339   **        due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
  3305   3340   **
  3306   3341   **   (3)  The subquery is not the right operand of a LEFT JOIN
  3307         -**        or the subquery is not itself a join and the outer query is not
  3308         -**        an aggregate.
         3342  +**        or (a) the subquery is not itself a join and (b) the FROM clause
         3343  +**        of the subquery does not contain a virtual table and (c) the 
         3344  +**        outer query is not an aggregate.
  3309   3345   **
  3310   3346   **   (4)  The subquery is not DISTINCT.
  3311   3347   **
  3312   3348   **  (**)  At one point restrictions (4) and (5) defined a subset of DISTINCT
  3313   3349   **        sub-queries that were excluded from this optimization. Restriction 
  3314   3350   **        (4) has since been expanded to exclude all DISTINCT subqueries.
  3315   3351   **
................................................................................
  3506   3542     ** are processed - there is no mechanism to determine if the LEFT JOIN
  3507   3543     ** table should be all-NULL.
  3508   3544     **
  3509   3545     ** See also tickets #306, #350, and #3300.
  3510   3546     */
  3511   3547     if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
  3512   3548       isLeftJoin = 1;
  3513         -    if( pSubSrc->nSrc>1 || isAgg ){
         3549  +    if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
  3514   3550         return 0; /* Restriction (3) */
  3515   3551       }
  3516   3552     }
  3517   3553   #ifdef SQLITE_EXTRA_IFNULLROW
  3518   3554     else if( iFrom>0 && !isAgg ){
  3519   3555       /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
  3520   3556       ** every reference to any result column from subquery in a join, even though

Changes to src/shell.c.

            1  +/* DO NOT EDIT!
            2  +** This file is automatically generated by the script in the canonical
            3  +** SQLite source tree at tool/mkshellc.tcl.  That script combines source
            4  +** code from various constituent source files of SQLite into this single
            5  +** "shell.c" file used to implement the SQLite command-line shell.
            6  +**
            7  +** Most of the code found below comes from the "src/shell.c.in" file in
            8  +** the canonical SQLite source tree.  That main file contains "INCLUDE"
            9  +** lines that specify other files in the canonical source tree that are
           10  +** inserted to getnerate this complete program source file.
           11  +**
           12  +** The code from multiple files is combined into this single "shell.c"
           13  +** source file to help make the command-line program easier to compile.
           14  +**
           15  +** To modify this program, get a copy of the canonical SQLite source tree,
           16  +** edit the src/shell.c.in" and/or some of the other files that are included
           17  +** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
           18  +*/
     1     19   /*
     2     20   ** 2001 September 15
     3     21   **
     4     22   ** The author disclaims copyright to this source code.  In place of
     5     23   ** a legal notice, here is a blessing:
     6     24   **
     7     25   **    May you do good and not evil.
................................................................................
   762    780        "VIRTUAL TABLE"
   763    781     };
   764    782     int i = 0;
   765    783     const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
   766    784     const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
   767    785     assert( nVal==2 );
   768    786     if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
   769         -    for(i=0; i<sizeof(aPrefix)/sizeof(aPrefix[0]); i++){
          787  +    for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
   770    788         int n = strlen30(aPrefix[i]);
   771    789         if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
   772    790           char cQuote = quoteChar(zSchema);
   773    791           char *z;
   774    792           if( cQuote ){
   775    793            z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
   776    794           }else{
................................................................................
   780    798           return;
   781    799         }
   782    800       }
   783    801     }
   784    802     sqlite3_result_value(pCtx, apVal[0]);
   785    803   }
   786    804   
   787         -/******************************************************************************
   788         -** SHA3 hash implementation copied from ../ext/misc/shathree.c
          805  +/*
          806  +** The source code for several run-time loadable extensions is inserted
          807  +** below by the ../tool/mkshellc.tcl script.  Before processing that included
          808  +** code, we need to override some macros to make the included program code
          809  +** work here in the middle of this regular program.
   789    810   */
          811  +#define SQLITE_EXTENSION_INIT1
          812  +#define SQLITE_EXTENSION_INIT2(X) (void)(X)
          813  +
          814  +/************************* Begin ../ext/misc/shathree.c ******************/
          815  +/*
          816  +** 2017-03-08
          817  +**
          818  +** The author disclaims copyright to this source code.  In place of
          819  +** a legal notice, here is a blessing:
          820  +**
          821  +**    May you do good and not evil.
          822  +**    May you find forgiveness for yourself and forgive others.
          823  +**    May you share freely, never taking more than you give.
          824  +**
          825  +******************************************************************************
          826  +**
          827  +** This SQLite extension implements a functions that compute SHA1 hashes.
          828  +** Two SQL functions are implemented:
          829  +**
          830  +**     sha3(X,SIZE)
          831  +**     sha3_query(Y,SIZE)
          832  +**
          833  +** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
          834  +** X is NULL.
          835  +**
          836  +** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
          837  +** and returns a hash of their results.
          838  +**
          839  +** The SIZE argument is optional.  If omitted, the SHA3-256 hash algorithm
          840  +** is used.  If SIZE is included it must be one of the integers 224, 256,
          841  +** 384, or 512, to determine SHA3 hash variant that is computed.
          842  +*/
          843  +SQLITE_EXTENSION_INIT1
          844  +#include <assert.h>
          845  +#include <string.h>
          846  +#include <stdarg.h>
   790    847   typedef sqlite3_uint64 u64;
          848  +
          849  +/******************************************************************************
          850  +** The Hash Engine
          851  +*/
   791    852   /*
   792    853   ** Macros to determine whether the machine is big or little endian,
   793    854   ** and whether or not that determination is run-time or compile-time.
   794    855   **
   795    856   ** For best performance, an attempt is made to guess at the byte-order
   796    857   ** using C-preprocessor macros.  If that is unsuccessful, or if
   797    858   ** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
................................................................................
   821    882       unsigned char x[1600];    /* ... or 1600 bytes */
   822    883     } u;
   823    884     unsigned nRate;        /* Bytes of input accepted per Keccak iteration */
   824    885     unsigned nLoaded;      /* Input bytes loaded into u.x[] so far this cycle */
   825    886     unsigned ixMask;       /* Insert next input into u.x[nLoaded^ixMask]. */
   826    887   };
   827    888   
   828         -/* Allow the following routine to use the B0 variable, which is also
   829         -** a macro in the termios.h header file */
   830         -#undef B0
   831         -
   832    889   /*
   833    890   ** A single step of the Keccak mixing function for a 1600-bit state
   834    891   */
   835    892   static void KeccakF1600Step(SHA3Context *p){
   836    893     int i;
   837    894     u64 B0, B1, B2, B3, B4;
   838    895     u64 C0, C1, C2, C3, C4;
................................................................................
  1235   1292       SHA3Update(p, &c3, 1);
  1236   1293     }
  1237   1294     for(i=0; i<p->nRate; i++){
  1238   1295       p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
  1239   1296     }
  1240   1297     return &p->u.x[p->nRate];
  1241   1298   }
         1299  +/* End of the hashing logic
         1300  +*****************************************************************************/
  1242   1301   
  1243   1302   /*
  1244   1303   ** Implementation of the sha3(X,SIZE) function.
  1245   1304   **
  1246   1305   ** Return a BLOB which is the SIZE-bit SHA3 hash of X.  The default
  1247         -** size is 256.  If X is a BLOB, it is hashed as is.
         1306  +** size is 256.  If X is a BLOB, it is hashed as is.  
  1248   1307   ** For all other non-NULL types of input, X is converted into a UTF-8 string
  1249   1308   ** and the string is hashed without the trailing 0x00 terminator.  The hash
  1250   1309   ** of a NULL value is NULL.
  1251   1310   */
  1252   1311   static void sha3Func(
  1253   1312     sqlite3_context *context,
  1254   1313     int argc,
................................................................................
  1371   1430         sqlite3_finalize(pStmt);
  1372   1431         sqlite3_result_error(context, zMsg, -1);
  1373   1432         sqlite3_free(zMsg);
  1374   1433         return;
  1375   1434       }
  1376   1435       nCol = sqlite3_column_count(pStmt);
  1377   1436       z = sqlite3_sql(pStmt);
  1378         -    if( z==0 ){
  1379         -      sqlite3_finalize(pStmt);
  1380         -      continue;
  1381         -    }
  1382   1437       n = (int)strlen(z);
  1383   1438       hash_step_vformat(&cx,"S%d:",n);
  1384   1439       SHA3Update(&cx,(unsigned char*)z,n);
  1385   1440   
  1386   1441       /* Compute a hash over the result of the query */
  1387   1442       while( SQLITE_ROW==sqlite3_step(pStmt) ){
  1388   1443         SHA3Update(&cx,(const unsigned char*)"R",1);
................................................................................
  1437   1492           }
  1438   1493         }
  1439   1494       }
  1440   1495       sqlite3_finalize(pStmt);
  1441   1496     }
  1442   1497     sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
  1443   1498   }
  1444         -/* End of SHA3 hashing logic copy/pasted from ../ext/misc/shathree.c
  1445         -********************************************************************************/
         1499  +
         1500  +
         1501  +#ifdef _WIN32
         1502  +__declspec(dllexport)
         1503  +#endif
         1504  +int sqlite3_shathree_init(
         1505  +  sqlite3 *db,
         1506  +  char **pzErrMsg,
         1507  +  const sqlite3_api_routines *pApi
         1508  +){
         1509  +  int rc = SQLITE_OK;
         1510  +  SQLITE_EXTENSION_INIT2(pApi);
         1511  +  (void)pzErrMsg;  /* Unused parameter */
         1512  +  rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0,
         1513  +                               sha3Func, 0, 0);
         1514  +  if( rc==SQLITE_OK ){
         1515  +    rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
         1516  +                                 sha3Func, 0, 0);
         1517  +  }
         1518  +  if( rc==SQLITE_OK ){
         1519  +    rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
         1520  +                                 sha3QueryFunc, 0, 0);
         1521  +  }
         1522  +  if( rc==SQLITE_OK ){
         1523  +    rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
         1524  +                                 sha3QueryFunc, 0, 0);
         1525  +  }
         1526  +  return rc;
         1527  +}
         1528  +
         1529  +/************************* End ../ext/misc/shathree.c ********************/
         1530  +/************************* Begin ../ext/misc/fileio.c ******************/
         1531  +/*
         1532  +** 2014-06-13
         1533  +**
         1534  +** The author disclaims copyright to this source code.  In place of
         1535  +** a legal notice, here is a blessing:
         1536  +**
         1537  +**    May you do good and not evil.
         1538  +**    May you find forgiveness for yourself and forgive others.
         1539  +**    May you share freely, never taking more than you give.
         1540  +**
         1541  +******************************************************************************
         1542  +**
         1543  +** This SQLite extension implements SQL functions readfile() and
         1544  +** writefile().
         1545  +*/
         1546  +SQLITE_EXTENSION_INIT1
         1547  +#include <stdio.h>
         1548  +
         1549  +/*
         1550  +** Implementation of the "readfile(X)" SQL function.  The entire content
         1551  +** of the file named X is read and returned as a BLOB.  NULL is returned
         1552  +** if the file does not exist or is unreadable.
         1553  +*/
         1554  +static void readfileFunc(
         1555  +  sqlite3_context *context,
         1556  +  int argc,
         1557  +  sqlite3_value **argv
         1558  +){
         1559  +  const char *zName;
         1560  +  FILE *in;
         1561  +  long nIn;
         1562  +  void *pBuf;
         1563  +
         1564  +  (void)(argc);  /* Unused parameter */
         1565  +  zName = (const char*)sqlite3_value_text(argv[0]);
         1566  +  if( zName==0 ) return;
         1567  +  in = fopen(zName, "rb");
         1568  +  if( in==0 ) return;
         1569  +  fseek(in, 0, SEEK_END);
         1570  +  nIn = ftell(in);
         1571  +  rewind(in);
         1572  +  pBuf = sqlite3_malloc( nIn );
         1573  +  if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
         1574  +    sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
         1575  +  }else{
         1576  +    sqlite3_free(pBuf);
         1577  +  }
         1578  +  fclose(in);
         1579  +}
         1580  +
         1581  +/*
         1582  +** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
         1583  +** is written into file X.  The number of bytes written is returned.  Or
         1584  +** NULL is returned if something goes wrong, such as being unable to open
         1585  +** file X for writing.
         1586  +*/
         1587  +static void writefileFunc(
         1588  +  sqlite3_context *context,
         1589  +  int argc,
         1590  +  sqlite3_value **argv
         1591  +){
         1592  +  FILE *out;
         1593  +  const char *z;
         1594  +  sqlite3_int64 rc;
         1595  +  const char *zFile;
         1596  +
         1597  +  (void)(argc);  /* Unused parameter */
         1598  +  zFile = (const char*)sqlite3_value_text(argv[0]);
         1599  +  if( zFile==0 ) return;
         1600  +  out = fopen(zFile, "wb");
         1601  +  if( out==0 ) return;
         1602  +  z = (const char*)sqlite3_value_blob(argv[1]);
         1603  +  if( z==0 ){
         1604  +    rc = 0;
         1605  +  }else{
         1606  +    rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
         1607  +  }
         1608  +  fclose(out);
         1609  +  sqlite3_result_int64(context, rc);
         1610  +}
         1611  +
         1612  +
         1613  +#ifdef _WIN32
         1614  +__declspec(dllexport)
         1615  +#endif
         1616  +int sqlite3_fileio_init(
         1617  +  sqlite3 *db, 
         1618  +  char **pzErrMsg, 
         1619  +  const sqlite3_api_routines *pApi
         1620  +){
         1621  +  int rc = SQLITE_OK;
         1622  +  SQLITE_EXTENSION_INIT2(pApi);
         1623  +  (void)pzErrMsg;  /* Unused parameter */
         1624  +  rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
         1625  +                               readfileFunc, 0, 0);
         1626  +  if( rc==SQLITE_OK ){
         1627  +    rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
         1628  +                                 writefileFunc, 0, 0);
         1629  +  }
         1630  +  return rc;
         1631  +}
         1632  +
         1633  +/************************* End ../ext/misc/fileio.c ********************/
         1634  +/************************* Begin ../ext/misc/completion.c ******************/
         1635  +/*
         1636  +** 2017-07-10
         1637  +**
         1638  +** The author disclaims copyright to this source code.  In place of
         1639  +** a legal notice, here is a blessing:
         1640  +**
         1641  +**    May you do good and not evil.
         1642  +**    May you find forgiveness for yourself and forgive others.
         1643  +**    May you share freely, never taking more than you give.
         1644  +**
         1645  +*************************************************************************
         1646  +**
         1647  +** This file implements an eponymous virtual table that returns suggested
         1648  +** completions for a partial SQL input.
         1649  +**
         1650  +** Suggested usage:
         1651  +**
         1652  +**     SELECT DISTINCT candidate COLLATE nocase
         1653  +**       FROM completion($prefix,$wholeline)
         1654  +**      ORDER BY 1;
         1655  +**
         1656  +** The two query parameters are optional.  $prefix is the text of the
         1657  +** current word being typed and that is to be completed.  $wholeline is
         1658  +** the complete input line, used for context.
         1659  +**
         1660  +** The raw completion() table might return the same candidate multiple
         1661  +** times, for example if the same column name is used to two or more
         1662  +** tables.  And the candidates are returned in an arbitrary order.  Hence,
         1663  +** the DISTINCT and ORDER BY are recommended.
         1664  +**
         1665  +** This virtual table operates at the speed of human typing, and so there
         1666  +** is no attempt to make it fast.  Even a slow implementation will be much
         1667  +** faster than any human can type.
         1668  +**
         1669  +*/
         1670  +SQLITE_EXTENSION_INIT1
         1671  +#include <assert.h>
         1672  +#include <string.h>
         1673  +#include <ctype.h>
         1674  +
         1675  +#ifndef SQLITE_OMIT_VIRTUALTABLE
         1676  +
         1677  +/* completion_vtab is a subclass of sqlite3_vtab which will
         1678  +** serve as the underlying representation of a completion virtual table
         1679  +*/
         1680  +typedef struct completion_vtab completion_vtab;
         1681  +struct completion_vtab {
         1682  +  sqlite3_vtab base;  /* Base class - must be first */
         1683  +  sqlite3 *db;        /* Database connection for this completion vtab */
         1684  +};
         1685  +
         1686  +/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
         1687  +** serve as the underlying representation of a cursor that scans
         1688  +** over rows of the result
         1689  +*/
         1690  +typedef struct completion_cursor completion_cursor;
         1691  +struct completion_cursor {
         1692  +  sqlite3_vtab_cursor base;  /* Base class - must be first */
         1693  +  sqlite3 *db;               /* Database connection for this cursor */
         1694  +  int nPrefix, nLine;        /* Number of bytes in zPrefix and zLine */
         1695  +  char *zPrefix;             /* The prefix for the word we want to complete */
         1696  +  char *zLine;               /* The whole that we want to complete */
         1697  +  const char *zCurrentRow;   /* Current output row */
         1698  +  sqlite3_stmt *pStmt;       /* Current statement */
         1699  +  sqlite3_int64 iRowid;      /* The rowid */
         1700  +  int ePhase;                /* Current phase */
         1701  +  int j;                     /* inter-phase counter */
         1702  +};
         1703  +
         1704  +/* Values for ePhase:
         1705  +*/
         1706  +#define COMPLETION_FIRST_PHASE   1
         1707  +#define COMPLETION_KEYWORDS      1
         1708  +#define COMPLETION_PRAGMAS       2
         1709  +#define COMPLETION_FUNCTIONS     3
         1710  +#define COMPLETION_COLLATIONS    4
         1711  +#define COMPLETION_INDEXES       5
         1712  +#define COMPLETION_TRIGGERS      6
         1713  +#define COMPLETION_DATABASES     7
         1714  +#define COMPLETION_TABLES        8
         1715  +#define COMPLETION_COLUMNS       9
         1716  +#define COMPLETION_MODULES       10
         1717  +#define COMPLETION_EOF           11
         1718  +
         1719  +/*
         1720  +** The completionConnect() method is invoked to create a new
         1721  +** completion_vtab that describes the completion virtual table.
         1722  +**
         1723  +** Think of this routine as the constructor for completion_vtab objects.
         1724  +**
         1725  +** All this routine needs to do is:
         1726  +**
         1727  +**    (1) Allocate the completion_vtab object and initialize all fields.
         1728  +**
         1729  +**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
         1730  +**        result set of queries against completion will look like.
         1731  +*/
         1732  +static int completionConnect(
         1733  +  sqlite3 *db,
         1734  +  void *pAux,
         1735  +  int argc, const char *const*argv,
         1736  +  sqlite3_vtab **ppVtab,
         1737  +  char **pzErr
         1738  +){
         1739  +  completion_vtab *pNew;
         1740  +  int rc;
         1741  +
         1742  +  (void)(pAux);    /* Unused parameter */
         1743  +  (void)(argc);    /* Unused parameter */
         1744  +  (void)(argv);    /* Unused parameter */
         1745  +  (void)(pzErr);   /* Unused parameter */
         1746  +
         1747  +/* Column numbers */
         1748  +#define COMPLETION_COLUMN_CANDIDATE 0  /* Suggested completion of the input */
         1749  +#define COMPLETION_COLUMN_PREFIX    1  /* Prefix of the word to be completed */
         1750  +#define COMPLETION_COLUMN_WHOLELINE 2  /* Entire line seen so far */
         1751  +#define COMPLETION_COLUMN_PHASE     3  /* ePhase - used for debugging only */
         1752  +
         1753  +  rc = sqlite3_declare_vtab(db,
         1754  +      "CREATE TABLE x("
         1755  +      "  candidate TEXT,"
         1756  +      "  prefix TEXT HIDDEN,"
         1757  +      "  wholeline TEXT HIDDEN,"
         1758  +      "  phase INT HIDDEN"        /* Used for debugging only */
         1759  +      ")");
         1760  +  if( rc==SQLITE_OK ){
         1761  +    pNew = sqlite3_malloc( sizeof(*pNew) );
         1762  +    *ppVtab = (sqlite3_vtab*)pNew;
         1763  +    if( pNew==0 ) return SQLITE_NOMEM;
         1764  +    memset(pNew, 0, sizeof(*pNew));
         1765  +    pNew->db = db;
         1766  +  }
         1767  +  return rc;
         1768  +}
         1769  +
         1770  +/*
         1771  +** This method is the destructor for completion_cursor objects.
         1772  +*/
         1773  +static int completionDisconnect(sqlite3_vtab *pVtab){
         1774  +  sqlite3_free(pVtab);
         1775  +  return SQLITE_OK;
         1776  +}
         1777  +
         1778  +/*
         1779  +** Constructor for a new completion_cursor object.
         1780  +*/
         1781  +static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
         1782  +  completion_cursor *pCur;
         1783  +  pCur = sqlite3_malloc( sizeof(*pCur) );
         1784  +  if( pCur==0 ) return SQLITE_NOMEM;
         1785  +  memset(pCur, 0, sizeof(*pCur));
         1786  +  pCur->db = ((completion_vtab*)p)->db;
         1787  +  *ppCursor = &pCur->base;
         1788  +  return SQLITE_OK;
         1789  +}
         1790  +
         1791  +/*
         1792  +** Reset the completion_cursor.
         1793  +*/
         1794  +static void completionCursorReset(completion_cursor *pCur){
         1795  +  sqlite3_free(pCur->zPrefix);   pCur->zPrefix = 0;  pCur->nPrefix = 0;
         1796  +  sqlite3_free(pCur->zLine);     pCur->zLine = 0;    pCur->nLine = 0;
         1797  +  sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
         1798  +  pCur->j = 0;
         1799  +}
         1800  +
         1801  +/*
         1802  +** Destructor for a completion_cursor.
         1803  +*/
         1804  +static int completionClose(sqlite3_vtab_cursor *cur){
         1805  +  completionCursorReset((completion_cursor*)cur);
         1806  +  sqlite3_free(cur);
         1807  +  return SQLITE_OK;
         1808  +}
         1809  +
         1810  +/*
         1811  +** All SQL keywords understood by SQLite
         1812  +*/
         1813  +static const char *completionKwrds[] = {
         1814  +  "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
         1815  +  "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
         1816  +  "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
         1817  +  "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
         1818  +  "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
         1819  +  "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
         1820  +  "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
         1821  +  "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
         1822  +  "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
         1823  +  "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
         1824  +  "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
         1825  +  "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
         1826  +  "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
         1827  +  "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
         1828  +  "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
         1829  +  "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
         1830  +  "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
         1831  +  "WITH", "WITHOUT",
         1832  +};
         1833  +#define completionKwCount \
         1834  +   (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0]))
         1835  +
         1836  +/*
         1837  +** Advance a completion_cursor to its next row of output.
         1838  +**
         1839  +** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
         1840  +** record the current state of the scan.  This routine sets ->zCurrentRow
         1841  +** to the current row of output and then returns.  If no more rows remain,
         1842  +** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
         1843  +** table that has reached the end of its scan.
         1844  +**
         1845  +** The current implementation just lists potential identifiers and
         1846  +** keywords and filters them by zPrefix.  Future enhancements should
         1847  +** take zLine into account to try to restrict the set of identifiers and
         1848  +** keywords based on what would be legal at the current point of input.
         1849  +*/
         1850  +static int completionNext(sqlite3_vtab_cursor *cur){
         1851  +  completion_cursor *pCur = (completion_cursor*)cur;
         1852  +  int eNextPhase = 0;  /* Next phase to try if current phase reaches end */
         1853  +  int iCol = -1;       /* If >=0, step pCur->pStmt and use the i-th column */
         1854  +  pCur->iRowid++;
         1855  +  while( pCur->ePhase!=COMPLETION_EOF ){
         1856  +    switch( pCur->ePhase ){
         1857  +      case COMPLETION_KEYWORDS: {
         1858  +        if( pCur->j >= completionKwCount ){
         1859  +          pCur->zCurrentRow = 0;
         1860  +          pCur->ePhase = COMPLETION_DATABASES;
         1861  +        }else{
         1862  +          pCur->zCurrentRow = completionKwrds[pCur->j++];
         1863  +        }
         1864  +        iCol = -1;
         1865  +        break;
         1866  +      }
         1867  +      case COMPLETION_DATABASES: {
         1868  +        if( pCur->pStmt==0 ){
         1869  +          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
         1870  +                             &pCur->pStmt, 0);
         1871  +        }
         1872  +        iCol = 1;
         1873  +        eNextPhase = COMPLETION_TABLES;
         1874  +        break;
         1875  +      }
         1876  +      case COMPLETION_TABLES: {
         1877  +        if( pCur->pStmt==0 ){
         1878  +          sqlite3_stmt *pS2;
         1879  +          char *zSql = 0;
         1880  +          const char *zSep = "";
         1881  +          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
         1882  +          while( sqlite3_step(pS2)==SQLITE_ROW ){
         1883  +            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
         1884  +            zSql = sqlite3_mprintf(
         1885  +               "%z%s"
         1886  +               "SELECT name FROM \"%w\".sqlite_master"
         1887  +               " WHERE type='table'",
         1888  +               zSql, zSep, zDb
         1889  +            );
         1890  +            if( zSql==0 ) return SQLITE_NOMEM;
         1891  +            zSep = " UNION ";
         1892  +          }
         1893  +          sqlite3_finalize(pS2);
         1894  +          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
         1895  +          sqlite3_free(zSql);
         1896  +        }
         1897  +        iCol = 0;
         1898  +        eNextPhase = COMPLETION_COLUMNS;
         1899  +        break;
         1900  +      }
         1901  +      case COMPLETION_COLUMNS: {
         1902  +        if( pCur->pStmt==0 ){
         1903  +          sqlite3_stmt *pS2;
         1904  +          char *zSql = 0;
         1905  +          const char *zSep = "";
         1906  +          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
         1907  +          while( sqlite3_step(pS2)==SQLITE_ROW ){
         1908  +            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
         1909  +            zSql = sqlite3_mprintf(
         1910  +               "%z%s"
         1911  +               "SELECT pti.name FROM \"%w\".sqlite_master AS sm"
         1912  +                       " JOIN pragma_table_info(sm.name,%Q) AS pti"
         1913  +               " WHERE sm.type='table'",
         1914  +               zSql, zSep, zDb, zDb
         1915  +            );
         1916  +            if( zSql==0 ) return SQLITE_NOMEM;
         1917  +            zSep = " UNION ";
         1918  +          }
         1919  +          sqlite3_finalize(pS2);
         1920  +          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
         1921  +          sqlite3_free(zSql);
         1922  +        }
         1923  +        iCol = 0;
         1924  +        eNextPhase = COMPLETION_EOF;
         1925  +        break;
         1926  +      }
         1927  +    }
         1928  +    if( iCol<0 ){
         1929  +      /* This case is when the phase presets zCurrentRow */
         1930  +      if( pCur->zCurrentRow==0 ) continue;
         1931  +    }else{
         1932  +      if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
         1933  +        /* Extract the next row of content */
         1934  +        pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
         1935  +      }else{
         1936  +        /* When all rows are finished, advance to the next phase */
         1937  +        sqlite3_finalize(pCur->pStmt);
         1938  +        pCur->pStmt = 0;
         1939  +        pCur->ePhase = eNextPhase;
         1940  +        continue;
         1941  +      }
         1942  +    }
         1943  +    if( pCur->nPrefix==0 ) break;
         1944  +    if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){
         1945  +      break;
         1946  +    }
         1947  +  }
         1948  +
         1949  +  return SQLITE_OK;
         1950  +}
         1951  +
         1952  +/*
         1953  +** Return values of columns for the row at which the completion_cursor
         1954  +** is currently pointing.
         1955  +*/
         1956  +static int completionColumn(
         1957  +  sqlite3_vtab_cursor *cur,   /* The cursor */
         1958  +  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
         1959  +  int i                       /* Which column to return */
         1960  +){
         1961  +  completion_cursor *pCur = (completion_cursor*)cur;
         1962  +  switch( i ){
         1963  +    case COMPLETION_COLUMN_CANDIDATE: {
         1964  +      sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT);
         1965  +      break;
         1966  +    }
         1967  +    case COMPLETION_COLUMN_PREFIX: {
         1968  +      sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
         1969  +      break;
         1970  +    }
         1971  +    case COMPLETION_COLUMN_WHOLELINE: {
         1972  +      sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
         1973  +      break;
         1974  +    }
         1975  +    case COMPLETION_COLUMN_PHASE: {
         1976  +      sqlite3_result_int(ctx, pCur->ePhase);
         1977  +      break;
         1978  +    }
         1979  +  }
         1980  +  return SQLITE_OK;
         1981  +}
         1982  +
         1983  +/*
         1984  +** Return the rowid for the current row.  In this implementation, the
         1985  +** rowid is the same as the output value.
         1986  +*/
         1987  +static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
         1988  +  completion_cursor *pCur = (completion_cursor*)cur;
         1989  +  *pRowid = pCur->iRowid;
         1990  +  return SQLITE_OK;
         1991  +}
         1992  +
         1993  +/*
         1994  +** Return TRUE if the cursor has been moved off of the last
         1995  +** row of output.
         1996  +*/
         1997  +static int completionEof(sqlite3_vtab_cursor *cur){
         1998  +  completion_cursor *pCur = (completion_cursor*)cur;
         1999  +  return pCur->ePhase >= COMPLETION_EOF;
         2000  +}
         2001  +
         2002  +/*
         2003  +** This method is called to "rewind" the completion_cursor object back
         2004  +** to the first row of output.  This method is always called at least
         2005  +** once prior to any call to completionColumn() or completionRowid() or 
         2006  +** completionEof().
         2007  +*/
         2008  +static int completionFilter(
         2009  +  sqlite3_vtab_cursor *pVtabCursor, 
         2010  +  int idxNum, const char *idxStr,
         2011  +  int argc, sqlite3_value **argv
         2012  +){
         2013  +  completion_cursor *pCur = (completion_cursor *)pVtabCursor;
         2014  +  int iArg = 0;
         2015  +  (void)(idxStr);   /* Unused parameter */
         2016  +  (void)(argc);     /* Unused parameter */
         2017  +  completionCursorReset(pCur);
         2018  +  if( idxNum & 1 ){
         2019  +    pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
         2020  +    if( pCur->nPrefix>0 ){
         2021  +      pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
         2022  +      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
         2023  +    }
         2024  +    iArg++;
         2025  +  }
         2026  +  if( idxNum & 2 ){
         2027  +    pCur->nLine = sqlite3_value_bytes(argv[iArg]);
         2028  +    if( pCur->nLine>0 ){
         2029  +      pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
         2030  +      if( pCur->zLine==0 ) return SQLITE_NOMEM;
         2031  +    }
         2032  +    iArg++;
         2033  +  }
         2034  +  if( pCur->zLine!=0 && pCur->zPrefix==0 ){
         2035  +    int i = pCur->nLine;
         2036  +    while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
         2037  +      i--;
         2038  +    }
         2039  +    pCur->nPrefix = pCur->nLine - i;
         2040  +    if( pCur->nPrefix>0 ){
         2041  +      pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
         2042  +      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
         2043  +    }
         2044  +  }
         2045  +  pCur->iRowid = 0;
         2046  +  pCur->ePhase = COMPLETION_FIRST_PHASE;
         2047  +  return completionNext(pVtabCursor);
         2048  +}
         2049  +
         2050  +/*
         2051  +** SQLite will invoke this method one or more times while planning a query
         2052  +** that uses the completion virtual table.  This routine needs to create
         2053  +** a query plan for each invocation and compute an estimated cost for that
         2054  +** plan.
         2055  +**
         2056  +** There are two hidden parameters that act as arguments to the table-valued
         2057  +** function:  "prefix" and "wholeline".  Bit 0 of idxNum is set if "prefix"
         2058  +** is available and bit 1 is set if "wholeline" is available.
         2059  +*/
         2060  +static int completionBestIndex(
         2061  +  sqlite3_vtab *tab,
         2062  +  sqlite3_index_info *pIdxInfo
         2063  +){
         2064  +  int i;                 /* Loop over constraints */
         2065  +  int idxNum = 0;        /* The query plan bitmask */
         2066  +  int prefixIdx = -1;    /* Index of the start= constraint, or -1 if none */
         2067  +  int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
         2068  +  int nArg = 0;          /* Number of arguments that completeFilter() expects */
         2069  +  const struct sqlite3_index_constraint *pConstraint;
         2070  +
         2071  +  (void)(tab);    /* Unused parameter */
         2072  +  pConstraint = pIdxInfo->aConstraint;
         2073  +  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
         2074  +    if( pConstraint->usable==0 ) continue;
         2075  +    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
         2076  +    switch( pConstraint->iColumn ){
         2077  +      case COMPLETION_COLUMN_PREFIX:
         2078  +        prefixIdx = i;
         2079  +        idxNum |= 1;
         2080  +        break;
         2081  +      case COMPLETION_COLUMN_WHOLELINE:
         2082  +        wholelineIdx = i;
         2083  +        idxNum |= 2;
         2084  +        break;
         2085  +    }
         2086  +  }
         2087  +  if( prefixIdx>=0 ){
         2088  +    pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
         2089  +    pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
         2090  +  }
         2091  +  if( wholelineIdx>=0 ){
         2092  +    pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
         2093  +    pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
         2094  +  }
         2095  +  pIdxInfo->idxNum = idxNum;
         2096  +  pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
         2097  +  pIdxInfo->estimatedRows = 500 - 100*nArg;
         2098  +  return SQLITE_OK;
         2099  +}
         2100  +
         2101  +/*
         2102  +** This following structure defines all the methods for the 
         2103  +** completion virtual table.
         2104  +*/
         2105  +static sqlite3_module completionModule = {
         2106  +  0,                         /* iVersion */
         2107  +  0,                         /* xCreate */
         2108  +  completionConnect,         /* xConnect */
         2109  +  completionBestIndex,       /* xBestIndex */
         2110  +  completionDisconnect,      /* xDisconnect */
         2111  +  0,                         /* xDestroy */
         2112  +  completionOpen,            /* xOpen - open a cursor */
         2113  +  completionClose,           /* xClose - close a cursor */
         2114  +  completionFilter,          /* xFilter - configure scan constraints */
         2115  +  completionNext,            /* xNext - advance a cursor */
         2116  +  completionEof,             /* xEof - check for end of scan */
         2117  +  completionColumn,          /* xColumn - read data */
         2118  +  completionRowid,           /* xRowid - read data */
         2119  +  0,                         /* xUpdate */
         2120  +  0,                         /* xBegin */
         2121  +  0,                         /* xSync */
         2122  +  0,                         /* xCommit */
         2123  +  0,                         /* xRollback */
         2124  +  0,                         /* xFindMethod */
         2125  +  0,                         /* xRename */
         2126  +  0,                         /* xSavepoint */
         2127  +  0,                         /* xRelease */
         2128  +  0                          /* xRollbackTo */
         2129  +};
         2130  +
         2131  +#endif /* SQLITE_OMIT_VIRTUALTABLE */
         2132  +
         2133  +int sqlite3CompletionVtabInit(sqlite3 *db){
         2134  +  int rc = SQLITE_OK;
         2135  +#ifndef SQLITE_OMIT_VIRTUALTABLE
         2136  +  rc = sqlite3_create_module(db, "completion", &completionModule, 0);
         2137  +#endif
         2138  +  return rc;
         2139  +}
         2140  +
         2141  +#ifdef _WIN32
         2142  +__declspec(dllexport)
         2143  +#endif
         2144  +int sqlite3_completion_init(
         2145  +  sqlite3 *db, 
         2146  +  char **pzErrMsg, 
         2147  +  const sqlite3_api_routines *pApi
         2148  +){
         2149  +  int rc = SQLITE_OK;
         2150  +  SQLITE_EXTENSION_INIT2(pApi);
         2151  +  (void)(pzErrMsg);  /* Unused parameter */
         2152  +#ifndef SQLITE_OMIT_VIRTUALTABLE
         2153  +  rc = sqlite3CompletionVtabInit(db);
         2154  +#endif
         2155  +  return rc;
         2156  +}
         2157  +
         2158  +/************************* End ../ext/misc/completion.c ********************/
  1446   2159   
  1447   2160   #if defined(SQLITE_ENABLE_SESSION)
  1448   2161   /*
  1449   2162   ** State information for a single open session
  1450   2163   */
  1451   2164   typedef struct OpenSession OpenSession;
  1452   2165   struct OpenSession {
................................................................................
  1519   2232   ** These are the allowed shellFlgs values
  1520   2233   */
  1521   2234   #define SHFLG_Scratch        0x00000001 /* The --scratch option is used */
  1522   2235   #define SHFLG_Pagecache      0x00000002 /* The --pagecache option is used */
  1523   2236   #define SHFLG_Lookaside      0x00000004 /* Lookaside memory is used */
  1524   2237   #define SHFLG_Backslash      0x00000008 /* The --backslash option is used */
  1525   2238   #define SHFLG_PreserveRowid  0x00000010 /* .dump preserves rowid values */
  1526         -#define SHFLG_CountChanges   0x00000020 /* .changes setting */
  1527         -#define SHFLG_Echo           0x00000040 /* .echo or --echo setting */
         2239  +#define SHFLG_Newlines       0x00000020 /* .dump --newline flag */
         2240  +#define SHFLG_CountChanges   0x00000040 /* .changes setting */
         2241  +#define SHFLG_Echo           0x00000080 /* .echo or --echo setting */
  1528   2242   
  1529   2243   /*
  1530   2244   ** Macros for testing and setting shellFlgs
  1531   2245   */
  1532   2246   #define ShellHasFlag(P,X)    (((P)->shellFlgs & (X))!=0)
  1533   2247   #define ShellSetFlag(P,X)    ((P)->shellFlgs|=(X))
  1534   2248   #define ShellClearFlag(P,X)  ((P)->shellFlgs&=(~(X)))
................................................................................
  2191   2905         }
  2192   2906         p->cnt++;
  2193   2907         for(i=0; i<nArg; i++){
  2194   2908           raw_printf(p->out, i>0 ? "," : " VALUES(");
  2195   2909           if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
  2196   2910             utf8_printf(p->out,"NULL");
  2197   2911           }else if( aiType && aiType[i]==SQLITE_TEXT ){
  2198         -          output_quoted_escaped_string(p->out, azArg[i]);
         2912  +          if( ShellHasFlag(p, SHFLG_Newlines) ){
         2913  +            output_quoted_string(p->out, azArg[i]);
         2914  +          }else{
         2915  +            output_quoted_escaped_string(p->out, azArg[i]);
         2916  +          }
  2199   2917           }else if( aiType && aiType[i]==SQLITE_INTEGER ){
  2200   2918             utf8_printf(p->out,"%s", azArg[i]);
  2201   2919           }else if( aiType && aiType[i]==SQLITE_FLOAT ){
  2202   2920             char z[50];
  2203   2921             double r = sqlite3_column_double(p->pStmt, i);
  2204   2922             sqlite3_snprintf(50,z,"%!.20g", r);
  2205   2923             raw_printf(p->out, "%s", z);
  2206   2924           }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
  2207   2925             const void *pBlob = sqlite3_column_blob(p->pStmt, i);
  2208   2926             int nBlob = sqlite3_column_bytes(p->pStmt, i);
  2209   2927             output_hex_blob(p->out, pBlob, nBlob);
  2210   2928           }else if( isNumber(azArg[i], 0) ){
  2211   2929             utf8_printf(p->out,"%s", azArg[i]);
         2930  +        }else if( ShellHasFlag(p, SHFLG_Newlines) ){
         2931  +          output_quoted_string(p->out, azArg[i]);
  2212   2932           }else{
  2213   2933             output_quoted_escaped_string(p->out, azArg[i]);
  2214   2934           }
  2215   2935         }
  2216   2936         raw_printf(p->out,");\n");
  2217   2937         break;
  2218   2938       }
................................................................................
  3460   4180       return 0;
  3461   4181     }
  3462   4182     pBuf[nIn] = 0;
  3463   4183     if( pnByte ) *pnByte = nIn;
  3464   4184     return pBuf;
  3465   4185   }
  3466   4186   
  3467         -/*
  3468         -** Implementation of the "readfile(X)" SQL function.  The entire content
  3469         -** of the file named X is read and returned as a BLOB.  NULL is returned
  3470         -** if the file does not exist or is unreadable.
  3471         -*/
  3472         -static void readfileFunc(
  3473         -  sqlite3_context *context,
  3474         -  int argc,
  3475         -  sqlite3_value **argv
  3476         -){
  3477         -  const char *zName;
  3478         -  void *pBuf;
  3479         -  int nBuf;
  3480         -
  3481         -  UNUSED_PARAMETER(argc);
  3482         -  zName = (const char*)sqlite3_value_text(argv[0]);
  3483         -  if( zName==0 ) return;
  3484         -  pBuf = readFile(zName, &nBuf);
  3485         -  if( pBuf ) sqlite3_result_blob(context, pBuf, nBuf, sqlite3_free);
  3486         -}
  3487         -
  3488         -/*
  3489         -** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
  3490         -** is written into file X.  The number of bytes written is returned.  Or
  3491         -** NULL is returned if something goes wrong, such as being unable to open
  3492         -** file X for writing.
  3493         -*/
  3494         -static void writefileFunc(
  3495         -  sqlite3_context *context,
  3496         -  int argc,
  3497         -  sqlite3_value **argv
  3498         -){
  3499         -  FILE *out;
  3500         -  const char *z;
  3501         -  sqlite3_int64 rc;
  3502         -  const char *zFile;
  3503         -
  3504         -  UNUSED_PARAMETER(argc);
  3505         -  zFile = (const char*)sqlite3_value_text(argv[0]);
  3506         -  if( zFile==0 ) return;
  3507         -  out = fopen(zFile, "wb");
  3508         -  if( out==0 ) return;
  3509         -  z = (const char*)sqlite3_value_blob(argv[1]);
  3510         -  if( z==0 ){
  3511         -    rc = 0;
  3512         -  }else{
  3513         -    rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
  3514         -  }
  3515         -  fclose(out);
  3516         -  sqlite3_result_int64(context, rc);
  3517         -}
  3518         -
  3519   4187   #if defined(SQLITE_ENABLE_SESSION)
  3520   4188   /*
  3521   4189   ** Close a single OpenSession object and release all of its associated
  3522   4190   ** resources.
  3523   4191   */
  3524   4192   static void session_close(OpenSession *pSession){
  3525   4193     int i;
................................................................................
  3577   4245             p->zDbFilename, sqlite3_errmsg(p->db));
  3578   4246         if( keepAlive ) return;
  3579   4247         exit(1);
  3580   4248       }
  3581   4249   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  3582   4250       sqlite3_enable_load_extension(p->db, 1);
  3583   4251   #endif
  3584         -    sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
  3585         -                            readfileFunc, 0, 0);
  3586         -    sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
  3587         -                            writefileFunc, 0, 0);
  3588         -    sqlite3_create_function(p->db, "sha3", 1, SQLITE_UTF8, 0,
  3589         -                            sha3Func, 0, 0);
  3590         -    sqlite3_create_function(p->db, "sha3", 2, SQLITE_UTF8, 0,
  3591         -                            sha3Func, 0, 0);
  3592         -    sqlite3_create_function(p->db, "sha3_query", 1, SQLITE_UTF8, 0,
  3593         -                            sha3QueryFunc, 0, 0);
  3594         -    sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0,
  3595         -                            sha3QueryFunc, 0, 0);
         4252  +    sqlite3_fileio_init(p->db, 0, 0);
         4253  +    sqlite3_shathree_init(p->db, 0, 0);
         4254  +    sqlite3_completion_init(p->db, 0, 0);
  3596   4255       sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
  3597   4256                               shellAddSchemaName, 0, 0);
  3598         -                            
  3599   4257     }
  3600   4258   }
         4259  +
         4260  +#if HAVE_READLINE || HAVE_EDITLINE
         4261  +/*
         4262  +** Readline completion callbacks
         4263  +*/
         4264  +static char *readline_completion_generator(const char *text, int state){
         4265  +  static sqlite3_stmt *pStmt = 0;
         4266  +  char *zRet;
         4267  +  if( state==0 ){
         4268  +    char *zSql;
         4269  +    sqlite3_finalize(pStmt);
         4270  +    zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
         4271  +                           "  FROM completion(%Q) ORDER BY 1", text);
         4272  +    sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
         4273  +    sqlite3_free(zSql);
         4274  +  }
         4275  +  if( sqlite3_step(pStmt)==SQLITE_ROW ){
         4276  +    zRet = strdup((const char*)sqlite3_column_text(pStmt, 0));
         4277  +  }else{
         4278  +    sqlite3_finalize(pStmt);
         4279  +    pStmt = 0;
         4280  +    zRet = 0;
         4281  +  }
         4282  +  return zRet;
         4283  +}
         4284  +static char **readline_completion(const char *zText, int iStart, int iEnd){
         4285  +  rl_attempted_completion_over = 1;
         4286  +  return rl_completion_matches(zText, readline_completion_generator);
         4287  +}
         4288  +
         4289  +#elif HAVE_LINENOISE
         4290  +/*
         4291  +** Linenoise completion callback
         4292  +*/
         4293  +static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
         4294  +  int nLine = (int)strlen(zLine);
         4295  +  int i, iStart;
         4296  +  sqlite3_stmt *pStmt = 0;
         4297  +  char *zSql;
         4298  +  char zBuf[1000];
         4299  +
         4300  +  if( nLine>sizeof(zBuf)-30 ) return;
         4301  +  if( zLine[0]=='.' ) return;
         4302  +  for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
         4303  +  if( i==nLine-1 ) return;
         4304  +  iStart = i+1;
         4305  +  memcpy(zBuf, zLine, iStart);
         4306  +  zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
         4307  +                         "  FROM completion(%Q,%Q) ORDER BY 1",
         4308  +                         &zLine[iStart], zLine);
         4309  +  sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
         4310  +  sqlite3_free(zSql);
         4311  +  sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
         4312  +  while( sqlite3_step(pStmt)==SQLITE_ROW ){
         4313  +    const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0);
         4314  +    int nCompletion = sqlite3_column_bytes(pStmt, 0);
         4315  +    if( iStart+nCompletion < sizeof(zBuf)-1 ){
         4316  +      memcpy(zBuf+iStart, zCompletion, nCompletion+1);
         4317  +      linenoiseAddCompletion(lc, zBuf);
         4318  +    }
         4319  +  }
         4320  +  sqlite3_finalize(pStmt);
         4321  +}
         4322  +#endif
  3601   4323   
  3602   4324   /*
  3603   4325   ** Do C-language style dequoting.
  3604   4326   **
  3605   4327   **    \a    -> alarm
  3606   4328   **    \b    -> backspace
  3607   4329   **    \t    -> tab
................................................................................
  4926   5648       rc = shell_dbinfo_command(p, nArg, azArg);
  4927   5649     }else
  4928   5650   
  4929   5651     if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
  4930   5652       const char *zLike = 0;
  4931   5653       int i;
  4932   5654       int savedShowHeader = p->showHeader;
  4933         -    ShellClearFlag(p, SHFLG_PreserveRowid);
         5655  +    ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines);
  4934   5656       for(i=1; i<nArg; i++){
  4935   5657         if( azArg[i][0]=='-' ){
  4936   5658           const char *z = azArg[i]+1;
  4937   5659           if( z[0]=='-' ) z++;
  4938   5660           if( strcmp(z,"preserve-rowids")==0 ){
  4939   5661   #ifdef SQLITE_OMIT_VIRTUALTABLE
  4940   5662             raw_printf(stderr, "The --preserve-rowids option is not compatible"
................................................................................
  4941   5663                                " with SQLITE_OMIT_VIRTUALTABLE\n");
  4942   5664             rc = 1;
  4943   5665             goto meta_command_exit;
  4944   5666   #else
  4945   5667             ShellSetFlag(p, SHFLG_PreserveRowid);
  4946   5668   #endif
  4947   5669           }else
         5670  +        if( strcmp(z,"newlines")==0 ){
         5671  +          ShellSetFlag(p, SHFLG_Newlines);
         5672  +        }else
  4948   5673           {
  4949   5674             raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
  4950   5675             rc = 1;
  4951   5676             goto meta_command_exit;
  4952   5677           }
  4953   5678         }else if( zLike ){
  4954         -        raw_printf(stderr, "Usage: .dump ?--preserve-rowids? ?LIKE-PATTERN?\n");
         5679  +        raw_printf(stderr, "Usage: .dump ?--preserve-rowids? "
         5680  +                           "?--newlines? ?LIKE-PATTERN?\n");
  4955   5681           rc = 1;
  4956   5682           goto meta_command_exit;
  4957   5683         }else{
  4958   5684           zLike = azArg[i];
  4959   5685         }
  4960   5686       }
  4961   5687       open_db(p, 0);
................................................................................
  5825   6551       }else{
  5826   6552         raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
  5827   6553         rc = 1;
  5828   6554         goto meta_command_exit;
  5829   6555       }
  5830   6556       if( zDiv ){
  5831   6557         sqlite3_stmt *pStmt = 0;
  5832         -      sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
  5833         -                         -1, &pStmt, 0);
         6558  +      rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
         6559  +                              -1, &pStmt, 0);
         6560  +      if( rc ){
         6561  +        utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
         6562  +        sqlite3_finalize(pStmt);
         6563  +        rc = 1;
         6564  +        goto meta_command_exit;
         6565  +      }
  5834   6566         appendText(&sSelect, "SELECT sql FROM", 0);
  5835   6567         iSchema = 0;
  5836   6568         while( sqlite3_step(pStmt)==SQLITE_ROW ){
  5837   6569           const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
  5838   6570           char zScNum[30];
  5839   6571           sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
  5840   6572           appendText(&sSelect, zDiv, 0);
................................................................................
  7632   8364         if( zHome ){
  7633   8365           nHistory = strlen30(zHome) + 20;
  7634   8366           if( (zHistory = malloc(nHistory))!=0 ){
  7635   8367             sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
  7636   8368           }
  7637   8369         }
  7638   8370         if( zHistory ){ shell_read_history(zHistory); }
         8371  +#if HAVE_READLINE || HAVE_EDITLINE
         8372  +      rl_attempted_completion_function = readline_completion;
         8373  +#elif HAVE_LINENOISE
         8374  +      linenoiseSetCompletionCallback(linenoise_completion);
         8375  +#endif
  7639   8376         rc = process_input(&data, 0);
  7640   8377         if( zHistory ){
  7641         -        shell_stifle_history(100);
         8378  +        shell_stifle_history(2000);
  7642   8379           shell_write_history(zHistory);
  7643   8380           free(zHistory);
  7644   8381         }
  7645   8382       }else{
  7646   8383         rc = process_input(&data, stdin);
  7647   8384       }
  7648   8385     }
................................................................................
  7655   8392     find_home_dir(1);
  7656   8393   #if !SQLITE_SHELL_IS_UTF8
  7657   8394     for(i=0; i<argc; i++) sqlite3_free(argv[i]);
  7658   8395     sqlite3_free(argv);
  7659   8396   #endif
  7660   8397     return rc;
  7661   8398   }
         8399  +

Added src/shell.c.in.

            1  +/*
            2  +** 2001 September 15
            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  +** This file contains code to implement the "sqlite" command line
           13  +** utility for accessing SQLite databases.
           14  +*/
           15  +#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
           16  +/* This needs to come before any includes for MSVC compiler */
           17  +#define _CRT_SECURE_NO_WARNINGS
           18  +#endif
           19  +
           20  +/*
           21  +** Warning pragmas copied from msvc.h in the core.
           22  +*/
           23  +#if defined(_MSC_VER)
           24  +#pragma warning(disable : 4054)
           25  +#pragma warning(disable : 4055)
           26  +#pragma warning(disable : 4100)
           27  +#pragma warning(disable : 4127)
           28  +#pragma warning(disable : 4130)
           29  +#pragma warning(disable : 4152)
           30  +#pragma warning(disable : 4189)
           31  +#pragma warning(disable : 4206)
           32  +#pragma warning(disable : 4210)
           33  +#pragma warning(disable : 4232)
           34  +#pragma warning(disable : 4244)
           35  +#pragma warning(disable : 4305)
           36  +#pragma warning(disable : 4306)
           37  +#pragma warning(disable : 4702)
           38  +#pragma warning(disable : 4706)
           39  +#endif /* defined(_MSC_VER) */
           40  +
           41  +/*
           42  +** No support for loadable extensions in VxWorks.
           43  +*/
           44  +#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
           45  +# define SQLITE_OMIT_LOAD_EXTENSION 1
           46  +#endif
           47  +
           48  +/*
           49  +** Enable large-file support for fopen() and friends on unix.
           50  +*/
           51  +#ifndef SQLITE_DISABLE_LFS
           52  +# define _LARGE_FILE       1
           53  +# ifndef _FILE_OFFSET_BITS
           54  +#   define _FILE_OFFSET_BITS 64
           55  +# endif
           56  +# define _LARGEFILE_SOURCE 1
           57  +#endif
           58  +
           59  +#include <stdlib.h>
           60  +#include <string.h>
           61  +#include <stdio.h>
           62  +#include <assert.h>
           63  +#include "sqlite3.h"
           64  +#if SQLITE_USER_AUTHENTICATION
           65  +# include "sqlite3userauth.h"
           66  +#endif
           67  +#include <ctype.h>
           68  +#include <stdarg.h>
           69  +
           70  +#if !defined(_WIN32) && !defined(WIN32)
           71  +# include <signal.h>
           72  +# if !defined(__RTP__) && !defined(_WRS_KERNEL)
           73  +#  include <pwd.h>
           74  +# endif
           75  +# include <unistd.h>
           76  +# include <sys/types.h>
           77  +#endif
           78  +
           79  +#if HAVE_READLINE
           80  +# include <readline/readline.h>
           81  +# include <readline/history.h>
           82  +#endif
           83  +
           84  +#if HAVE_EDITLINE
           85  +# include <editline/readline.h>
           86  +#endif
           87  +
           88  +#if HAVE_EDITLINE || HAVE_READLINE
           89  +
           90  +# define shell_add_history(X) add_history(X)
           91  +# define shell_read_history(X) read_history(X)
           92  +# define shell_write_history(X) write_history(X)
           93  +# define shell_stifle_history(X) stifle_history(X)
           94  +# define shell_readline(X) readline(X)
           95  +
           96  +#elif HAVE_LINENOISE
           97  +
           98  +# include "linenoise.h"
           99  +# define shell_add_history(X) linenoiseHistoryAdd(X)
          100  +# define shell_read_history(X) linenoiseHistoryLoad(X)
          101  +# define shell_write_history(X) linenoiseHistorySave(X)
          102  +# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
          103  +# define shell_readline(X) linenoise(X)
          104  +
          105  +#else
          106  +
          107  +# define shell_read_history(X)
          108  +# define shell_write_history(X)
          109  +# define shell_stifle_history(X)
          110  +
          111  +# define SHELL_USE_LOCAL_GETLINE 1
          112  +#endif
          113  +
          114  +
          115  +#if defined(_WIN32) || defined(WIN32)
          116  +# include <io.h>
          117  +# include <fcntl.h>
          118  +# define isatty(h) _isatty(h)
          119  +# ifndef access
          120  +#  define access(f,m) _access((f),(m))
          121  +# endif
          122  +# undef popen
          123  +# define popen _popen
          124  +# undef pclose
          125  +# define pclose _pclose
          126  +#else
          127  + /* Make sure isatty() has a prototype. */
          128  + extern int isatty(int);
          129  +
          130  +# if !defined(__RTP__) && !defined(_WRS_KERNEL)
          131  +  /* popen and pclose are not C89 functions and so are
          132  +  ** sometimes omitted from the <stdio.h> header */
          133  +   extern FILE *popen(const char*,const char*);
          134  +   extern int pclose(FILE*);
          135  +# else
          136  +#  define SQLITE_OMIT_POPEN 1
          137  +# endif
          138  +#endif
          139  +
          140  +#if defined(_WIN32_WCE)
          141  +/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
          142  + * thus we always assume that we have a console. That can be
          143  + * overridden with the -batch command line option.
          144  + */
          145  +#define isatty(x) 1
          146  +#endif
          147  +
          148  +/* ctype macros that work with signed characters */
          149  +#define IsSpace(X)  isspace((unsigned char)X)
          150  +#define IsDigit(X)  isdigit((unsigned char)X)
          151  +#define ToLower(X)  (char)tolower((unsigned char)X)
          152  +
          153  +#if defined(_WIN32) || defined(WIN32)
          154  +#include <windows.h>
          155  +
          156  +/* string conversion routines only needed on Win32 */
          157  +extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
          158  +extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
          159  +extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
          160  +extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
          161  +#endif
          162  +
          163  +/* On Windows, we normally run with output mode of TEXT so that \n characters
          164  +** are automatically translated into \r\n.  However, this behavior needs
          165  +** to be disabled in some cases (ex: when generating CSV output and when
          166  +** rendering quoted strings that contain \n characters).  The following
          167  +** routines take care of that.
          168  +*/
          169  +#if defined(_WIN32) || defined(WIN32)
          170  +static void setBinaryMode(FILE *file, int isOutput){
          171  +  if( isOutput ) fflush(file);
          172  +  _setmode(_fileno(file), _O_BINARY);
          173  +}
          174  +static void setTextMode(FILE *file, int isOutput){
          175  +  if( isOutput ) fflush(file);
          176  +  _setmode(_fileno(file), _O_TEXT);
          177  +}
          178  +#else
          179  +# define setBinaryMode(X,Y)
          180  +# define setTextMode(X,Y)
          181  +#endif
          182  +
          183  +
          184  +/* True if the timer is enabled */
          185  +static int enableTimer = 0;
          186  +
          187  +/* Return the current wall-clock time */
          188  +static sqlite3_int64 timeOfDay(void){
          189  +  static sqlite3_vfs *clockVfs = 0;
          190  +  sqlite3_int64 t;
          191  +  if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
          192  +  if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
          193  +    clockVfs->xCurrentTimeInt64(clockVfs, &t);
          194  +  }else{
          195  +    double r;
          196  +    clockVfs->xCurrentTime(clockVfs, &r);
          197  +    t = (sqlite3_int64)(r*86400000.0);
          198  +  }
          199  +  return t;
          200  +}
          201  +
          202  +#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
          203  +#include <sys/time.h>
          204  +#include <sys/resource.h>
          205  +
          206  +/* VxWorks does not support getrusage() as far as we can determine */
          207  +#if defined(_WRS_KERNEL) || defined(__RTP__)
          208  +struct rusage {
          209  +  struct timeval ru_utime; /* user CPU time used */
          210  +  struct timeval ru_stime; /* system CPU time used */
          211  +};
          212  +#define getrusage(A,B) memset(B,0,sizeof(*B))
          213  +#endif
          214  +
          215  +/* Saved resource information for the beginning of an operation */
          216  +static struct rusage sBegin;  /* CPU time at start */
          217  +static sqlite3_int64 iBegin;  /* Wall-clock time at start */
          218  +
          219  +/*
          220  +** Begin timing an operation
          221  +*/
          222  +static void beginTimer(void){
          223  +  if( enableTimer ){
          224  +    getrusage(RUSAGE_SELF, &sBegin);
          225  +    iBegin = timeOfDay();
          226  +  }
          227  +}
          228  +
          229  +/* Return the difference of two time_structs in seconds */
          230  +static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
          231  +  return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
          232  +         (double)(pEnd->tv_sec - pStart->tv_sec);
          233  +}
          234  +
          235  +/*
          236  +** Print the timing results.
          237  +*/
          238  +static void endTimer(void){
          239  +  if( enableTimer ){
          240  +    sqlite3_int64 iEnd = timeOfDay();
          241  +    struct rusage sEnd;
          242  +    getrusage(RUSAGE_SELF, &sEnd);
          243  +    printf("Run Time: real %.3f user %f sys %f\n",
          244  +       (iEnd - iBegin)*0.001,
          245  +       timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
          246  +       timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
          247  +  }
          248  +}
          249  +
          250  +#define BEGIN_TIMER beginTimer()
          251  +#define END_TIMER endTimer()
          252  +#define HAS_TIMER 1
          253  +
          254  +#elif (defined(_WIN32) || defined(WIN32))
          255  +
          256  +/* Saved resource information for the beginning of an operation */
          257  +static HANDLE hProcess;
          258  +static FILETIME ftKernelBegin;
          259  +static FILETIME ftUserBegin;
          260  +static sqlite3_int64 ftWallBegin;
          261  +typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
          262  +                                    LPFILETIME, LPFILETIME);
          263  +static GETPROCTIMES getProcessTimesAddr = NULL;
          264  +
          265  +/*
          266  +** Check to see if we have timer support.  Return 1 if necessary
          267  +** support found (or found previously).
          268  +*/
          269  +static int hasTimer(void){
          270  +  if( getProcessTimesAddr ){
          271  +    return 1;
          272  +  } else {
          273  +    /* GetProcessTimes() isn't supported in WIN95 and some other Windows
          274  +    ** versions. See if the version we are running on has it, and if it
          275  +    ** does, save off a pointer to it and the current process handle.
          276  +    */
          277  +    hProcess = GetCurrentProcess();
          278  +    if( hProcess ){
          279  +      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
          280  +      if( NULL != hinstLib ){
          281  +        getProcessTimesAddr =
          282  +            (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
          283  +        if( NULL != getProcessTimesAddr ){
          284  +          return 1;
          285  +        }
          286  +        FreeLibrary(hinstLib);
          287  +      }
          288  +    }
          289  +  }
          290  +  return 0;
          291  +}
          292  +
          293  +/*
          294  +** Begin timing an operation
          295  +*/
          296  +static void beginTimer(void){
          297  +  if( enableTimer && getProcessTimesAddr ){
          298  +    FILETIME ftCreation, ftExit;
          299  +    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
          300  +                        &ftKernelBegin,&ftUserBegin);
          301  +    ftWallBegin = timeOfDay();
          302  +  }
          303  +}
          304  +
          305  +/* Return the difference of two FILETIME structs in seconds */
          306  +static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
          307  +  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
          308  +  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
          309  +  return (double) ((i64End - i64Start) / 10000000.0);
          310  +}
          311  +
          312  +/*
          313  +** Print the timing results.
          314  +*/
          315  +static void endTimer(void){
          316  +  if( enableTimer && getProcessTimesAddr){
          317  +    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
          318  +    sqlite3_int64 ftWallEnd = timeOfDay();
          319  +    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
          320  +    printf("Run Time: real %.3f user %f sys %f\n",
          321  +       (ftWallEnd - ftWallBegin)*0.001,
          322  +       timeDiff(&ftUserBegin, &ftUserEnd),
          323  +       timeDiff(&ftKernelBegin, &ftKernelEnd));
          324  +  }
          325  +}
          326  +
          327  +#define BEGIN_TIMER beginTimer()
          328  +#define END_TIMER endTimer()
          329  +#define HAS_TIMER hasTimer()
          330  +
          331  +#else
          332  +#define BEGIN_TIMER
          333  +#define END_TIMER
          334  +#define HAS_TIMER 0
          335  +#endif
          336  +
          337  +/*
          338  +** Used to prevent warnings about unused parameters
          339  +*/
          340  +#define UNUSED_PARAMETER(x) (void)(x)
          341  +
          342  +/*
          343  +** If the following flag is set, then command execution stops
          344  +** at an error if we are not interactive.
          345  +*/
          346  +static int bail_on_error = 0;
          347  +
          348  +/*
          349  +** Threat stdin as an interactive input if the following variable
          350  +** is true.  Otherwise, assume stdin is connected to a file or pipe.
          351  +*/
          352  +static int stdin_is_interactive = 1;
          353  +
          354  +/*
          355  +** On Windows systems we have to know if standard output is a console
          356  +** in order to translate UTF-8 into MBCS.  The following variable is
          357  +** true if translation is required.
          358  +*/
          359  +static int stdout_is_console = 1;
          360  +
          361  +/*
          362  +** The following is the open SQLite database.  We make a pointer
          363  +** to this database a static variable so that it can be accessed
          364  +** by the SIGINT handler to interrupt database processing.
          365  +*/
          366  +static sqlite3 *globalDb = 0;
          367  +
          368  +/*
          369  +** True if an interrupt (Control-C) has been received.
          370  +*/
          371  +static volatile int seenInterrupt = 0;
          372  +
          373  +/*
          374  +** This is the name of our program. It is set in main(), used
          375  +** in a number of other places, mostly for error messages.
          376  +*/
          377  +static char *Argv0;
          378  +
          379  +/*
          380  +** Prompt strings. Initialized in main. Settable with
          381  +**   .prompt main continue
          382  +*/
          383  +static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
          384  +static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
          385  +
          386  +/*
          387  +** Render output like fprintf().  Except, if the output is going to the
          388  +** console and if this is running on a Windows machine, translate the
          389  +** output from UTF-8 into MBCS.
          390  +*/
          391  +#if defined(_WIN32) || defined(WIN32)
          392  +void utf8_printf(FILE *out, const char *zFormat, ...){
          393  +  va_list ap;
          394  +  va_start(ap, zFormat);
          395  +  if( stdout_is_console && (out==stdout || out==stderr) ){
          396  +    char *z1 = sqlite3_vmprintf(zFormat, ap);
          397  +    char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
          398  +    sqlite3_free(z1);
          399  +    fputs(z2, out);
          400  +    sqlite3_free(z2);
          401  +  }else{
          402  +    vfprintf(out, zFormat, ap);
          403  +  }
          404  +  va_end(ap);
          405  +}
          406  +#elif !defined(utf8_printf)
          407  +# define utf8_printf fprintf
          408  +#endif
          409  +
          410  +/*
          411  +** Render output like fprintf().  This should not be used on anything that
          412  +** includes string formatting (e.g. "%s").
          413  +*/
          414  +#if !defined(raw_printf)
          415  +# define raw_printf fprintf
          416  +#endif
          417  +
          418  +/*
          419  +** Write I/O traces to the following stream.
          420  +*/
          421  +#ifdef SQLITE_ENABLE_IOTRACE
          422  +static FILE *iotrace = 0;
          423  +#endif
          424  +
          425  +/*
          426  +** This routine works like printf in that its first argument is a
          427  +** format string and subsequent arguments are values to be substituted
          428  +** in place of % fields.  The result of formatting this string
          429  +** is written to iotrace.
          430  +*/
          431  +#ifdef SQLITE_ENABLE_IOTRACE
          432  +static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
          433  +  va_list ap;
          434  +  char *z;
          435  +  if( iotrace==0 ) return;
          436  +  va_start(ap, zFormat);
          437  +  z = sqlite3_vmprintf(zFormat, ap);
          438  +  va_end(ap);
          439  +  utf8_printf(iotrace, "%s", z);
          440  +  sqlite3_free(z);
          441  +}
          442  +#endif
          443  +
          444  +/*
          445  +** Output string zUtf to stream pOut as w characters.  If w is negative,
          446  +** then right-justify the text.  W is the width in UTF-8 characters, not
          447  +** in bytes.  This is different from the %*.*s specification in printf
          448  +** since with %*.*s the width is measured in bytes, not characters.
          449  +*/
          450  +static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
          451  +  int i;
          452  +  int n;
          453  +  int aw = w<0 ? -w : w;
          454  +  char zBuf[1000];
          455  +  if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
          456  +  for(i=n=0; zUtf[i]; i++){
          457  +    if( (zUtf[i]&0xc0)!=0x80 ){
          458  +      n++;
          459  +      if( n==aw ){
          460  +        do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
          461  +        break;
          462  +      }
          463  +    }
          464  +  }
          465  +  if( n>=aw ){
          466  +    utf8_printf(pOut, "%.*s", i, zUtf);
          467  +  }else if( w<0 ){
          468  +    utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
          469  +  }else{
          470  +    utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
          471  +  }
          472  +}
          473  +
          474  +
          475  +/*
          476  +** Determines if a string is a number of not.
          477  +*/
          478  +static int isNumber(const char *z, int *realnum){
          479  +  if( *z=='-' || *z=='+' ) z++;
          480  +  if( !IsDigit(*z) ){
          481  +    return 0;
          482  +  }
          483  +  z++;
          484  +  if( realnum ) *realnum = 0;
          485  +  while( IsDigit(*z) ){ z++; }
          486  +  if( *z=='.' ){
          487  +    z++;
          488  +    if( !IsDigit(*z) ) return 0;
          489  +    while( IsDigit(*z) ){ z++; }
          490  +    if( realnum ) *realnum = 1;
          491  +  }
          492  +  if( *z=='e' || *z=='E' ){
          493  +    z++;
          494  +    if( *z=='+' || *z=='-' ) z++;
          495  +    if( !IsDigit(*z) ) return 0;
          496  +    while( IsDigit(*z) ){ z++; }
          497  +    if( realnum ) *realnum = 1;
          498  +  }
          499  +  return *z==0;
          500  +}
          501  +
          502  +/*
          503  +** Compute a string length that is limited to what can be stored in
          504  +** lower 30 bits of a 32-bit signed integer.
          505  +*/
          506  +static int strlen30(const char *z){
          507  +  const char *z2 = z;
          508  +  while( *z2 ){ z2++; }
          509  +  return 0x3fffffff & (int)(z2 - z);
          510  +}
          511  +
          512  +/*
          513  +** Return the length of a string in characters.  Multibyte UTF8 characters
          514  +** count as a single character.
          515  +*/
          516  +static int strlenChar(const char *z){
          517  +  int n = 0;
          518  +  while( *z ){
          519  +    if( (0xc0&*(z++))!=0x80 ) n++;
          520  +  }
          521  +  return n;
          522  +}
          523  +
          524  +/*
          525  +** This routine reads a line of text from FILE in, stores
          526  +** the text in memory obtained from malloc() and returns a pointer
          527  +** to the text.  NULL is returned at end of file, or if malloc()
          528  +** fails.
          529  +**
          530  +** If zLine is not NULL then it is a malloced buffer returned from
          531  +** a previous call to this routine that may be reused.
          532  +*/
          533  +static char *local_getline(char *zLine, FILE *in){
          534  +  int nLine = zLine==0 ? 0 : 100;
          535  +  int n = 0;
          536  +
          537  +  while( 1 ){
          538  +    if( n+100>nLine ){
          539  +      nLine = nLine*2 + 100;
          540  +      zLine = realloc(zLine, nLine);
          541  +      if( zLine==0 ) return 0;
          542  +    }
          543  +    if( fgets(&zLine[n], nLine - n, in)==0 ){
          544  +      if( n==0 ){
          545  +        free(zLine);
          546  +        return 0;
          547  +      }
          548  +      zLine[n] = 0;
          549  +      break;
          550  +    }
          551  +    while( zLine[n] ) n++;
          552  +    if( n>0 && zLine[n-1]=='\n' ){
          553  +      n--;
          554  +      if( n>0 && zLine[n-1]=='\r' ) n--;
          555  +      zLine[n] = 0;
          556  +      break;
          557  +    }
          558  +  }
          559  +#if defined(_WIN32) || defined(WIN32)
          560  +  /* For interactive input on Windows systems, translate the
          561  +  ** multi-byte characterset characters into UTF-8. */
          562  +  if( stdin_is_interactive && in==stdin ){
          563  +    char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
          564  +    if( zTrans ){
          565  +      int nTrans = strlen30(zTrans)+1;
          566  +      if( nTrans>nLine ){
          567  +        zLine = realloc(zLine, nTrans);
          568  +        if( zLine==0 ){
          569  +          sqlite3_free(zTrans);
          570  +          return 0;
          571  +        }
          572  +      }
          573  +      memcpy(zLine, zTrans, nTrans);
          574  +      sqlite3_free(zTrans);
          575  +    }
          576  +  }
          577  +#endif /* defined(_WIN32) || defined(WIN32) */
          578  +  return zLine;
          579  +}
          580  +
          581  +/*
          582  +** Retrieve a single line of input text.
          583  +**
          584  +** If in==0 then read from standard input and prompt before each line.
          585  +** If isContinuation is true, then a continuation prompt is appropriate.
          586  +** If isContinuation is zero, then the main prompt should be used.
          587  +**
          588  +** If zPrior is not NULL then it is a buffer from a prior call to this
          589  +** routine that can be reused.
          590  +**
          591  +** The result is stored in space obtained from malloc() and must either
          592  +** be freed by the caller or else passed back into this routine via the
          593  +** zPrior argument for reuse.
          594  +*/
          595  +static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
          596  +  char *zPrompt;
          597  +  char *zResult;
          598  +  if( in!=0 ){
          599  +    zResult = local_getline(zPrior, in);
          600  +  }else{
          601  +    zPrompt = isContinuation ? continuePrompt : mainPrompt;
          602  +#if SHELL_USE_LOCAL_GETLINE
          603  +    printf("%s", zPrompt);
          604  +    fflush(stdout);
          605  +    zResult = local_getline(zPrior, stdin);
          606  +#else
          607  +    free(zPrior);
          608  +    zResult = shell_readline(zPrompt);
          609  +    if( zResult && *zResult ) shell_add_history(zResult);
          610  +#endif
          611  +  }
          612  +  return zResult;
          613  +}
          614  +/*
          615  +** A variable length string to which one can append text.
          616  +*/
          617  +typedef struct ShellText ShellText;
          618  +struct ShellText {
          619  +  char *z;
          620  +  int n;
          621  +  int nAlloc;
          622  +};
          623  +
          624  +/*
          625  +** Initialize and destroy a ShellText object
          626  +*/
          627  +static void initText(ShellText *p){
          628  +  memset(p, 0, sizeof(*p));
          629  +}
          630  +static void freeText(ShellText *p){
          631  +  free(p->z);
          632  +  initText(p);
          633  +}
          634  +
          635  +/* zIn is either a pointer to a NULL-terminated string in memory obtained
          636  +** from malloc(), or a NULL pointer. The string pointed to by zAppend is
          637  +** added to zIn, and the result returned in memory obtained from malloc().
          638  +** zIn, if it was not NULL, is freed.
          639  +**
          640  +** If the third argument, quote, is not '\0', then it is used as a
          641  +** quote character for zAppend.
          642  +*/
          643  +static void appendText(ShellText *p, char const *zAppend, char quote){
          644  +  int len;
          645  +  int i;
          646  +  int nAppend = strlen30(zAppend);
          647  +
          648  +  len = nAppend+p->n+1;
          649  +  if( quote ){
          650  +    len += 2;
          651  +    for(i=0; i<nAppend; i++){
          652  +      if( zAppend[i]==quote ) len++;
          653  +    }
          654  +  }
          655  +
          656  +  if( p->n+len>=p->nAlloc ){
          657  +    p->nAlloc = p->nAlloc*2 + len + 20;
          658  +    p->z = realloc(p->z, p->nAlloc);
          659  +    if( p->z==0 ){
          660  +      memset(p, 0, sizeof(*p));
          661  +      return;
          662  +    }
          663  +  }
          664  +
          665  +  if( quote ){
          666  +    char *zCsr = p->z+p->n;
          667  +    *zCsr++ = quote;
          668  +    for(i=0; i<nAppend; i++){
          669  +      *zCsr++ = zAppend[i];
          670  +      if( zAppend[i]==quote ) *zCsr++ = quote;
          671  +    }
          672  +    *zCsr++ = quote;
          673  +    p->n = (int)(zCsr - p->z);
          674  +    *zCsr = '\0';
          675  +  }else{
          676  +    memcpy(p->z+p->n, zAppend, nAppend);
          677  +    p->n += nAppend;
          678  +    p->z[p->n] = '\0';
          679  +  }
          680  +}
          681  +
          682  +/*
          683  +** Attempt to determine if identifier zName needs to be quoted, either
          684  +** because it contains non-alphanumeric characters, or because it is an
          685  +** SQLite keyword.  Be conservative in this estimate:  When in doubt assume
          686  +** that quoting is required.
          687  +**
          688  +** Return '"' if quoting is required.  Return 0 if no quoting is required.
          689  +*/
          690  +static char quoteChar(const char *zName){
          691  +  /* All SQLite keywords, in alphabetical order */
          692  +  static const char *azKeywords[] = {
          693  +    "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
          694  +    "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
          695  +    "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
          696  +    "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
          697  +    "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
          698  +    "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
          699  +    "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
          700  +    "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
          701  +    "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
          702  +    "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
          703  +    "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
          704  +    "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
          705  +    "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
          706  +    "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
          707  +    "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
          708  +    "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
          709  +    "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
          710  +    "WITH", "WITHOUT",
          711  +  };
          712  +  int i, lwr, upr, mid, c;
          713  +  if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
          714  +  for(i=0; zName[i]; i++){
          715  +    if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
          716  +  }
          717  +  lwr = 0;
          718  +  upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
          719  +  while( lwr<=upr ){
          720  +    mid = (lwr+upr)/2;
          721  +    c = sqlite3_stricmp(azKeywords[mid], zName);
          722  +    if( c==0 ) return '"';
          723  +    if( c<0 ){
          724  +      lwr = mid+1;
          725  +    }else{
          726  +      upr = mid-1;
          727  +    }
          728  +  }
          729  +  return 0;
          730  +}
          731  +
          732  +/*
          733  +** SQL function:  shell_add_schema(S,X)
          734  +**
          735  +** Add the schema name X to the CREATE statement in S and return the result.
          736  +** Examples:
          737  +**
          738  +**    CREATE TABLE t1(x)   ->   CREATE TABLE xyz.t1(x);
          739  +**
          740  +** Also works on
          741  +**
          742  +**    CREATE INDEX
          743  +**    CREATE UNIQUE INDEX
          744  +**    CREATE VIEW
          745  +**    CREATE TRIGGER
          746  +**    CREATE VIRTUAL TABLE
          747  +**
          748  +** This UDF is used by the .schema command to insert the schema name of
          749  +** attached databases into the middle of the sqlite_master.sql field.
          750  +*/
          751  +static void shellAddSchemaName(
          752  +  sqlite3_context *pCtx,
          753  +  int nVal,
          754  +  sqlite3_value **apVal
          755  +){
          756  +  static const char *aPrefix[] = {
          757  +     "TABLE",
          758  +     "INDEX",
          759  +     "UNIQUE INDEX",
          760  +     "VIEW",
          761  +     "TRIGGER",
          762  +     "VIRTUAL TABLE"
          763  +  };
          764  +  int i = 0;
          765  +  const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
          766  +  const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
          767  +  assert( nVal==2 );
          768  +  if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
          769  +    for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
          770  +      int n = strlen30(aPrefix[i]);
          771  +      if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
          772  +        char cQuote = quoteChar(zSchema);
          773  +        char *z;
          774  +        if( cQuote ){
          775  +         z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
          776  +        }else{
          777  +          z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
          778  +        }
          779  +        sqlite3_result_text(pCtx, z, -1, sqlite3_free);
          780  +        return;
          781  +      }
          782  +    }
          783  +  }
          784  +  sqlite3_result_value(pCtx, apVal[0]);
          785  +}
          786  +
          787  +/*
          788  +** The source code for several run-time loadable extensions is inserted
          789  +** below by the ../tool/mkshellc.tcl script.  Before processing that included
          790  +** code, we need to override some macros to make the included program code
          791  +** work here in the middle of this regular program.
          792  +*/
          793  +#define SQLITE_EXTENSION_INIT1
          794  +#define SQLITE_EXTENSION_INIT2(X) (void)(X)
          795  +
          796  +INCLUDE ../ext/misc/shathree.c
          797  +INCLUDE ../ext/misc/fileio.c
          798  +INCLUDE ../ext/misc/completion.c
          799  +
          800  +#if defined(SQLITE_ENABLE_SESSION)
          801  +/*
          802  +** State information for a single open session
          803  +*/
          804  +typedef struct OpenSession OpenSession;
          805  +struct OpenSession {
          806  +  char *zName;             /* Symbolic name for this session */
          807  +  int nFilter;             /* Number of xFilter rejection GLOB patterns */
          808  +  char **azFilter;         /* Array of xFilter rejection GLOB patterns */
          809  +  sqlite3_session *p;      /* The open session */
          810  +};
          811  +#endif
          812  +
          813  +/*
          814  +** Shell output mode information from before ".explain on",
          815  +** saved so that it can be restored by ".explain off"
          816  +*/
          817  +typedef struct SavedModeInfo SavedModeInfo;
          818  +struct SavedModeInfo {
          819  +  int valid;          /* Is there legit data in here? */
          820  +  int mode;           /* Mode prior to ".explain on" */
          821  +  int showHeader;     /* The ".header" setting prior to ".explain on" */
          822  +  int colWidth[100];  /* Column widths prior to ".explain on" */
          823  +};
          824  +
          825  +/*
          826  +** State information about the database connection is contained in an
          827  +** instance of the following structure.
          828  +*/
          829  +typedef struct ShellState ShellState;
          830  +struct ShellState {
          831  +  sqlite3 *db;           /* The database */
          832  +  int autoExplain;       /* Automatically turn on .explain mode */
          833  +  int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
          834  +  int statsOn;           /* True to display memory stats before each finalize */
          835  +  int scanstatsOn;       /* True to display scan stats before each finalize */
          836  +  int outCount;          /* Revert to stdout when reaching zero */
          837  +  int cnt;               /* Number of records displayed so far */
          838  +  FILE *out;             /* Write results here */
          839  +  FILE *traceOut;        /* Output for sqlite3_trace() */
          840  +  int nErr;              /* Number of errors seen */
          841  +  int mode;              /* An output mode setting */
          842  +  int cMode;             /* temporary output mode for the current query */
          843  +  int normalMode;        /* Output mode before ".explain on" */
          844  +  int writableSchema;    /* True if PRAGMA writable_schema=ON */
          845  +  int showHeader;        /* True to show column names in List or Column mode */
          846  +  int nCheck;            /* Number of ".check" commands run */
          847  +  unsigned shellFlgs;    /* Various flags */
          848  +  char *zDestTable;      /* Name of destination table when MODE_Insert */
          849  +  char zTestcase[30];    /* Name of current test case */
          850  +  char colSeparator[20]; /* Column separator character for several modes */
          851  +  char rowSeparator[20]; /* Row separator character for MODE_Ascii */
          852  +  int colWidth[100];     /* Requested width of each column when in column mode*/
          853  +  int actualWidth[100];  /* Actual width of each column */
          854  +  char nullValue[20];    /* The text to print when a NULL comes back from
          855  +                         ** the database */
          856  +  char outfile[FILENAME_MAX]; /* Filename for *out */
          857  +  const char *zDbFilename;    /* name of the database file */
          858  +  char *zFreeOnClose;         /* Filename to free when closing */
          859  +  const char *zVfs;           /* Name of VFS to use */
          860  +  sqlite3_stmt *pStmt;   /* Current statement if any. */
          861  +  FILE *pLog;            /* Write log output here */
          862  +  int *aiIndent;         /* Array of indents used in MODE_Explain */
          863  +  int nIndent;           /* Size of array aiIndent[] */
          864  +  int iIndent;           /* Index of current op in aiIndent[] */
          865  +#if defined(SQLITE_ENABLE_SESSION)
          866  +  int nSession;             /* Number of active sessions */
          867  +  OpenSession aSession[4];  /* Array of sessions.  [0] is in focus. */
          868  +#endif
          869  +};
          870  +
          871  +/*
          872  +** These are the allowed shellFlgs values
          873  +*/
          874  +#define SHFLG_Scratch        0x00000001 /* The --scratch option is used */
          875  +#define SHFLG_Pagecache      0x00000002 /* The --pagecache option is used */
          876  +#define SHFLG_Lookaside      0x00000004 /* Lookaside memory is used */
          877  +#define SHFLG_Backslash      0x00000008 /* The --backslash option is used */
          878  +#define SHFLG_PreserveRowid  0x00000010 /* .dump preserves rowid values */
          879  +#define SHFLG_Newlines       0x00000020 /* .dump --newline flag */
          880  +#define SHFLG_CountChanges   0x00000040 /* .changes setting */
          881  +#define SHFLG_Echo           0x00000080 /* .echo or --echo setting */
          882  +
          883  +/*
          884  +** Macros for testing and setting shellFlgs
          885  +*/
          886  +#define ShellHasFlag(P,X)    (((P)->shellFlgs & (X))!=0)
          887  +#define ShellSetFlag(P,X)    ((P)->shellFlgs|=(X))
          888  +#define ShellClearFlag(P,X)  ((P)->shellFlgs&=(~(X)))
          889  +
          890  +/*
          891  +** These are the allowed modes.
          892  +*/
          893  +#define MODE_Line     0  /* One column per line.  Blank line between records */
          894  +#define MODE_Column   1  /* One record per line in neat columns */
          895  +#define MODE_List     2  /* One record per line with a separator */
          896  +#define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
          897  +#define MODE_Html     4  /* Generate an XHTML table */
          898  +#define MODE_Insert   5  /* Generate SQL "insert" statements */
          899  +#define MODE_Quote    6  /* Quote values as for SQL */
          900  +#define MODE_Tcl      7  /* Generate ANSI-C or TCL quoted elements */
          901  +#define MODE_Csv      8  /* Quote strings, numbers are plain */
          902  +#define MODE_Explain  9  /* Like MODE_Column, but do not truncate data */
          903  +#define MODE_Ascii   10  /* Use ASCII unit and record separators (0x1F/0x1E) */
          904  +#define MODE_Pretty  11  /* Pretty-print schemas */
          905  +
          906  +static const char *modeDescr[] = {
          907  +  "line",
          908  +  "column",
          909  +  "list",
          910  +  "semi",
          911  +  "html",
          912  +  "insert",
          913  +  "quote",
          914  +  "tcl",
          915  +  "csv",
          916  +  "explain",
          917  +  "ascii",
          918  +  "prettyprint",
          919  +};
          920  +
          921  +/*
          922  +** These are the column/row/line separators used by the various
          923  +** import/export modes.
          924  +*/
          925  +#define SEP_Column    "|"
          926  +#define SEP_Row       "\n"
          927  +#define SEP_Tab       "\t"
          928  +#define SEP_Space     " "
          929  +#define SEP_Comma     ","
          930  +#define SEP_CrLf      "\r\n"
          931  +#define SEP_Unit      "\x1F"
          932  +#define SEP_Record    "\x1E"
          933  +
          934  +/*
          935  +** Number of elements in an array
          936  +*/
          937  +#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
          938  +
          939  +/*
          940  +** A callback for the sqlite3_log() interface.
          941  +*/
          942  +static void shellLog(void *pArg, int iErrCode, const char *zMsg){
          943  +  ShellState *p = (ShellState*)pArg;
          944  +  if( p->pLog==0 ) return;
          945  +  utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
          946  +  fflush(p->pLog);
          947  +}
          948  +
          949  +/*
          950  +** Output the given string as a hex-encoded blob (eg. X'1234' )
          951  +*/
          952  +static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
          953  +  int i;
          954  +  char *zBlob = (char *)pBlob;
          955  +  raw_printf(out,"X'");
          956  +  for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
          957  +  raw_printf(out,"'");
          958  +}
          959  +
          960  +/*
          961  +** Find a string that is not found anywhere in z[].  Return a pointer
          962  +** to that string.
          963  +**
          964  +** Try to use zA and zB first.  If both of those are already found in z[]
          965  +** then make up some string and store it in the buffer zBuf.
          966  +*/
          967  +static const char *unused_string(
          968  +  const char *z,                    /* Result must not appear anywhere in z */
          969  +  const char *zA, const char *zB,   /* Try these first */
          970  +  char *zBuf                        /* Space to store a generated string */
          971  +){
          972  +  unsigned i = 0;
          973  +  if( strstr(z, zA)==0 ) return zA;
          974  +  if( strstr(z, zB)==0 ) return zB;
          975  +  do{
          976  +    sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
          977  +  }while( strstr(z,zBuf)!=0 );
          978  +  return zBuf;
          979  +}
          980  +
          981  +/*
          982  +** Output the given string as a quoted string using SQL quoting conventions.
          983  +**
          984  +** See also: output_quoted_escaped_string()
          985  +*/
          986  +static void output_quoted_string(FILE *out, const char *z){
          987  +  int i;
          988  +  char c;
          989  +  setBinaryMode(out, 1);
          990  +  for(i=0; (c = z[i])!=0 && c!='\''; i++){}
          991  +  if( c==0 ){
          992  +    utf8_printf(out,"'%s'",z);
          993  +  }else{
          994  +    raw_printf(out, "'");
          995  +    while( *z ){
          996  +      for(i=0; (c = z[i])!=0 && c!='\''; i++){}
          997  +      if( c=='\'' ) i++;
          998  +      if( i ){
          999  +        utf8_printf(out, "%.*s", i, z);
         1000  +        z += i;
         1001  +      }
         1002  +      if( c=='\'' ){
         1003  +        raw_printf(out, "'");
         1004  +        continue;
         1005  +      }
         1006  +      if( c==0 ){
         1007  +        break;
         1008  +      }
         1009  +      z++;
         1010  +    }
         1011  +    raw_printf(out, "'");
         1012  +  }
         1013  +  setTextMode(out, 1);
         1014  +}
         1015  +
         1016  +/*
         1017  +** Output the given string as a quoted string using SQL quoting conventions.
         1018  +** Additionallly , escape the "\n" and "\r" characters so that they do not
         1019  +** get corrupted by end-of-line translation facilities in some operating
         1020  +** systems.
         1021  +**
         1022  +** This is like output_quoted_string() but with the addition of the \r\n
         1023  +** escape mechanism.
         1024  +*/
         1025  +static void output_quoted_escaped_string(FILE *out, const char *z){
         1026  +  int i;
         1027  +  char c;
         1028  +  setBinaryMode(out, 1);
         1029  +  for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
         1030  +  if( c==0 ){
         1031  +    utf8_printf(out,"'%s'",z);
         1032  +  }else{
         1033  +    const char *zNL = 0;
         1034  +    const char *zCR = 0;
         1035  +    int nNL = 0;
         1036  +    int nCR = 0;
         1037  +    char zBuf1[20], zBuf2[20];
         1038  +    for(i=0; z[i]; i++){
         1039  +      if( z[i]=='\n' ) nNL++;
         1040  +      if( z[i]=='\r' ) nCR++;
         1041  +    }
         1042  +    if( nNL ){
         1043  +      raw_printf(out, "replace(");
         1044  +      zNL = unused_string(z, "\\n", "\\012", zBuf1);
         1045  +    }
         1046  +    if( nCR ){
         1047  +      raw_printf(out, "replace(");
         1048  +      zCR = unused_string(z, "\\r", "\\015", zBuf2);
         1049  +    }
         1050  +    raw_printf(out, "'");
         1051  +    while( *z ){
         1052  +      for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
         1053  +      if( c=='\'' ) i++;
         1054  +      if( i ){
         1055  +        utf8_printf(out, "%.*s", i, z);
         1056  +        z += i;
         1057  +      }
         1058  +      if( c=='\'' ){
         1059  +        raw_printf(out, "'");
         1060  +        continue;
         1061  +      }
         1062  +      if( c==0 ){
         1063  +        break;
         1064  +      }
         1065  +      z++;
         1066  +      if( c=='\n' ){
         1067  +        raw_printf(out, "%s", zNL);
         1068  +        continue;
         1069  +      }
         1070  +      raw_printf(out, "%s", zCR);
         1071  +    }
         1072  +    raw_printf(out, "'");
         1073  +    if( nCR ){
         1074  +      raw_printf(out, ",'%s',char(13))", zCR);
         1075  +    }
         1076  +    if( nNL ){
         1077  +      raw_printf(out, ",'%s',char(10))", zNL);
         1078  +    }
         1079  +  }
         1080  +  setTextMode(out, 1);
         1081  +}
         1082  +
         1083  +/*
         1084  +** Output the given string as a quoted according to C or TCL quoting rules.
         1085  +*/
         1086  +static void output_c_string(FILE *out, const char *z){
         1087  +  unsigned int c;
         1088  +  fputc('"', out);
         1089  +  while( (c = *(z++))!=0 ){
         1090  +    if( c=='\\' ){
         1091  +      fputc(c, out);
         1092  +      fputc(c, out);
         1093  +    }else if( c=='"' ){
         1094  +      fputc('\\', out);
         1095  +      fputc('"', out);
         1096  +    }else if( c=='\t' ){
         1097  +      fputc('\\', out);
         1098  +      fputc('t', out);
         1099  +    }else if( c=='\n' ){
         1100  +      fputc('\\', out);
         1101  +      fputc('n', out);
         1102  +    }else if( c=='\r' ){
         1103  +      fputc('\\', out);
         1104  +      fputc('r', out);
         1105  +    }else if( !isprint(c&0xff) ){
         1106  +      raw_printf(out, "\\%03o", c&0xff);
         1107  +    }else{
         1108  +      fputc(c, out);
         1109  +    }
         1110  +  }
         1111  +  fputc('"', out);
         1112  +}
         1113  +
         1114  +/*
         1115  +** Output the given string with characters that are special to
         1116  +** HTML escaped.
         1117  +*/
         1118  +static void output_html_string(FILE *out, const char *z){
         1119  +  int i;
         1120  +  if( z==0 ) z = "";
         1121  +  while( *z ){
         1122  +    for(i=0;   z[i]
         1123  +            && z[i]!='<'
         1124  +            && z[i]!='&'
         1125  +            && z[i]!='>'
         1126  +            && z[i]!='\"'
         1127  +            && z[i]!='\'';
         1128  +        i++){}
         1129  +    if( i>0 ){
         1130  +      utf8_printf(out,"%.*s",i,z);
         1131  +    }
         1132  +    if( z[i]=='<' ){
         1133  +      raw_printf(out,"&lt;");
         1134  +    }else if( z[i]=='&' ){
         1135  +      raw_printf(out,"&amp;");
         1136  +    }else if( z[i]=='>' ){
         1137  +      raw_printf(out,"&gt;");
         1138  +    }else if( z[i]=='\"' ){
         1139  +      raw_printf(out,"&quot;");
         1140  +    }else if( z[i]=='\'' ){
         1141  +      raw_printf(out,"&#39;");
         1142  +    }else{
         1143  +      break;
         1144  +    }
         1145  +    z += i + 1;
         1146  +  }
         1147  +}
         1148  +
         1149  +/*
         1150  +** If a field contains any character identified by a 1 in the following
         1151  +** array, then the string must be quoted for CSV.
         1152  +*/
         1153  +static const char needCsvQuote[] = {
         1154  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1155  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1156  +  1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0,
         1157  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
         1158  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
         1159  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
         1160  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
         1161  +  0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1,
         1162  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1163  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1164  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1165  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1166  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1167  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1168  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1169  +  1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
         1170  +};
         1171  +
         1172  +/*
         1173  +** Output a single term of CSV.  Actually, p->colSeparator is used for
         1174  +** the separator, which may or may not be a comma.  p->nullValue is
         1175  +** the null value.  Strings are quoted if necessary.  The separator
         1176  +** is only issued if bSep is true.
         1177  +*/
         1178  +static void output_csv(ShellState *p, const char *z, int bSep){
         1179  +  FILE *out = p->out;
         1180  +  if( z==0 ){
         1181  +    utf8_printf(out,"%s",p->nullValue);
         1182  +  }else{
         1183  +    int i;
         1184  +    int nSep = strlen30(p->colSeparator);
         1185  +    for(i=0; z[i]; i++){
         1186  +      if( needCsvQuote[((unsigned char*)z)[i]]
         1187  +         || (z[i]==p->colSeparator[0] &&
         1188  +             (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
         1189  +        i = 0;
         1190  +        break;
         1191  +      }
         1192  +    }
         1193  +    if( i==0 ){
         1194  +      putc('"', out);
         1195  +      for(i=0; z[i]; i++){
         1196  +        if( z[i]=='"' ) putc('"', out);
         1197  +        putc(z[i], out);
         1198  +      }
         1199  +      putc('"', out);
         1200  +    }else{
         1201  +      utf8_printf(out, "%s", z);
         1202  +    }
         1203  +  }
         1204  +  if( bSep ){
         1205  +    utf8_printf(p->out, "%s", p->colSeparator);
         1206  +  }
         1207  +}
         1208  +
         1209  +#ifdef SIGINT
         1210  +/*
         1211  +** This routine runs when the user presses Ctrl-C
         1212  +*/
         1213  +static void interrupt_handler(int NotUsed){
         1214  +  UNUSED_PARAMETER(NotUsed);
         1215  +  seenInterrupt++;
         1216  +  if( seenInterrupt>2 ) exit(1);
         1217  +  if( globalDb ) sqlite3_interrupt(globalDb);
         1218  +}
         1219  +#endif
         1220  +
         1221  +#ifndef SQLITE_OMIT_AUTHORIZATION
         1222  +/*
         1223  +** When the ".auth ON" is set, the following authorizer callback is
         1224  +** invoked.  It always returns SQLITE_OK.
         1225  +*/
         1226  +static int shellAuth(
         1227  +  void *pClientData,
         1228  +  int op,
         1229  +  const char *zA1,
         1230  +  const char *zA2,
         1231  +  const char *zA3,
         1232  +  const char *zA4
         1233  +){
         1234  +  ShellState *p = (ShellState*)pClientData;
         1235  +  static const char *azAction[] = { 0,
         1236  +     "CREATE_INDEX",         "CREATE_TABLE",         "CREATE_TEMP_INDEX",
         1237  +     "CREATE_TEMP_TABLE",    "CREATE_TEMP_TRIGGER",  "CREATE_TEMP_VIEW",
         1238  +     "CREATE_TRIGGER",       "CREATE_VIEW",          "DELETE",
         1239  +     "DROP_INDEX",           "DROP_TABLE",           "DROP_TEMP_INDEX",
         1240  +     "DROP_TEMP_TABLE",      "DROP_TEMP_TRIGGER",    "DROP_TEMP_VIEW",
         1241  +     "DROP_TRIGGER",         "DROP_VIEW",            "INSERT",
         1242  +     "PRAGMA",               "READ",                 "SELECT",
         1243  +     "TRANSACTION",          "UPDATE",               "ATTACH",
         1244  +     "DETACH",               "ALTER_TABLE",          "REINDEX",
         1245  +     "ANALYZE",              "CREATE_VTABLE",        "DROP_VTABLE",
         1246  +     "FUNCTION",             "SAVEPOINT",            "RECURSIVE"
         1247  +  };
         1248  +  int i;
         1249  +  const char *az[4];
         1250  +  az[0] = zA1;
         1251  +  az[1] = zA2;
         1252  +  az[2] = zA3;
         1253  +  az[3] = zA4;
         1254  +  utf8_printf(p->out, "authorizer: %s", azAction[op]);
         1255  +  for(i=0; i<4; i++){
         1256  +    raw_printf(p->out, " ");
         1257  +    if( az[i] ){
         1258  +      output_c_string(p->out, az[i]);
         1259  +    }else{
         1260  +      raw_printf(p->out, "NULL");
         1261  +    }
         1262  +  }
         1263  +  raw_printf(p->out, "\n");
         1264  +  return SQLITE_OK;
         1265  +}
         1266  +#endif
         1267  +
         1268  +/*
         1269  +** Print a schema statement.  Part of MODE_Semi and MODE_Pretty output.
         1270  +**
         1271  +** This routine converts some CREATE TABLE statements for shadow tables
         1272  +** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
         1273  +*/
         1274  +static void printSchemaLine(FILE *out, const char *z, const char *zTail){
         1275  +  if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
         1276  +    utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
         1277  +  }else{
         1278  +    utf8_printf(out, "%s%s", z, zTail);
         1279  +  }
         1280  +}
         1281  +static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
         1282  +  char c = z[n];
         1283  +  z[n] = 0;
         1284  +  printSchemaLine(out, z, zTail);
         1285  +  z[n] = c;
         1286  +}
         1287  +
         1288  +/*
         1289  +** This is the callback routine that the shell
         1290  +** invokes for each row of a query result.
         1291  +*/
         1292  +static int shell_callback(
         1293  +  void *pArg,
         1294  +  int nArg,        /* Number of result columns */
         1295  +  char **azArg,    /* Text of each result column */
         1296  +  char **azCol,    /* Column names */
         1297  +  int *aiType      /* Column types */
         1298  +){
         1299  +  int i;
         1300  +  ShellState *p = (ShellState*)pArg;
         1301  +
         1302  +  switch( p->cMode ){
         1303  +    case MODE_Line: {
         1304  +      int w = 5;
         1305  +      if( azArg==0 ) break;
         1306  +      for(i=0; i<nArg; i++){
         1307  +        int len = strlen30(azCol[i] ? azCol[i] : "");
         1308  +        if( len>w ) w = len;
         1309  +      }
         1310  +      if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
         1311  +      for(i=0; i<nArg; i++){
         1312  +        utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
         1313  +                azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
         1314  +      }
         1315  +      break;
         1316  +    }
         1317  +    case MODE_Explain:
         1318  +    case MODE_Column: {
         1319  +      static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
         1320  +      const int *colWidth;
         1321  +      int showHdr;
         1322  +      char *rowSep;
         1323  +      if( p->cMode==MODE_Column ){
         1324  +        colWidth = p->colWidth;
         1325  +        showHdr = p->showHeader;
         1326  +        rowSep = p->rowSeparator;
         1327  +      }else{
         1328  +        colWidth = aExplainWidths;
         1329  +        showHdr = 1;
         1330  +        rowSep = SEP_Row;
         1331  +      }
         1332  +      if( p->cnt++==0 ){
         1333  +        for(i=0; i<nArg; i++){
         1334  +          int w, n;
         1335  +          if( i<ArraySize(p->colWidth) ){
         1336  +            w = colWidth[i];
         1337  +          }else{
         1338  +            w = 0;
         1339  +          }
         1340  +          if( w==0 ){
         1341  +            w = strlenChar(azCol[i] ? azCol[i] : "");
         1342  +            if( w<10 ) w = 10;
         1343  +            n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue);
         1344  +            if( w<n ) w = n;
         1345  +          }
         1346  +          if( i<ArraySize(p->actualWidth) ){
         1347  +            p->actualWidth[i] = w;
         1348  +          }
         1349  +          if( showHdr ){
         1350  +            utf8_width_print(p->out, w, azCol[i]);
         1351  +            utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : "  ");
         1352  +          }
         1353  +        }
         1354  +        if( showHdr ){
         1355  +          for(i=0; i<nArg; i++){
         1356  +            int w;
         1357  +            if( i<ArraySize(p->actualWidth) ){
         1358  +               w = p->actualWidth[i];
         1359  +               if( w<0 ) w = -w;
         1360  +            }else{
         1361  +               w = 10;
         1362  +            }
         1363  +            utf8_printf(p->out,"%-*.*s%s",w,w,
         1364  +                   "----------------------------------------------------------"
         1365  +                   "----------------------------------------------------------",
         1366  +                    i==nArg-1 ? rowSep : "  ");
         1367  +          }
         1368  +        }
         1369  +      }
         1370  +      if( azArg==0 ) break;
         1371  +      for(i=0; i<nArg; i++){
         1372  +        int w;
         1373  +        if( i<ArraySize(p->actualWidth) ){
         1374  +           w = p->actualWidth[i];
         1375  +        }else{
         1376  +           w = 10;
         1377  +        }
         1378  +        if( p->cMode==MODE_Explain && azArg[i] && strlenChar(azArg[i])>w ){
         1379  +          w = strlenChar(azArg[i]);
         1380  +        }
         1381  +        if( i==1 && p->aiIndent && p->pStmt ){
         1382  +          if( p->iIndent<p->nIndent ){
         1383  +            utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
         1384  +          }
         1385  +          p->iIndent++;
         1386  +        }
         1387  +        utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
         1388  +        utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : "  ");
         1389  +      }
         1390  +      break;
         1391  +    }
         1392  +    case MODE_Semi: {   /* .schema and .fullschema output */
         1393  +      printSchemaLine(p->out, azArg[0], ";\n");
         1394  +      break;
         1395  +    }
         1396  +    case MODE_Pretty: {  /* .schema and .fullschema with --indent */
         1397  +      char *z;
         1398  +      int j;
         1399  +      int nParen = 0;
         1400  +      char cEnd = 0;
         1401  +      char c;
         1402  +      int nLine = 0;
         1403  +      assert( nArg==1 );
         1404  +      if( azArg[0]==0 ) break;
         1405  +      if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
         1406  +       || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
         1407  +      ){
         1408  +        utf8_printf(p->out, "%s;\n", azArg[0]);
         1409  +        break;
         1410  +      }
         1411  +      z = sqlite3_mprintf("%s", azArg[0]);
         1412  +      j = 0;
         1413  +      for(i=0; IsSpace(z[i]); i++){}
         1414  +      for(; (c = z[i])!=0; i++){
         1415  +        if( IsSpace(c) ){
         1416  +          if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
         1417  +        }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
         1418  +          j--;
         1419  +        }
         1420  +        z[j++] = c;
         1421  +      }
         1422  +      while( j>0 && IsSpace(z[j-1]) ){ j--; }
         1423  +      z[j] = 0;
         1424  +      if( strlen30(z)>=79 ){
         1425  +        for(i=j=0; (c = z[i])!=0; i++){
         1426  +          if( c==cEnd ){
         1427  +            cEnd = 0;
         1428  +          }else if( c=='"' || c=='\'' || c=='`' ){
         1429  +            cEnd = c;
         1430  +          }else if( c=='[' ){
         1431  +            cEnd = ']';
         1432  +          }else if( c=='(' ){
         1433  +            nParen++;
         1434  +          }else if( c==')' ){
         1435  +            nParen--;
         1436  +            if( nLine>0 && nParen==0 && j>0 ){
         1437  +              printSchemaLineN(p->out, z, j, "\n");
         1438  +              j = 0;
         1439  +            }
         1440  +          }
         1441  +          z[j++] = c;
         1442  +          if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
         1443  +            if( c=='\n' ) j--;
         1444  +            printSchemaLineN(p->out, z, j, "\n  ");
         1445  +            j = 0;
         1446  +            nLine++;
         1447  +            while( IsSpace(z[i+1]) ){ i++; }
         1448  +          }
         1449  +        }
         1450  +        z[j] = 0;
         1451  +      }
         1452  +      printSchemaLine(p->out, z, ";\n");
         1453  +      sqlite3_free(z);
         1454  +      break;
         1455  +    }
         1456  +    case MODE_List: {
         1457  +      if( p->cnt++==0 && p->showHeader ){
         1458  +        for(i=0; i<nArg; i++){
         1459  +          utf8_printf(p->out,"%s%s",azCol[i],
         1460  +                  i==nArg-1 ? p->rowSeparator : p->colSeparator);
         1461  +        }
         1462  +      }
         1463  +      if( azArg==0 ) break;
         1464  +      for(i=0; i<nArg; i++){
         1465  +        char *z = azArg[i];
         1466  +        if( z==0 ) z = p->nullValue;
         1467  +        utf8_printf(p->out, "%s", z);
         1468  +        if( i<nArg-1 ){
         1469  +          utf8_printf(p->out, "%s", p->colSeparator);
         1470  +        }else{
         1471  +          utf8_printf(p->out, "%s", p->rowSeparator);
         1472  +        }
         1473  +      }
         1474  +      break;
         1475  +    }
         1476  +    case MODE_Html: {
         1477  +      if( p->cnt++==0 && p->showHeader ){
         1478  +        raw_printf(p->out,"<TR>");
         1479  +        for(i=0; i<nArg; i++){
         1480  +          raw_printf(p->out,"<TH>");
         1481  +          output_html_string(p->out, azCol[i]);
         1482  +          raw_printf(p->out,"</TH>\n");
         1483  +        }
         1484  +        raw_printf(p->out,"</TR>\n");
         1485  +      }
         1486  +      if( azArg==0 ) break;
         1487  +      raw_printf(p->out,"<TR>");
         1488  +      for(i=0; i<nArg; i++){
         1489  +        raw_printf(p->out,"<TD>");
         1490  +        output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
         1491  +        raw_printf(p->out,"</TD>\n");
         1492  +      }
         1493  +      raw_printf(p->out,"</TR>\n");
         1494  +      break;
         1495  +    }
         1496  +    case MODE_Tcl: {
         1497  +      if( p->cnt++==0 && p->showHeader ){
         1498  +        for(i=0; i<nArg; i++){
         1499  +          output_c_string(p->out,azCol[i] ? azCol[i] : "");
         1500  +          if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
         1501  +        }
         1502  +        utf8_printf(p->out, "%s", p->rowSeparator);
         1503  +      }
         1504  +      if( azArg==0 ) break;
         1505  +      for(i=0; i<nArg; i++){
         1506  +        output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
         1507  +        if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
         1508  +      }
         1509  +      utf8_printf(p->out, "%s", p->rowSeparator);
         1510  +      break;
         1511  +    }
         1512  +    case MODE_Csv: {
         1513  +      setBinaryMode(p->out, 1);
         1514  +      if( p->cnt++==0 && p->showHeader ){
         1515  +        for(i=0; i<nArg; i++){
         1516  +          output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
         1517  +        }
         1518  +        utf8_printf(p->out, "%s", p->rowSeparator);
         1519  +      }
         1520  +      if( nArg>0 ){
         1521  +        for(i=0; i<nArg; i++){
         1522  +          output_csv(p, azArg[i], i<nArg-1);
         1523  +        }
         1524  +        utf8_printf(p->out, "%s", p->rowSeparator);
         1525  +      }
         1526  +      setTextMode(p->out, 1);
         1527  +      break;
         1528  +    }
         1529  +    case MODE_Insert: {
         1530  +      if( azArg==0 ) break;
         1531  +      utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
         1532  +      if( p->showHeader ){
         1533  +        raw_printf(p->out,"(");
         1534  +        for(i=0; i<nArg; i++){
         1535  +          if( i>0 ) raw_printf(p->out, ",");
         1536  +          if( quoteChar(azCol[i]) ){
         1537  +            char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
         1538  +            utf8_printf(p->out, "%s", z);
         1539  +            sqlite3_free(z);
         1540  +          }else{
         1541  +            raw_printf(p->out, "%s", azCol[i]);
         1542  +          }
         1543  +        }
         1544  +        raw_printf(p->out,")");
         1545  +      }
         1546  +      p->cnt++;
         1547  +      for(i=0; i<nArg; i++){
         1548  +        raw_printf(p->out, i>0 ? "," : " VALUES(");
         1549  +        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
         1550  +          utf8_printf(p->out,"NULL");
         1551  +        }else if( aiType && aiType[i]==SQLITE_TEXT ){
         1552  +          if( ShellHasFlag(p, SHFLG_Newlines) ){
         1553  +            output_quoted_string(p->out, azArg[i]);
         1554  +          }else{
         1555  +            output_quoted_escaped_string(p->out, azArg[i]);
         1556  +          }
         1557  +        }else if( aiType && aiType[i]==SQLITE_INTEGER ){
         1558  +          utf8_printf(p->out,"%s", azArg[i]);
         1559  +        }else if( aiType && aiType[i]==SQLITE_FLOAT ){
         1560  +          char z[50];
         1561  +          double r = sqlite3_column_double(p->pStmt, i);
         1562  +          sqlite3_snprintf(50,z,"%!.20g", r);
         1563  +          raw_printf(p->out, "%s", z);
         1564  +        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
         1565  +          const void *pBlob = sqlite3_column_blob(p->pStmt, i);
         1566  +          int nBlob = sqlite3_column_bytes(p->pStmt, i);
         1567  +          output_hex_blob(p->out, pBlob, nBlob);
         1568  +        }else if( isNumber(azArg[i], 0) ){
         1569  +          utf8_printf(p->out,"%s", azArg[i]);
         1570  +        }else if( ShellHasFlag(p, SHFLG_Newlines) ){
         1571  +          output_quoted_string(p->out, azArg[i]);
         1572  +        }else{
         1573  +          output_quoted_escaped_string(p->out, azArg[i]);
         1574  +        }
         1575  +      }
         1576  +      raw_printf(p->out,");\n");
         1577  +      break;
         1578  +    }
         1579  +    case MODE_Quote: {
         1580  +      if( azArg==0 ) break;
         1581  +      if( p->cnt==0 && p->showHeader ){
         1582  +        for(i=0; i<nArg; i++){
         1583  +          if( i>0 ) raw_printf(p->out, ",");
         1584  +          output_quoted_string(p->out, azCol[i]);
         1585  +        }
         1586  +        raw_printf(p->out,"\n");
         1587  +      }
         1588  +      p->cnt++;
         1589  +      for(i=0; i<nArg; i++){
         1590  +        if( i>0 ) raw_printf(p->out, ",");
         1591  +        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
         1592  +          utf8_printf(p->out,"NULL");
         1593  +        }else if( aiType && aiType[i]==SQLITE_TEXT ){
         1594  +          output_quoted_string(p->out, azArg[i]);
         1595  +        }else if( aiType && aiType[i]==SQLITE_INTEGER ){
         1596  +          utf8_printf(p->out,"%s", azArg[i]);
         1597  +        }else if( aiType && aiType[i]==SQLITE_FLOAT ){
         1598  +          char z[50];
         1599  +          double r = sqlite3_column_double(p->pStmt, i);
         1600  +          sqlite3_snprintf(50,z,"%!.20g", r);
         1601  +          raw_printf(p->out, "%s", z);
         1602  +        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
         1603  +          const void *pBlob = sqlite3_column_blob(p->pStmt, i);
         1604  +          int nBlob = sqlite3_column_bytes(p->pStmt, i);
         1605  +          output_hex_blob(p->out, pBlob, nBlob);
         1606  +        }else if( isNumber(azArg[i], 0) ){
         1607  +          utf8_printf(p->out,"%s", azArg[i]);
         1608  +        }else{
         1609  +          output_quoted_string(p->out, azArg[i]);
         1610  +        }
         1611  +      }
         1612  +      raw_printf(p->out,"\n");
         1613  +      break;
         1614  +    }
         1615  +    case MODE_Ascii: {
         1616  +      if( p->cnt++==0 && p->showHeader ){
         1617  +        for(i=0; i<nArg; i++){
         1618  +          if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
         1619  +          utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
         1620  +        }
         1621  +        utf8_printf(p->out, "%s", p->rowSeparator);
         1622  +      }
         1623  +      if( azArg==0 ) break;
         1624  +      for(i=0; i<nArg; i++){
         1625  +        if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
         1626  +        utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
         1627  +      }
         1628  +      utf8_printf(p->out, "%s", p->rowSeparator);
         1629  +      break;
         1630  +    }
         1631  +  }
         1632  +  return 0;
         1633  +}
         1634  +
         1635  +/*
         1636  +** This is the callback routine that the SQLite library
         1637  +** invokes for each row of a query result.
         1638  +*/
         1639  +static int callback(void *pArg, int nArg, char **azArg, char **azCol){
         1640  +  /* since we don't have type info, call the shell_callback with a NULL value */
         1641  +  return shell_callback(pArg, nArg, azArg, azCol, NULL);
         1642  +}
         1643  +
         1644  +/*
         1645  +** This is the callback routine from sqlite3_exec() that appends all
         1646  +** output onto the end of a ShellText object.
         1647  +*/
         1648  +static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
         1649  +  ShellText *p = (ShellText*)pArg;
         1650  +  int i;
         1651  +  UNUSED_PARAMETER(az);
         1652  +  if( p->n ) appendText(p, "|", 0);
         1653  +  for(i=0; i<nArg; i++){
         1654  +    if( i ) appendText(p, ",", 0);
         1655  +    if( azArg[i] ) appendText(p, azArg[i], 0);
         1656  +  }
         1657  +  return 0;
         1658  +}
         1659  +
         1660  +/*
         1661  +** Generate an appropriate SELFTEST table in the main database.
         1662  +*/
         1663  +static void createSelftestTable(ShellState *p){
         1664  +  char *zErrMsg = 0;
         1665  +  sqlite3_exec(p->db,
         1666  +    "SAVEPOINT selftest_init;\n"
         1667  +    "CREATE TABLE IF NOT EXISTS selftest(\n"
         1668  +    "  tno INTEGER PRIMARY KEY,\n"   /* Test number */
         1669  +    "  op TEXT,\n"                   /* Operator:  memo run */
         1670  +    "  cmd TEXT,\n"                  /* Command text */
         1671  +    "  ans TEXT\n"                   /* Desired answer */
         1672  +    ");"
         1673  +    "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
         1674  +    "INSERT INTO [_shell$self](rowid,op,cmd)\n"
         1675  +    "  VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
         1676  +    "         'memo','Tests generated by --init');\n"
         1677  +    "INSERT INTO [_shell$self]\n"
         1678  +    "  SELECT 'run',\n"
         1679  +    "    'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
         1680  +                                 "FROM sqlite_master ORDER BY 2'',224))',\n"
         1681  +    "    hex(sha3_query('SELECT type,name,tbl_name,sql "
         1682  +                          "FROM sqlite_master ORDER BY 2',224));\n"
         1683  +    "INSERT INTO [_shell$self]\n"
         1684  +    "  SELECT 'run',"
         1685  +    "    'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
         1686  +    "        printf('%w',name) || '\" NOT INDEXED'',224))',\n"
         1687  +    "    hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
         1688  +    "  FROM (\n"
         1689  +    "    SELECT name FROM sqlite_master\n"
         1690  +    "     WHERE type='table'\n"
         1691  +    "       AND name<>'selftest'\n"
         1692  +    "       AND coalesce(rootpage,0)>0\n"
         1693  +    "  )\n"
         1694  +    " ORDER BY name;\n"
         1695  +    "INSERT INTO [_shell$self]\n"
         1696  +    "  VALUES('run','PRAGMA integrity_check','ok');\n"
         1697  +    "INSERT INTO selftest(tno,op,cmd,ans)"
         1698  +    "  SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
         1699  +    "DROP TABLE [_shell$self];"
         1700  +    ,0,0,&zErrMsg);
         1701  +  if( zErrMsg ){
         1702  +    utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
         1703  +    sqlite3_free(zErrMsg);
         1704  +  }
         1705  +  sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
         1706  +}
         1707  +
         1708  +
         1709  +/*
         1710  +** Set the destination table field of the ShellState structure to
         1711  +** the name of the table given.  Escape any quote characters in the
         1712  +** table name.
         1713  +*/
         1714  +static void set_table_name(ShellState *p, const char *zName){
         1715  +  int i, n;
         1716  +  int cQuote;
         1717  +  char *z;
         1718  +
         1719  +  if( p->zDestTable ){
         1720  +    free(p->zDestTable);
         1721  +    p->zDestTable = 0;
         1722  +  }
         1723  +  if( zName==0 ) return;
         1724  +  cQuote = quoteChar(zName);
         1725  +  n = strlen30(zName);
         1726  +  if( cQuote ) n += n+2;
         1727  +  z = p->zDestTable = malloc( n+1 );
         1728  +  if( z==0 ){
         1729  +    raw_printf(stderr,"Error: out of memory\n");
         1730  +    exit(1);
         1731  +  }
         1732  +  n = 0;
         1733  +  if( cQuote ) z[n++] = cQuote;
         1734  +  for(i=0; zName[i]; i++){
         1735  +    z[n++] = zName[i];
         1736  +    if( zName[i]==cQuote ) z[n++] = cQuote;
         1737  +  }
         1738  +  if( cQuote ) z[n++] = cQuote;
         1739  +  z[n] = 0;
         1740  +}
         1741  +
         1742  +
         1743  +/*
         1744  +** Execute a query statement that will generate SQL output.  Print
         1745  +** the result columns, comma-separated, on a line and then add a
         1746  +** semicolon terminator to the end of that line.
         1747  +**
         1748  +** If the number of columns is 1 and that column contains text "--"
         1749  +** then write the semicolon on a separate line.  That way, if a
         1750  +** "--" comment occurs at the end of the statement, the comment
         1751  +** won't consume the semicolon terminator.
         1752  +*/
         1753  +static int run_table_dump_query(
         1754  +  ShellState *p,           /* Query context */
         1755  +  const char *zSelect,     /* SELECT statement to extract content */
         1756  +  const char *zFirstRow    /* Print before first row, if not NULL */
         1757  +){
         1758  +  sqlite3_stmt *pSelect;
         1759  +  int rc;
         1760  +  int nResult;
         1761  +  int i;
         1762  +  const char *z;
         1763  +  rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
         1764  +  if( rc!=SQLITE_OK || !pSelect ){
         1765  +    utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
         1766  +                sqlite3_errmsg(p->db));
         1767  +    if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
         1768  +    return rc;
         1769  +  }
         1770  +  rc = sqlite3_step(pSelect);
         1771  +  nResult = sqlite3_column_count(pSelect);
         1772  +  while( rc==SQLITE_ROW ){
         1773  +    if( zFirstRow ){
         1774  +      utf8_printf(p->out, "%s", zFirstRow);
         1775  +      zFirstRow = 0;
         1776  +    }
         1777  +    z = (const char*)sqlite3_column_text(pSelect, 0);
         1778  +    utf8_printf(p->out, "%s", z);
         1779  +    for(i=1; i<nResult; i++){
         1780  +      utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
         1781  +    }
         1782  +    if( z==0 ) z = "";
         1783  +    while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
         1784  +    if( z[0] ){
         1785  +      raw_printf(p->out, "\n;\n");
         1786  +    }else{
         1787  +      raw_printf(p->out, ";\n");
         1788  +    }
         1789  +    rc = sqlite3_step(pSelect);
         1790  +  }
         1791  +  rc = sqlite3_finalize(pSelect);
         1792  +  if( rc!=SQLITE_OK ){
         1793  +    utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
         1794  +                sqlite3_errmsg(p->db));
         1795  +    if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
         1796  +  }
         1797  +  return rc;
         1798  +}
         1799  +
         1800  +/*
         1801  +** Allocate space and save off current error string.
         1802  +*/
         1803  +static char *save_err_msg(
         1804  +  sqlite3 *db            /* Database to query */
         1805  +){
         1806  +  int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
         1807  +  char *zErrMsg = sqlite3_malloc64(nErrMsg);
         1808  +  if( zErrMsg ){
         1809  +    memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
         1810  +  }
         1811  +  return zErrMsg;
         1812  +}
         1813  +
         1814  +#ifdef __linux__
         1815  +/*
         1816  +** Attempt to display I/O stats on Linux using /proc/PID/io
         1817  +*/
         1818  +static void displayLinuxIoStats(FILE *out){
         1819  +  FILE *in;
         1820  +  char z[200];
         1821  +  sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
         1822  +  in = fopen(z, "rb");
         1823  +  if( in==0 ) return;
         1824  +  while( fgets(z, sizeof(z), in)!=0 ){
         1825  +    static const struct {
         1826  +      const char *zPattern;
         1827  +      const char *zDesc;
         1828  +    } aTrans[] = {
         1829  +      { "rchar: ",                  "Bytes received by read():" },
         1830  +      { "wchar: ",                  "Bytes sent to write():"    },
         1831  +      { "syscr: ",                  "Read() system calls:"      },
         1832  +      { "syscw: ",                  "Write() system calls:"     },
         1833  +      { "read_bytes: ",             "Bytes read from storage:"  },
         1834  +      { "write_bytes: ",            "Bytes written to storage:" },
         1835  +      { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
         1836  +    };
         1837  +    int i;
         1838  +    for(i=0; i<ArraySize(aTrans); i++){
         1839  +      int n = (int)strlen(aTrans[i].zPattern);
         1840  +      if( strncmp(aTrans[i].zPattern, z, n)==0 ){
         1841  +        utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
         1842  +        break;
         1843  +      }
         1844  +    }
         1845  +  }
         1846  +  fclose(in);
         1847  +}
         1848  +#endif
         1849  +
         1850  +/*
         1851  +** Display a single line of status using 64-bit values.
         1852  +*/
         1853  +static void displayStatLine(
         1854  +  ShellState *p,            /* The shell context */
         1855  +  char *zLabel,             /* Label for this one line */
         1856  +  char *zFormat,            /* Format for the result */
         1857  +  int iStatusCtrl,          /* Which status to display */
         1858  +  int bReset                /* True to reset the stats */
         1859  +){
         1860  +  sqlite3_int64 iCur = -1;
         1861  +  sqlite3_int64 iHiwtr = -1;
         1862  +  int i, nPercent;
         1863  +  char zLine[200];
         1864  +  sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
         1865  +  for(i=0, nPercent=0; zFormat[i]; i++){
         1866  +    if( zFormat[i]=='%' ) nPercent++;
         1867  +  }
         1868  +  if( nPercent>1 ){
         1869  +    sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
         1870  +  }else{
         1871  +    sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
         1872  +  }
         1873  +  raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
         1874  +}
         1875  +
         1876  +/*
         1877  +** Display memory stats.
         1878  +*/
         1879  +static int display_stats(
         1880  +  sqlite3 *db,                /* Database to query */
         1881  +  ShellState *pArg,           /* Pointer to ShellState */
         1882  +  int bReset                  /* True to reset the stats */
         1883  +){
         1884  +  int iCur;
         1885  +  int iHiwtr;
         1886  +
         1887  +  if( pArg && pArg->out ){
         1888  +    displayStatLine(pArg, "Memory Used:",
         1889  +       "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
         1890  +    displayStatLine(pArg, "Number of Outstanding Allocations:",
         1891  +       "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
         1892  +    if( pArg->shellFlgs & SHFLG_Pagecache ){
         1893  +      displayStatLine(pArg, "Number of Pcache Pages Used:",
         1894  +         "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
         1895  +    }
         1896  +    displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
         1897  +       "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
         1898  +    if( pArg->shellFlgs & SHFLG_Scratch ){
         1899  +      displayStatLine(pArg, "Number of Scratch Allocations Used:",
         1900  +         "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset);
         1901  +    }
         1902  +    displayStatLine(pArg, "Number of Scratch Overflow Bytes:",
         1903  +       "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLO