/ Check-in [6994826c]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge the latest trunk changes into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 6994826c0784280f2e9728dfa4185848846d03df
User & Date: drh 2013-04-22 23:59:06
Context
2013-05-03
18:29
Merge all recent trunk changes into the sessions branch. check-in: 3879ab1b user: drh tags: sessions
2013-04-22
23:59
Merge the latest trunk changes into the sessions branch. check-in: 6994826c user: drh tags: sessions
23:38
Fix harmless compiler warnings. check-in: 1a1cf5aa user: drh tags: trunk
2013-04-12
13:53
Fix the xCheckReservedLock() method on the windows VFS so that it cannot return a false positive when two or more processes use it at the same time on the same file. Ticket [7ff3120e4fa54abb55]. Update to version 3.7.16.2. check-in: 67b3c0ef user: drh tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   165    165   #
   166    166   LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
   167    167            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
   168    168            callback.lo complete.lo ctime.lo date.lo delete.lo \
   169    169            expr.lo fault.lo fkey.lo \
   170    170            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
   171    171            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
          172  +         fts3_tokenize_vtab.lo \
   172    173            fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
   173    174            func.lo global.lo hash.lo \
   174    175            icu.lo insert.lo journal.lo legacy.lo loadext.lo \
   175    176            main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
   176    177            memjournal.lo \
   177    178            mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
   178    179            notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
................................................................................
   315    316     $(TOP)/ext/fts3/fts3_hash.h \
   316    317     $(TOP)/ext/fts3/fts3_icu.c \
   317    318     $(TOP)/ext/fts3/fts3_porter.c \
   318    319     $(TOP)/ext/fts3/fts3_snippet.c \
   319    320     $(TOP)/ext/fts3/fts3_tokenizer.h \
   320    321     $(TOP)/ext/fts3/fts3_tokenizer.c \
   321    322     $(TOP)/ext/fts3/fts3_tokenizer1.c \
          323  +  $(TOP)/ext/fts3/fts3_tokenize_vtab.c \
   322    324     $(TOP)/ext/fts3/fts3_unicode.c \
   323    325     $(TOP)/ext/fts3/fts3_unicode2.c \
   324    326     $(TOP)/ext/fts3/fts3_write.c
   325    327   SRC += \
   326    328     $(TOP)/ext/icu/sqliteicu.h \
   327    329     $(TOP)/ext/icu/icu.c
   328    330   SRC += \
................................................................................
   506    508   		-version-info "8:6:8" \
   507    509   		-avoid-version
   508    510   
   509    511   sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h
   510    512   	$(LTLINK) $(READLINE_FLAGS) \
   511    513   		-o $@ $(TOP)/src/shell.c libsqlite3.la \
   512    514   		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
          515  +
          516  +mptester$(EXE):	sqlite3.c $(TOP)/mptest/mptest.c
          517  +	$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
          518  +		$(TLIBS) -rpath "$(libdir)"
          519  +
   513    520   
   514    521   # This target creates a directory named "tsrc" and fills it with
   515    522   # copies of all of the C source code and header files needed to
   516    523   # build on the target system.  Some of the C source code and header
   517    524   # files are automatically generated.  This target takes care of
   518    525   # all that automatic generation.
   519    526   #
................................................................................
   859    866   
   860    867   fts3_tokenizer.lo:	$(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
   861    868   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
   862    869   
   863    870   fts3_tokenizer1.lo:	$(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
   864    871   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
   865    872   
          873  +fts3_tokenizer_vtab.lo:	$(TOP)/ext/fts3/fts3_tokenizer_vtab.c $(HDR) $(EXTHDR)
          874  +	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer_vtab.c
          875  +
   866    876   fts3_unicode.lo:	$(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR)
   867    877   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c
   868    878   
   869    879   fts3_unicode2.lo:	$(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
   870    880   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c
   871    881   
   872    882   fts3_write.lo:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
................................................................................
   955    965   	rm -f *.da *.bb *.bbg gmon.out
   956    966   	rm -rf quota2a quota2b quota2c
   957    967   	rm -rf tsrc .target_source
   958    968   	rm -f tclsqlite3$(TEXE)
   959    969   	rm -f testfixture$(TEXE) test.db
   960    970   	rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
   961    971   	rm -f sqlite3.c
          972  +	rm -f sqlite3rc.h
          973  +	rm -f shell.c sqlite3ext.h
   962    974   	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
   963    975   	rm -f sqlite-*-output.vsix
          976  +	rm -f mptester mptester.exe
   964    977   
   965    978   distclean:	clean
   966    979   	rm -f config.log config.status libtool Makefile sqlite3.pc
   967    980   
   968    981   #
   969    982   # Windows section
   970    983   #

Changes to Makefile.msc.

   478    478   #
   479    479   LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
   480    480            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
   481    481            callback.lo complete.lo ctime.lo date.lo delete.lo \
   482    482            expr.lo fault.lo fkey.lo \
   483    483            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
   484    484            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
   485         -         fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
          485  +         fts3_tokenize_vtab.lo fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
   486    486            func.lo global.lo hash.lo \
   487    487            icu.lo insert.lo journal.lo legacy.lo loadext.lo \
   488    488            main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
   489    489            memjournal.lo \
   490    490            mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
   491    491            notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
   492    492            pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
................................................................................
   639    639     $(TOP)\ext\fts3\fts3_hash.h \
   640    640     $(TOP)\ext\fts3\fts3_icu.c \
   641    641     $(TOP)\ext\fts3\fts3_porter.c \
   642    642     $(TOP)\ext\fts3\fts3_snippet.c \
   643    643     $(TOP)\ext\fts3\fts3_tokenizer.h \
   644    644     $(TOP)\ext\fts3\fts3_tokenizer.c \
   645    645     $(TOP)\ext\fts3\fts3_tokenizer1.c \
          646  +  $(TOP)\ext\fts3\fts3_tokenize_vtab.c \
   646    647     $(TOP)\ext\fts3\fts3_unicode.c \
   647    648     $(TOP)\ext\fts3\fts3_unicode2.c \
   648    649     $(TOP)\ext\fts3\fts3_write.c
   649    650   SRC = $(SRC) \
   650    651     $(TOP)\ext\icu\sqliteicu.h \
   651    652     $(TOP)\ext\icu\icu.c
   652    653   SRC = $(SRC) \
................................................................................
   754    755     $(TOP)\src\vdbetrace.c \
   755    756     $(TOP)\src\where.c \
   756    757     parse.c \
   757    758     $(TOP)\ext\fts3\fts3.c \
   758    759     $(TOP)\ext\fts3\fts3_aux.c \
   759    760     $(TOP)\ext\fts3\fts3_expr.c \
   760    761     $(TOP)\ext\fts3\fts3_tokenizer.c \
          762  +  $(TOP)\ext\fts3\fts3_tokenize_vtab.c \
   761    763     $(TOP)\ext\fts3\fts3_unicode.c \
   762    764     $(TOP)\ext\fts3\fts3_unicode2.c \
   763    765     $(TOP)\ext\fts3\fts3_write.c \
   764    766     $(TOP)\ext\async\sqlite3async.c \
   765    767     $(TOP)\ext\session\sqlite3session.c
   766    768   
   767    769   # Source code to the library files needed by the test fixture
................................................................................
   828    830   	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
   829    831   
   830    832   sqlite3.exe:	$(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
   831    833   	$(LTLINK) $(READLINE_FLAGS) \
   832    834   		$(TOP)\src\shell.c \
   833    835   		/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
   834    836   
          837  +mptester.exe:	$(TOP)\mptest\mptest.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
          838  +	$(LTLINK) $(TOP)\mptest\mptest.c \
          839  +		/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
          840  +
   835    841   # This target creates a directory named "tsrc" and fills it with
   836    842   # copies of all of the C source code and header files needed to
   837    843   # build on the target system.  Some of the C source code and header
   838    844   # files are automatically generated.  This target takes care of
   839    845   # all that automatic generation.
   840    846   #
   841    847   .target_source:	$(SRC) $(TOP)\tool\vdbe-compress.tcl
................................................................................
  1188   1194   
  1189   1195   fts3_tokenizer.lo:	$(TOP)\ext\fts3\fts3_tokenizer.c $(HDR) $(EXTHDR)
  1190   1196   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenizer.c
  1191   1197   
  1192   1198   fts3_tokenizer1.lo:	$(TOP)\ext\fts3\fts3_tokenizer1.c $(HDR) $(EXTHDR)
  1193   1199   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenizer1.c
  1194   1200   
         1201  +fts3_tokenize_vtab.lo:	$(TOP)\ext\fts3\fts3_tokenize_vtab.c $(HDR) $(EXTHDR)
         1202  +	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenize_vtab.c
         1203  +
  1195   1204   fts3_unicode.lo:	$(TOP)\ext\fts3\fts3_unicode.c $(HDR) $(EXTHDR)
  1196   1205   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_unicode.c
  1197   1206   
  1198   1207   fts3_unicode2.lo:	$(TOP)\ext\fts3\fts3_unicode2.c $(HDR) $(EXTHDR)
  1199   1208   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_unicode2.c
  1200   1209   
  1201   1210   fts3_write.lo:	$(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
................................................................................
  1269   1278   	-rmdir /Q/S tsrc
  1270   1279   	del /Q .target_source
  1271   1280   	del /Q tclsqlite3.exe tclsqlite3.exp
  1272   1281   	del /Q testfixture.exe testfixture.exp test.db
  1273   1282   	del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
  1274   1283   	del /Q sqlite3.c
  1275   1284   	del /Q sqlite3rc.h
         1285  +	del /Q shell.c sqlite3ext.h
  1276   1286   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
  1277   1287   	del /Q sqlite-*-output.vsix
         1288  +	del /Q mptester.exe
  1278   1289   
  1279   1290   # Dynamic link library section.
  1280   1291   #
  1281   1292   dll: sqlite3.dll
  1282   1293   
  1283   1294   sqlite3.def: libsqlite3.lib
  1284   1295   	echo EXPORTS > sqlite3.def
  1285   1296   	dumpbin /all libsqlite3.lib \
  1286   1297   		| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
  1287   1298   		| sort >> sqlite3.def
  1288   1299   
  1289   1300   sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) sqlite3.def
  1290   1301   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)

Changes to Makefile.vxworks.

   658    658   	rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
   659    659   	rm -f $(PUBLISH)
   660    660   	rm -f *.da *.bb *.bbg gmon.out
   661    661   	rm -rf quota2a quota2b quota2c
   662    662   	rm -rf tsrc target_source
   663    663   	rm -f testloadext.dll libtestloadext.so
   664    664   	rm -f sqlite3.c fts?amal.c tclsqlite3.c
          665  +	rm -f sqlite3rc.h
          666  +	rm -f shell.c sqlite3ext.h
   665    667   	rm -f $(SHPREFIX)sqlite3.$(SO)

Changes to ext/fts3/fts3.c.

  3589   3589     rc = sqlite3Fts3InitTerm(db);
  3590   3590     if( rc!=SQLITE_OK ) return rc;
  3591   3591   #endif
  3592   3592   
  3593   3593     rc = sqlite3Fts3InitAux(db);
  3594   3594     if( rc!=SQLITE_OK ) return rc;
  3595   3595   
         3596  +  rc = sqlite3Fts3InitTok(db);
         3597  +  if( rc!=SQLITE_OK ) return rc;
         3598  +
  3596   3599     sqlite3Fts3SimpleTokenizerModule(&pSimple);
  3597   3600     sqlite3Fts3PorterTokenizerModule(&pPorter);
  3598   3601   
  3599   3602     /* Allocate and initialize the hash-table used to store tokenizers. */
  3600   3603     pHash = sqlite3_malloc(sizeof(Fts3Hash));
  3601   3604     if( !pHash ){
  3602   3605       rc = SQLITE_NOMEM;

Changes to ext/fts3/fts3Int.h.

   545    545       Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
   546    546   int sqlite3Fts3MsrIncrNext(
   547    547       Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
   548    548   int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); 
   549    549   int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
   550    550   int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
   551    551   
          552  +/* fts3_tokenize_vtab.c */
          553  +int sqlite3Fts3InitTok(sqlite3*);
          554  +
   552    555   /* fts3_unicode2.c (functions generated by parsing unicode text files) */
   553    556   #ifdef SQLITE_ENABLE_FTS4_UNICODE61
   554    557   int sqlite3FtsUnicodeFold(int, int);
   555    558   int sqlite3FtsUnicodeIsalnum(int);
   556    559   int sqlite3FtsUnicodeIsdiacritic(int);
   557    560   #endif
   558    561   
   559    562   #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
   560    563   #endif /* _FTSINT_H */

Changes to ext/fts3/fts3_aux.c.

    66     66     int nFts3;                      /* Result of strlen(zFts3) */
    67     67     int nByte;                      /* Bytes of space to allocate here */
    68     68     int rc;                         /* value returned by declare_vtab() */
    69     69     Fts3auxTable *p;                /* Virtual table object to return */
    70     70   
    71     71     UNUSED_PARAMETER(pUnused);
    72     72   
    73         -  /* The user should specify a single argument - the name of an fts3 table. */
    74         -  if( argc!=4 ){
    75         -    *pzErr = sqlite3_mprintf(
    76         -        "wrong number of arguments to fts4aux constructor"
    77         -    );
    78         -    return SQLITE_ERROR;
    79         -  }
           73  +  /* The user should invoke this in one of two forms:
           74  +  **
           75  +  **     CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table);
           76  +  **     CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table-db, fts4-table);
           77  +  */
           78  +  if( argc!=4 && argc!=5 ) goto bad_args;
    80     79   
    81     80     zDb = argv[1]; 
    82     81     nDb = (int)strlen(zDb);
    83         -  zFts3 = argv[3];
           82  +  if( argc==5 ){
           83  +    if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){
           84  +      zDb = argv[3]; 
           85  +      nDb = (int)strlen(zDb);
           86  +      zFts3 = argv[4];
           87  +    }else{
           88  +      goto bad_args;
           89  +    }
           90  +  }else{
           91  +    zFts3 = argv[3];
           92  +  }
    84     93     nFts3 = (int)strlen(zFts3);
    85     94   
    86     95     rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA);
    87     96     if( rc!=SQLITE_OK ) return rc;
    88     97   
    89     98     nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
    90     99     p = (Fts3auxTable *)sqlite3_malloc(nByte);
................................................................................
    99    108   
   100    109     memcpy((char *)p->pFts3Tab->zDb, zDb, nDb);
   101    110     memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3);
   102    111     sqlite3Fts3Dequote((char *)p->pFts3Tab->zName);
   103    112   
   104    113     *ppVtab = (sqlite3_vtab *)p;
   105    114     return SQLITE_OK;
          115  +
          116  + bad_args:
          117  +  *pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor");
          118  +  return SQLITE_ERROR;
   106    119   }
   107    120   
   108    121   /*
   109    122   ** This function does the work for both the xDisconnect and xDestroy methods.
   110    123   ** These tables have no persistent representation of their own, so xDisconnect
   111    124   ** and xDestroy are identical operations.
   112    125   */

Added ext/fts3/fts3_tokenize_vtab.c.

            1  +/*
            2  +** 2013 Apr 22
            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 code for the "fts3tokenize" virtual table module.
           14  +** An fts3tokenize virtual table is created as follows:
           15  +**
           16  +**   CREATE VIRTUAL TABLE <tbl> USING fts3tokenize(
           17  +**       <tokenizer-name>, <arg-1>, ...
           18  +**   );
           19  +**
           20  +** The table created has the following schema:
           21  +**
           22  +**   CREATE TABLE <tbl>(input, token, start, end, position)
           23  +**
           24  +** When queried, the query must include a WHERE clause of type:
           25  +**
           26  +**   input = <string>
           27  +**
           28  +** The virtual table module tokenizes this <string>, using the FTS3 
           29  +** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE 
           30  +** statement and returns one row for each token in the result. With
           31  +** fields set as follows:
           32  +**
           33  +**   input:   Always set to a copy of <string>
           34  +**   token:   A token from the input.
           35  +**   start:   Byte offset of the token within the input <string>.
           36  +**   end:     Byte offset of the byte immediately following the end of the
           37  +**            token within the input string.
           38  +**   pos:     Token offset of token within input.
           39  +**
           40  +*/
           41  +#include "fts3Int.h"
           42  +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
           43  +
           44  +#include <string.h>
           45  +#include <assert.h>
           46  +
           47  +typedef struct Fts3tokTable Fts3tokTable;
           48  +typedef struct Fts3tokCursor Fts3tokCursor;
           49  +
           50  +/*
           51  +** Virtual table structure.
           52  +*/
           53  +struct Fts3tokTable {
           54  +  sqlite3_vtab base;              /* Base class used by SQLite core */
           55  +  const sqlite3_tokenizer_module *pMod;
           56  +  sqlite3_tokenizer *pTok;
           57  +};
           58  +
           59  +/*
           60  +** Virtual table cursor structure.
           61  +*/
           62  +struct Fts3tokCursor {
           63  +  sqlite3_vtab_cursor base;       /* Base class used by SQLite core */
           64  +  char *zInput;                   /* Input string */
           65  +  sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */
           66  +  int iRowid;                     /* Current 'rowid' value */
           67  +  const char *zToken;             /* Current 'token' value */
           68  +  int nToken;                     /* Size of zToken in bytes */
           69  +  int iStart;                     /* Current 'start' value */
           70  +  int iEnd;                       /* Current 'end' value */
           71  +  int iPos;                       /* Current 'pos' value */
           72  +};
           73  +
           74  +/*
           75  +** Query FTS for the tokenizer implementation named zName.
           76  +*/
           77  +static int fts3tokQueryTokenizer(
           78  +  sqlite3 *db,
           79  +  const char *zName,
           80  +  const sqlite3_tokenizer_module **pp
           81  +){
           82  +  int rc;
           83  +  sqlite3_stmt *pStmt;
           84  +  const char *zSql = "SELECT fts3_tokenizer(?)";
           85  +
           86  +  *pp = 0;
           87  +  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
           88  +  if( rc!=SQLITE_OK ){
           89  +    return rc;
           90  +  }
           91  +
           92  +  sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
           93  +  if( SQLITE_ROW==sqlite3_step(pStmt) ){
           94  +    if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
           95  +      memcpy((void*)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
           96  +    }
           97  +  }
           98  +
           99  +  return sqlite3_finalize(pStmt);
          100  +}
          101  +
          102  +/*
          103  +** The second argument, argv[], is an array of pointers to nul-terminated
          104  +** strings. This function makes a copy of the array and strings into a 
          105  +** single block of memory. It then dequotes any of the strings that appear
          106  +** to be quoted.
          107  +**
          108  +** If successful, output parameter *pazDequote is set to point at the
          109  +** array of dequoted strings and SQLITE_OK is returned. The caller is
          110  +** responsible for eventually calling sqlite3_free() to free the array
          111  +** in this case. Or, if an error occurs, an SQLite error code is returned.
          112  +** The final value of *pazDequote is undefined in this case.
          113  +*/
          114  +static int fts3tokDequoteArray(
          115  +  int argc,                       /* Number of elements in argv[] */
          116  +  const char * const *argv,       /* Input array */
          117  +  char ***pazDequote              /* Output array */
          118  +){
          119  +  int rc = SQLITE_OK;             /* Return code */
          120  +  if( argc==0 ){
          121  +    *pazDequote = 0;
          122  +  }else{
          123  +    int i;
          124  +    int nByte = 0;
          125  +    char **azDequote;
          126  +
          127  +    for(i=0; i<argc; i++){
          128  +      nByte += (int)(strlen(argv[i]) + 1);
          129  +    }
          130  +
          131  +    *pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
          132  +    if( azDequote==0 ){
          133  +      rc = SQLITE_NOMEM;
          134  +    }else{
          135  +      char *pSpace = (char *)&azDequote[argc];
          136  +      for(i=0; i<argc; i++){
          137  +        int n = (int)strlen(argv[i]);
          138  +        azDequote[i] = pSpace;
          139  +        memcpy(pSpace, argv[i], n+1);
          140  +        sqlite3Fts3Dequote(pSpace);
          141  +        pSpace += (n+1);
          142  +      }
          143  +    }
          144  +  }
          145  +
          146  +  return rc;
          147  +}
          148  +
          149  +/*
          150  +** Schema of the tokenizer table.
          151  +*/
          152  +#define FTS3_TOK_SCHEMA "CREATE TABLE x(input, token, start, end, position)"
          153  +
          154  +/*
          155  +** This function does all the work for both the xConnect and xCreate methods.
          156  +** These tables have no persistent representation of their own, so xConnect
          157  +** and xCreate are identical operations.
          158  +**
          159  +**   argv[0]: module name
          160  +**   argv[1]: database name 
          161  +**   argv[2]: table name
          162  +**   argv[3]: first argument (tokenizer name)
          163  +*/
          164  +static int fts3tokConnectMethod(
          165  +  sqlite3 *db,                    /* Database connection */
          166  +  void *pUnused,                  /* Unused */
          167  +  int argc,                       /* Number of elements in argv array */
          168  +  const char * const *argv,       /* xCreate/xConnect argument array */
          169  +  sqlite3_vtab **ppVtab,          /* OUT: New sqlite3_vtab object */
          170  +  char **pzErr                    /* OUT: sqlite3_malloc'd error message */
          171  +){
          172  +  Fts3tokTable *pTab;
          173  +  const sqlite3_tokenizer_module *pMod = 0;
          174  +  sqlite3_tokenizer *pTok = 0;
          175  +  int rc;
          176  +  char **azDequote = 0;
          177  +  int nDequote;
          178  +  UNUSED_PARAMETER(pUnused);
          179  +
          180  +  rc = sqlite3_declare_vtab(db, FTS3_TOK_SCHEMA);
          181  +  if( rc!=SQLITE_OK ) return rc;
          182  +
          183  +  nDequote = argc-3;
          184  +  rc = fts3tokDequoteArray(nDequote, &argv[3], &azDequote);
          185  +
          186  +  if( rc==SQLITE_OK ){
          187  +    const char *zModule;
          188  +    if( nDequote<1 ){
          189  +      zModule = "simple";
          190  +    }else{
          191  +      zModule = azDequote[0];
          192  +    }
          193  +    rc = fts3tokQueryTokenizer(db, zModule, &pMod);
          194  +  }
          195  +
          196  +  if( rc!=SQLITE_OK ){
          197  +    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
          198  +  }else if( pMod==0 ){
          199  +    rc = SQLITE_ERROR;
          200  +  }else{
          201  +    const char * const *azArg = (const char * const *)&azDequote[1];
          202  +    rc = pMod->xCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok);
          203  +  }
          204  +
          205  +  if( rc==SQLITE_OK ){
          206  +    pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable));
          207  +    if( pTab==0 ){
          208  +      rc = SQLITE_NOMEM;
          209  +    }
          210  +  }
          211  +
          212  +  if( rc==SQLITE_OK ){
          213  +    memset(pTab, 0, sizeof(Fts3tokTable));
          214  +    pTab->pMod = pMod;
          215  +    pTab->pTok = pTok;
          216  +    *ppVtab = &pTab->base;
          217  +  }else{
          218  +    if( pTok ){
          219  +      pMod->xDestroy(pTok);
          220  +    }
          221  +  }
          222  +
          223  +  sqlite3_free(azDequote);
          224  +  return rc;
          225  +}
          226  +
          227  +/*
          228  +** This function does the work for both the xDisconnect and xDestroy methods.
          229  +** These tables have no persistent representation of their own, so xDisconnect
          230  +** and xDestroy are identical operations.
          231  +*/
          232  +static int fts3tokDisconnectMethod(sqlite3_vtab *pVtab){
          233  +  Fts3tokTable *pTab = (Fts3tokTable *)pVtab;
          234  +
          235  +  pTab->pMod->xDestroy(pTab->pTok);
          236  +  sqlite3_free(pTab);
          237  +  return SQLITE_OK;
          238  +}
          239  +
          240  +/*
          241  +** xBestIndex - Analyze a WHERE and ORDER BY clause.
          242  +*/
          243  +static int fts3tokBestIndexMethod(
          244  +  sqlite3_vtab *pVTab, 
          245  +  sqlite3_index_info *pInfo
          246  +){
          247  +  int i;
          248  +  UNUSED_PARAMETER(pVTab);
          249  +
          250  +  for(i=0; i<pInfo->nConstraint; i++){
          251  +    if( pInfo->aConstraint[i].usable 
          252  +     && pInfo->aConstraint[i].iColumn==0 
          253  +     && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ 
          254  +    ){
          255  +      pInfo->idxNum = 1;
          256  +      pInfo->aConstraintUsage[i].argvIndex = 1;
          257  +      pInfo->aConstraintUsage[i].omit = 1;
          258  +      pInfo->estimatedCost = 1;
          259  +      return SQLITE_OK;
          260  +    }
          261  +  }
          262  +
          263  +  pInfo->idxNum = 0;
          264  +  assert( pInfo->estimatedCost>1000000.0 );
          265  +
          266  +  return SQLITE_OK;
          267  +}
          268  +
          269  +/*
          270  +** xOpen - Open a cursor.
          271  +*/
          272  +static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
          273  +  Fts3tokCursor *pCsr;
          274  +  UNUSED_PARAMETER(pVTab);
          275  +
          276  +  pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor));
          277  +  if( pCsr==0 ){
          278  +    return SQLITE_NOMEM;
          279  +  }
          280  +  memset(pCsr, 0, sizeof(Fts3tokCursor));
          281  +
          282  +  *ppCsr = (sqlite3_vtab_cursor *)pCsr;
          283  +  return SQLITE_OK;
          284  +}
          285  +
          286  +/*
          287  +** Reset the tokenizer cursor passed as the only argument. As if it had
          288  +** just been returned by fts3tokOpenMethod().
          289  +*/
          290  +static void fts3tokResetCursor(Fts3tokCursor *pCsr){
          291  +  if( pCsr->pCsr ){
          292  +    Fts3tokTable *pTab = (Fts3tokTable *)(pCsr->base.pVtab);
          293  +    pTab->pMod->xClose(pCsr->pCsr);
          294  +    pCsr->pCsr = 0;
          295  +  }
          296  +  sqlite3_free(pCsr->zInput);
          297  +  pCsr->zInput = 0;
          298  +  pCsr->zToken = 0;
          299  +  pCsr->nToken = 0;
          300  +  pCsr->iStart = 0;
          301  +  pCsr->iEnd = 0;
          302  +  pCsr->iPos = 0;
          303  +  pCsr->iRowid = 0;
          304  +}
          305  +
          306  +/*
          307  +** xClose - Close a cursor.
          308  +*/
          309  +static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){
          310  +  Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
          311  +
          312  +  fts3tokResetCursor(pCsr);
          313  +  sqlite3_free(pCsr);
          314  +  return SQLITE_OK;
          315  +}
          316  +
          317  +/*
          318  +** xNext - Advance the cursor to the next row, if any.
          319  +*/
          320  +static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){
          321  +  Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
          322  +  Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab);
          323  +  int rc;                         /* Return code */
          324  +
          325  +  pCsr->iRowid++;
          326  +  rc = pTab->pMod->xNext(pCsr->pCsr,
          327  +      &pCsr->zToken, &pCsr->nToken,
          328  +      &pCsr->iStart, &pCsr->iEnd, &pCsr->iPos
          329  +  );
          330  +
          331  +  if( rc!=SQLITE_OK ){
          332  +    fts3tokResetCursor(pCsr);
          333  +    if( rc==SQLITE_DONE ) rc = SQLITE_OK;
          334  +  }
          335  +
          336  +  return rc;
          337  +}
          338  +
          339  +/*
          340  +** xFilter - Initialize a cursor to point at the start of its data.
          341  +*/
          342  +static int fts3tokFilterMethod(
          343  +  sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
          344  +  int idxNum,                     /* Strategy index */
          345  +  const char *idxStr,             /* Unused */
          346  +  int nVal,                       /* Number of elements in apVal */
          347  +  sqlite3_value **apVal           /* Arguments for the indexing scheme */
          348  +){
          349  +  int rc = SQLITE_ERROR;
          350  +  Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
          351  +  Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab);
          352  +  UNUSED_PARAMETER(idxStr);
          353  +  UNUSED_PARAMETER(nVal);
          354  +
          355  +  fts3tokResetCursor(pCsr);
          356  +  if( idxNum==1 ){
          357  +    const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
          358  +    int nByte = sqlite3_value_bytes(apVal[0]);
          359  +    pCsr->zInput = sqlite3_malloc(nByte+1);
          360  +    if( pCsr->zInput==0 ){
          361  +      rc = SQLITE_NOMEM;
          362  +    }else{
          363  +      memcpy(pCsr->zInput, zByte, nByte);
          364  +      pCsr->zInput[nByte] = 0;
          365  +      rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr);
          366  +      if( rc==SQLITE_OK ){
          367  +        pCsr->pCsr->pTokenizer = pTab->pTok;
          368  +      }
          369  +    }
          370  +  }
          371  +
          372  +  if( rc!=SQLITE_OK ) return rc;
          373  +  return fts3tokNextMethod(pCursor);
          374  +}
          375  +
          376  +/*
          377  +** xEof - Return true if the cursor is at EOF, or false otherwise.
          378  +*/
          379  +static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){
          380  +  Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
          381  +  return (pCsr->zToken==0);
          382  +}
          383  +
          384  +/*
          385  +** xColumn - Return a column value.
          386  +*/
          387  +static int fts3tokColumnMethod(
          388  +  sqlite3_vtab_cursor *pCursor,   /* Cursor to retrieve value from */
          389  +  sqlite3_context *pCtx,          /* Context for sqlite3_result_xxx() calls */
          390  +  int iCol                        /* Index of column to read value from */
          391  +){
          392  +  Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
          393  +
          394  +  /* CREATE TABLE x(input, token, start, end, position) */
          395  +  switch( iCol ){
          396  +    case 0:
          397  +      sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT);
          398  +      break;
          399  +    case 1:
          400  +      sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT);
          401  +      break;
          402  +    case 2:
          403  +      sqlite3_result_int(pCtx, pCsr->iStart);
          404  +      break;
          405  +    case 3:
          406  +      sqlite3_result_int(pCtx, pCsr->iEnd);
          407  +      break;
          408  +    default:
          409  +      assert( iCol==4 );
          410  +      sqlite3_result_int(pCtx, pCsr->iPos);
          411  +      break;
          412  +  }
          413  +  return SQLITE_OK;
          414  +}
          415  +
          416  +/*
          417  +** xRowid - Return the current rowid for the cursor.
          418  +*/
          419  +static int fts3tokRowidMethod(
          420  +  sqlite3_vtab_cursor *pCursor,   /* Cursor to retrieve value from */
          421  +  sqlite_int64 *pRowid            /* OUT: Rowid value */
          422  +){
          423  +  Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
          424  +  *pRowid = (sqlite3_int64)pCsr->iRowid;
          425  +  return SQLITE_OK;
          426  +}
          427  +
          428  +/*
          429  +** Register the fts3tok module with database connection db. Return SQLITE_OK
          430  +** if successful or an error code if sqlite3_create_module() fails.
          431  +*/
          432  +int sqlite3Fts3InitTok(sqlite3 *db){
          433  +  static const sqlite3_module fts3tok_module = {
          434  +     0,                           /* iVersion      */
          435  +     fts3tokConnectMethod,        /* xCreate       */
          436  +     fts3tokConnectMethod,        /* xConnect      */
          437  +     fts3tokBestIndexMethod,      /* xBestIndex    */
          438  +     fts3tokDisconnectMethod,     /* xDisconnect   */
          439  +     fts3tokDisconnectMethod,     /* xDestroy      */
          440  +     fts3tokOpenMethod,           /* xOpen         */
          441  +     fts3tokCloseMethod,          /* xClose        */
          442  +     fts3tokFilterMethod,         /* xFilter       */
          443  +     fts3tokNextMethod,           /* xNext         */
          444  +     fts3tokEofMethod,            /* xEof          */
          445  +     fts3tokColumnMethod,         /* xColumn       */
          446  +     fts3tokRowidMethod,          /* xRowid        */
          447  +     0,                           /* xUpdate       */
          448  +     0,                           /* xBegin        */
          449  +     0,                           /* xSync         */
          450  +     0,                           /* xCommit       */
          451  +     0,                           /* xRollback     */
          452  +     0,                           /* xFindFunction */
          453  +     0,                           /* xRename       */
          454  +     0,                           /* xSavepoint    */
          455  +     0,                           /* xRelease      */
          456  +     0                            /* xRollbackTo   */
          457  +  };
          458  +  int rc;                         /* Return code */
          459  +
          460  +  rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, 0);
          461  +  return rc;
          462  +}
          463  +
          464  +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/rtree/rtree1.test.

    13     13   #
    14     14   
    15     15   if {![info exists testdir]} {
    16     16     set testdir [file join [file dirname [info script]] .. .. test]
    17     17   }
    18     18   source [file join [file dirname [info script]] rtree_util.tcl]
    19     19   source $testdir/tester.tcl
           20  +set testprefix rtree1
    20     21   
    21     22   # Test plan:
    22     23   #
    23     24   #   rtree-1.*: Creating/destroying r-tree tables.
    24     25   #   rtree-2.*: Test the implicit constraints - unique rowid and
    25     26   #              (coord[N]<=coord[N+1]) for even values of N. Also
    26     27   #              automatic assigning of rowid values.

Changes to ext/rtree/rtree5.test.

    57     57   do_test rtree5-1.9 { 
    58     58     execsql { SELECT count(*) FROM t1 WHERE x1==5.0 }
    59     59   } {1}
    60     60   
    61     61   do_test rtree5-1.10 { 
    62     62     execsql { SELECT (1<<31)-5, (1<<31)-1, -1*(1<<31), -1*(1<<31)+5 }
    63     63   } {2147483643 2147483647 -2147483648 -2147483643}
    64         -do_test rtree5-1.10 { 
           64  +do_test rtree5-1.11 { 
    65     65     execsql { 
    66     66       INSERT INTO t1 VALUES(2, (1<<31)-5, (1<<31)-1, -1*(1<<31), -1*(1<<31)+5) 
    67     67     }
    68     68   } {}
    69     69   do_test rtree5-1.12 { 
    70     70     execsql { SELECT * FROM t1 WHERE id=2 }
    71     71   } {2 2147483643 2147483647 -2147483648 -2147483643}

Changes to main.mk.

    52     52   # Object files for the SQLite library.
    53     53   #
    54     54   LIBOBJ+= alter.o analyze.o attach.o auth.o \
    55     55            backup.o bitvec.o btmutex.o btree.o build.o \
    56     56            callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
    57     57            fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
    58     58            fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
           59  +         fts3_tokenize_vtab.o \
    59     60   	 fts3_unicode.o fts3_unicode2.o \
    60     61            fts3_write.o func.o global.o hash.o \
    61     62            icu.o insert.o journal.o legacy.o loadext.o \
    62     63            main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
    63     64            memjournal.o \
    64     65            mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
    65     66            notify.o opcodes.o os.o os_unix.o os_win.o \
................................................................................
   194    195     $(TOP)/ext/fts3/fts3_hash.h \
   195    196     $(TOP)/ext/fts3/fts3_icu.c \
   196    197     $(TOP)/ext/fts3/fts3_porter.c \
   197    198     $(TOP)/ext/fts3/fts3_snippet.c \
   198    199     $(TOP)/ext/fts3/fts3_tokenizer.h \
   199    200     $(TOP)/ext/fts3/fts3_tokenizer.c \
   200    201     $(TOP)/ext/fts3/fts3_tokenizer1.c \
          202  +  $(TOP)/ext/fts3/fts3_tokenize_vtab.c \
   201    203     $(TOP)/ext/fts3/fts3_unicode.c \
   202    204     $(TOP)/ext/fts3/fts3_unicode2.c \
   203    205     $(TOP)/ext/fts3/fts3_write.c
   204    206   SRC += \
   205    207     $(TOP)/ext/icu/sqliteicu.h \
   206    208     $(TOP)/ext/icu/icu.c
   207    209   SRC += \
................................................................................
   367    369   	$(RANLIB) libsqlite3.a
   368    370   
   369    371   sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
   370    372   	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE)                  \
   371    373   		$(TOP)/src/shell.c                                  \
   372    374   		libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
   373    375   
          376  +mptester$(EXE):	sqlite3.c $(TOP)/mptest/mptest.c
          377  +	$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
          378  +		$(TLIBS) $(THREADLIB)
          379  +
   374    380   sqlite3.o:	sqlite3.c
   375    381   	$(TCCX) -c sqlite3.c
   376    382   
   377    383   # This target creates a directory named "tsrc" and fills it with
   378    384   # copies of all of the C source code and header files needed to
   379    385   # build on the target system.  Some of the C source code and header
   380    386   # files are automatically generated.  This target takes care of
................................................................................
   514    520   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
   515    521   
   516    522   fts3_tokenizer.o:	$(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
   517    523   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
   518    524   
   519    525   fts3_tokenizer1.o:	$(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
   520    526   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
          527  +
          528  +fts3_tokenize_vtab.o:	$(TOP)/ext/fts3/fts3_tokenize_vtab.c $(HDR) $(EXTHDR)
          529  +	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenize_vtab.c
   521    530   
   522    531   fts3_unicode.o:	$(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR)
   523    532   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c
   524    533   
   525    534   fts3_unicode2.o:	$(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
   526    535   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c
   527    536   
................................................................................
   629    638   	rm -rf tsrc target_source
   630    639   	rm -f testloadext.dll libtestloadext.so
   631    640   	rm -f amalgamation-testfixture amalgamation-testfixture.exe
   632    641   	rm -f fts3-testfixture fts3-testfixture.exe
   633    642   	rm -f testfixture testfixture.exe
   634    643   	rm -f threadtest3 threadtest3.exe
   635    644   	rm -f sqlite3.c fts?amal.c tclsqlite3.c
          645  +	rm -f sqlite3rc.h
          646  +	rm -f shell.c sqlite3ext.h
   636    647   	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
   637    648   	rm -f sqlite-*-output.vsix
          649  +	rm -f mptester mptester.exe

Added mptest/config01.test.

            1  +/*
            2  +** Configure five tasks in different ways, then run tests.
            3  +*/
            4  +--if vfsname() GLOB 'unix'
            5  +PRAGMA page_size=8192;
            6  +--task 1
            7  +  PRAGMA journal_mode=PERSIST;
            8  +  PRAGMA mmap_size=0;
            9  +--end
           10  +--task 2
           11  +  PRAGMA journal_mode=TRUNCATE;
           12  +  PRAGMA mmap_size=28672;
           13  +--end
           14  +--task 3
           15  +  PRAGMA journal_mode=MEMORY;
           16  +--end
           17  +--task 4
           18  +  PRAGMA journal_mode=OFF;
           19  +--end
           20  +--task 4
           21  +  PRAGMA mmap_size(268435456);
           22  +--end
           23  +--source multiwrite01.test
           24  +--wait all
           25  +PRAGMA page_size=16384;
           26  +VACUUM;
           27  +CREATE TABLE pgsz(taskid, sz INTEGER);
           28  +--task 1
           29  +  INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
           30  +--end
           31  +--task 2
           32  +  INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
           33  +--end
           34  +--task 3
           35  +  INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
           36  +--end
           37  +--task 4
           38  +  INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
           39  +--end
           40  +--task 5
           41  +  INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
           42  +--end
           43  +--source multiwrite01.test
           44  +--wait all
           45  +SELECT sz FROM pgsz;
           46  +--match 16384 16384 16384 16384 16384

Added mptest/config02.test.

            1  +/*
            2  +** Configure five tasks in different ways, then run tests.
            3  +*/
            4  +PRAGMA page_size=512;
            5  +--task 1
            6  +  PRAGMA mmap_size=0;
            7  +--end
            8  +--task 2
            9  +  PRAGMA mmap_size=28672;
           10  +--end
           11  +--task 3
           12  +  PRAGMA mmap_size=8192;
           13  +--end
           14  +--task 4
           15  +  PRAGMA mmap_size=65536;
           16  +--end
           17  +--task 5
           18  +  PRAGMA mmap_size=268435456;
           19  +--end
           20  +--source multiwrite01.test
           21  +--source crash02.subtest
           22  +PRAGMA page_size=1024;
           23  +VACUUM;
           24  +CREATE TABLE pgsz(taskid, sz INTEGER);
           25  +--task 1
           26  +  INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
           27  +--end
           28  +--task 2
           29  +  INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
           30  +--end
           31  +--task 3
           32  +  INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
           33  +--end
           34  +--task 4
           35  +  INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
           36  +--end
           37  +--task 5
           38  +  INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
           39  +--end
           40  +--source multiwrite01.test
           41  +--source crash02.subtest
           42  +--wait all
           43  +SELECT sz FROM pgsz;
           44  +--match 1024 1024 1024 1024 1024
           45  +PRAGMA page_size=2048;
           46  +VACUUM;
           47  +DELETE FROM pgsz;
           48  +--task 1
           49  +  INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
           50  +--end
           51  +--task 2
           52  +  INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
           53  +--end
           54  +--task 3
           55  +  INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
           56  +--end
           57  +--task 4
           58  +  INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
           59  +--end
           60  +--task 5
           61  +  INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
           62  +--end
           63  +--source multiwrite01.test
           64  +--source crash02.subtest
           65  +--wait all
           66  +SELECT sz FROM pgsz;
           67  +--match 2048 2048 2048 2048 2048
           68  +PRAGMA page_size=8192;
           69  +VACUUM;
           70  +DELETE FROM pgsz;
           71  +--task 1
           72  +  INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
           73  +--end
           74  +--task 2
           75  +  INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
           76  +--end
           77  +--task 3
           78  +  INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
           79  +--end
           80  +--task 4
           81  +  INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
           82  +--end
           83  +--task 5
           84  +  INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
           85  +--end
           86  +--source multiwrite01.test
           87  +--source crash02.subtest
           88  +--wait all
           89  +SELECT sz FROM pgsz;
           90  +--match 8192 8192 8192 8192 8192
           91  +PRAGMA page_size=16384;
           92  +VACUUM;
           93  +DELETE FROM pgsz;
           94  +--task 1
           95  +  INSERT INTO pgsz VALUES(1, eval('PRAGMA page_size'));
           96  +--end
           97  +--task 2
           98  +  INSERT INTO pgsz VALUES(2, eval('PRAGMA page_size'));
           99  +--end
          100  +--task 3
          101  +  INSERT INTO pgsz VALUES(3, eval('PRAGMA page_size'));
          102  +--end
          103  +--task 4
          104  +  INSERT INTO pgsz VALUES(4, eval('PRAGMA page_size'));
          105  +--end
          106  +--task 5
          107  +  INSERT INTO pgsz VALUES(5, eval('PRAGMA page_size'));
          108  +--end
          109  +--source multiwrite01.test
          110  +--source crash02.subtest
          111  +--wait all
          112  +SELECT sz FROM pgsz;
          113  +--match 16384 16384 16384 16384 16384
          114  +PRAGMA auto_vacuum=FULL;
          115  +VACUUM;
          116  +--source multiwrite01.test
          117  +--source crash02.subtest
          118  +--wait all
          119  +PRAGMA auto_vacuum=FULL;
          120  +PRAGMA page_size=512;
          121  +VACUUM;
          122  +--source multiwrite01.test
          123  +--source crash02.subtest

Added mptest/crash01.test.

            1  +/* Test cases involving incomplete transactions that must be rolled back.
            2  +*/
            3  +--task 1
            4  +  DROP TABLE IF EXISTS t1;
            5  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
            6  +  --sleep 1
            7  +  INSERT INTO t1 VALUES(1, randomblob(2000));
            8  +  INSERT INTO t1 VALUES(2, randomblob(1000));
            9  +  --sleep 1
           10  +  INSERT INTO t1 SELECT a+2, randomblob(1500) FROM t1;
           11  +  INSERT INTO t1 SELECT a+4, randomblob(1500) FROM t1;
           12  +  INSERT INTO t1 SELECT a+8, randomblob(1500) FROM t1;
           13  +  --sleep 1
           14  +  INSERT INTO t1 SELECT a+16, randomblob(1500) FROM t1;
           15  +  --sleep 1
           16  +  INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1;
           17  +  SELECT count(*) FROM t1;
           18  +  --match 64
           19  +  SELECT avg(length(b)) FROM t1;
           20  +  --match 1500.0
           21  +  --sleep 2
           22  +  UPDATE t1 SET b='x'||a||'y';
           23  +  SELECT total(length(b)) FROM t1;
           24  +  --match 247
           25  +  SELECT a FROM t1 WHERE b='x17y';
           26  +  --match 17
           27  +  CREATE INDEX t1b ON t1(b);
           28  +  SELECT a FROM t1 WHERE b='x17y';
           29  +  --match 17
           30  +  SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           31  +  --match 29 28 27 26 25
           32  +--end
           33  +--wait 1
           34  +--task 2
           35  +  CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
           36  +  INSERT INTO t2 SELECT a, b FROM t1;
           37  +  UPDATE t1 SET b='x'||a||'y';
           38  +  SELECT total(length(b)) FROM t2;
           39  +  --match 247
           40  +  SELECT a FROM t2 WHERE b='x17y';
           41  +  --match 17
           42  +  CREATE INDEX t2b ON t2(b);
           43  +  SELECT a FROM t2 WHERE b='x17y';
           44  +  --match 17
           45  +  SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           46  +  --match 29 28 27 26 25
           47  +--end
           48  +--task 3
           49  +  CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
           50  +  INSERT INTO t3 SELECT a, b FROM t1;
           51  +  UPDATE t1 SET b='x'||a||'y';
           52  +  SELECT total(length(b)) FROM t3;
           53  +  --match 247
           54  +  SELECT a FROM t3 WHERE b='x17y';
           55  +  --match 17
           56  +  CREATE INDEX t3b ON t3(b);
           57  +  SELECT a FROM t3 WHERE b='x17y';
           58  +  --match 17
           59  +  SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           60  +  --match 29 28 27 26 25
           61  +--end
           62  +--task 4
           63  +  CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
           64  +  INSERT INTO t4 SELECT a, b FROM t1;
           65  +  UPDATE t1 SET b='x'||a||'y';
           66  +  SELECT total(length(b)) FROM t4;
           67  +  --match 247
           68  +  SELECT a FROM t4 WHERE b='x17y';
           69  +  --match 17
           70  +  CREATE INDEX t4b ON t4(b);
           71  +  SELECT a FROM t4 WHERE b='x17y';
           72  +  --match 17
           73  +  SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           74  +  --match 29 28 27 26 25
           75  +--end
           76  +--task 5
           77  +  CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
           78  +  INSERT INTO t5 SELECT a, b FROM t1;
           79  +  UPDATE t1 SET b='x'||a||'y';
           80  +  SELECT total(length(b)) FROM t5;
           81  +  --match 247
           82  +  SELECT a FROM t5 WHERE b='x17y';
           83  +  --match 17
           84  +  CREATE INDEX t5b ON t5(b);
           85  +  SELECT a FROM t5 WHERE b='x17y';
           86  +  --match 17
           87  +  SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           88  +  --match 29 28 27 26 25
           89  +--end
           90  +
           91  +--wait all
           92  +/* After the database file has been set up, run the crash2 subscript
           93  +** multiple times. */
           94  +--source crash02.subtest
           95  +--source crash02.subtest
           96  +--source crash02.subtest
           97  +--source crash02.subtest
           98  +--source crash02.subtest
           99  +--source crash02.subtest
          100  +--source crash02.subtest
          101  +--source crash02.subtest
          102  +--source crash02.subtest

Added mptest/crash02.subtest.

            1  +/*
            2  +** This script is called from crash01.test and config02.test and perhaps other
            3  +** script.  After the database file has been set up, make a big rollback 
            4  +** journal in client 1, then crash client 1.
            5  +** Then in the other clients, do an integrity check.
            6  +*/
            7  +--task 1 leave-hot-journal
            8  +  --sleep 5
            9  +  --finish
           10  +  PRAGMA cache_size=10;
           11  +  BEGIN;
           12  +  UPDATE t1 SET b=randomblob(20000);
           13  +  UPDATE t2 SET b=randomblob(20000);
           14  +  UPDATE t3 SET b=randomblob(20000);
           15  +  UPDATE t4 SET b=randomblob(20000);
           16  +  UPDATE t5 SET b=randomblob(20000);
           17  +  UPDATE t1 SET b=NULL;
           18  +  UPDATE t2 SET b=NULL;
           19  +  UPDATE t3 SET b=NULL;
           20  +  UPDATE t4 SET b=NULL;
           21  +  UPDATE t5 SET b=NULL;
           22  +  --print Task one crashing an incomplete transaction
           23  +  --exit 1
           24  +--end
           25  +--task 2 integrity_check-2
           26  +  SELECT count(*) FROM t1;
           27  +  --match 64
           28  +  --sleep 100
           29  +  PRAGMA integrity_check(10);
           30  +  --match ok
           31  +--end
           32  +--task 3 integrity_check-3
           33  +  SELECT count(*) FROM t1;
           34  +  --match 64
           35  +  --sleep 100
           36  +  PRAGMA integrity_check(10);
           37  +  --match ok
           38  +--end
           39  +--task 4 integrity_check-4
           40  +  SELECT count(*) FROM t1;
           41  +  --match 64
           42  +  --sleep 100
           43  +  PRAGMA integrity_check(10);
           44  +  --match ok
           45  +--end
           46  +--task 5 integrity_check-5
           47  +  SELECT count(*) FROM t1;
           48  +  --match 64
           49  +  --sleep 100
           50  +  PRAGMA integrity_check(10);
           51  +  --match ok
           52  +--end
           53  +--wait all

Added mptest/mptest.c.

            1  +/*
            2  +** 2013-04-05
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +** 
           13  +** This is a program used for testing SQLite, and specifically for testing
           14  +** the ability of independent processes to access the same SQLite database
           15  +** concurrently.
           16  +**
           17  +** Compile this program as follows:
           18  +**
           19  +**    gcc -g -c -Wall sqlite3.c $(OPTS)
           20  +**    gcc -g -o mptest mptest.c sqlite3.o $(LIBS)
           21  +**
           22  +** Recommended options:
           23  +**
           24  +**    -DHAVE_USLEEP
           25  +**    -DSQLITE_NO_SYNC
           26  +**    -DSQLITE_THREADSAFE=0
           27  +**    -DSQLITE_OMIT_LOAD_EXTENSION
           28  +**
           29  +** Run like this:
           30  +**
           31  +**     ./mptest $database $script
           32  +**
           33  +** where $database is the database to use for testing and $script is a
           34  +** test script.
           35  +*/
           36  +#include "sqlite3.h"
           37  +#include <stdio.h>
           38  +#if defined(_WIN32)
           39  +# define WIN32_LEAN_AND_MEAN
           40  +# include <windows.h>
           41  +#else
           42  +# include <unistd.h>
           43  +#endif
           44  +#include <stdlib.h>
           45  +#include <string.h>
           46  +#include <assert.h>
           47  +#include <ctype.h>
           48  +
           49  +/* The suffix to append to the child command lines, if any */
           50  +#if defined(_WIN32)
           51  +# define GETPID (int)GetCurrentProcessId
           52  +#else
           53  +# define GETPID getpid
           54  +#endif
           55  +
           56  +/* Mark a parameter as unused to suppress compiler warnings */
           57  +#define UNUSED_PARAMETER(x)  (void)x
           58  +
           59  +/* Global data
           60  +*/
           61  +static struct Global {
           62  +  char *argv0;           /* Name of the executable */
           63  +  const char *zVfs;      /* Name of VFS to use. Often NULL meaning "default" */
           64  +  char *zDbFile;         /* Name of the database */
           65  +  sqlite3 *db;           /* Open connection to database */
           66  +  char *zErrLog;         /* Filename for error log */
           67  +  FILE *pErrLog;         /* Where to write errors */
           68  +  char *zLog;            /* Name of output log file */
           69  +  FILE *pLog;            /* Where to write log messages */
           70  +  char zName[32];        /* Symbolic name of this process */
           71  +  int taskId;            /* Task ID.  0 means supervisor. */
           72  +  int iTrace;            /* Tracing level */
           73  +  int bSqlTrace;         /* True to trace SQL commands */
           74  +  int bIgnoreSqlErrors;  /* Ignore errors in SQL statements */
           75  +  int nError;            /* Number of errors */
           76  +  int nTest;             /* Number of --match operators */
           77  +  int iTimeout;          /* Milliseconds until a busy timeout */
           78  +  int bSync;             /* Call fsync() */
           79  +} g;
           80  +
           81  +/* Default timeout */
           82  +#define DEFAULT_TIMEOUT 10000
           83  +
           84  +/*
           85  +** Print a message adding zPrefix[] to the beginning of every line.
           86  +*/
           87  +static void printWithPrefix(FILE *pOut, const char *zPrefix, const char *zMsg){
           88  +  while( zMsg && zMsg[0] ){
           89  +    int i;
           90  +    for(i=0; zMsg[i] && zMsg[i]!='\n' && zMsg[i]!='\r'; i++){}
           91  +    fprintf(pOut, "%s%.*s\n", zPrefix, i, zMsg);
           92  +    zMsg += i;
           93  +    while( zMsg[0]=='\n' || zMsg[0]=='\r' ) zMsg++;
           94  +  }
           95  +}
           96  +
           97  +/*
           98  +** Compare two pointers to strings, where the pointers might be NULL.
           99  +*/
          100  +static int safe_strcmp(const char *a, const char *b){
          101  +  if( a==b ) return 0;
          102  +  if( a==0 ) return -1;
          103  +  if( b==0 ) return 1;
          104  +  return strcmp(a,b);
          105  +}
          106  +
          107  +/*
          108  +** Return TRUE if string z[] matches glob pattern zGlob[].
          109  +** Return FALSE if the pattern does not match.
          110  +**
          111  +** Globbing rules:
          112  +**
          113  +**      '*'       Matches any sequence of zero or more characters.
          114  +**
          115  +**      '?'       Matches exactly one character.
          116  +**
          117  +**     [...]      Matches one character from the enclosed list of
          118  +**                characters.
          119  +**
          120  +**     [^...]     Matches one character not in the enclosed list.
          121  +**
          122  +**      '#'       Matches any sequence of one or more digits with an
          123  +**                optional + or - sign in front
          124  +*/
          125  +int strglob(const char *zGlob, const char *z){
          126  +  int c, c2;
          127  +  int invert;
          128  +  int seen;
          129  +
          130  +  while( (c = (*(zGlob++)))!=0 ){
          131  +    if( c=='*' ){
          132  +      while( (c=(*(zGlob++))) == '*' || c=='?' ){
          133  +        if( c=='?' && (*(z++))==0 ) return 0;
          134  +      }
          135  +      if( c==0 ){
          136  +        return 1;
          137  +      }else if( c=='[' ){
          138  +        while( *z && strglob(zGlob-1,z) ){
          139  +          z++;
          140  +        }
          141  +        return (*z)!=0;
          142  +      }
          143  +      while( (c2 = (*(z++)))!=0 ){
          144  +        while( c2!=c ){
          145  +          c2 = *(z++);
          146  +          if( c2==0 ) return 0;
          147  +        }
          148  +        if( strglob(zGlob,z) ) return 1;
          149  +      }
          150  +      return 0;
          151  +    }else if( c=='?' ){
          152  +      if( (*(z++))==0 ) return 0;
          153  +    }else if( c=='[' ){
          154  +      int prior_c = 0;
          155  +      seen = 0;
          156  +      invert = 0;
          157  +      c = *(z++);
          158  +      if( c==0 ) return 0;
          159  +      c2 = *(zGlob++);
          160  +      if( c2=='^' ){
          161  +        invert = 1;
          162  +        c2 = *(zGlob++);
          163  +      }
          164  +      if( c2==']' ){
          165  +        if( c==']' ) seen = 1;
          166  +        c2 = *(zGlob++);
          167  +      }
          168  +      while( c2 && c2!=']' ){
          169  +        if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
          170  +          c2 = *(zGlob++);
          171  +          if( c>=prior_c && c<=c2 ) seen = 1;
          172  +          prior_c = 0;
          173  +        }else{
          174  +          if( c==c2 ){
          175  +            seen = 1;
          176  +          }
          177  +          prior_c = c2;
          178  +        }
          179  +        c2 = *(zGlob++);
          180  +      }
          181  +      if( c2==0 || (seen ^ invert)==0 ) return 0;
          182  +    }else if( c=='#' ){
          183  +      if( (z[0]=='-' || z[0]=='+') && isdigit(z[1]) ) z++;
          184  +      if( !isdigit(z[0]) ) return 0;
          185  +      z++;
          186  +      while( isdigit(z[0]) ){ z++; }
          187  +    }else{
          188  +      if( c!=(*(z++)) ) return 0;
          189  +    }
          190  +  }
          191  +  return *z==0;
          192  +}
          193  +
          194  +/*
          195  +** Close output stream pOut if it is not stdout or stderr
          196  +*/
          197  +static void maybeClose(FILE *pOut){
          198  +  if( pOut!=stdout && pOut!=stderr ) fclose(pOut);
          199  +}
          200  +
          201  +/*
          202  +** Print an error message
          203  +*/
          204  +static void errorMessage(const char *zFormat, ...){
          205  +  va_list ap;
          206  +  char *zMsg;
          207  +  char zPrefix[30];
          208  +  va_start(ap, zFormat);
          209  +  zMsg = sqlite3_vmprintf(zFormat, ap);
          210  +  va_end(ap);
          211  +  sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:ERROR: ", g.zName);
          212  +  if( g.pLog ){
          213  +    printWithPrefix(g.pLog, zPrefix, zMsg);
          214  +    fflush(g.pLog);
          215  +  }
          216  +  if( g.pErrLog && safe_strcmp(g.zErrLog,g.zLog) ){
          217  +    printWithPrefix(g.pErrLog, zPrefix, zMsg);
          218  +    fflush(g.pErrLog);
          219  +  }
          220  +  sqlite3_free(zMsg);
          221  +  g.nError++;
          222  +}
          223  +
          224  +/* Forward declaration */
          225  +static int trySql(const char*, ...);
          226  +
          227  +/*
          228  +** Print an error message and then quit.
          229  +*/
          230  +static void fatalError(const char *zFormat, ...){
          231  +  va_list ap;
          232  +  char *zMsg;
          233  +  char zPrefix[30];
          234  +  va_start(ap, zFormat);
          235  +  zMsg = sqlite3_vmprintf(zFormat, ap);
          236  +  va_end(ap);
          237  +  sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:FATAL: ", g.zName);
          238  +  if( g.pLog ){
          239  +    printWithPrefix(g.pLog, zPrefix, zMsg);
          240  +    fflush(g.pLog);
          241  +    maybeClose(g.pLog);
          242  +  }
          243  +  if( g.pErrLog && safe_strcmp(g.zErrLog,g.zLog) ){
          244  +    printWithPrefix(g.pErrLog, zPrefix, zMsg);
          245  +    fflush(g.pErrLog);
          246  +    maybeClose(g.pErrLog);
          247  +  }
          248  +  sqlite3_free(zMsg);
          249  +  if( g.db ){
          250  +    int nTry = 0;
          251  +    g.iTimeout = 0;
          252  +    while( trySql("UPDATE client SET wantHalt=1;")==SQLITE_BUSY
          253  +           && (nTry++)<100 ){
          254  +      sqlite3_sleep(10);
          255  +    }
          256  +  }
          257  +  sqlite3_close(g.db);
          258  +  exit(1);  
          259  +}
          260  +
          261  +
          262  +/*
          263  +** Print a log message
          264  +*/
          265  +static void logMessage(const char *zFormat, ...){
          266  +  va_list ap;
          267  +  char *zMsg;
          268  +  char zPrefix[30];
          269  +  va_start(ap, zFormat);
          270  +  zMsg = sqlite3_vmprintf(zFormat, ap);
          271  +  va_end(ap);
          272  +  sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s: ", g.zName);
          273  +  if( g.pLog ){
          274  +    printWithPrefix(g.pLog, zPrefix, zMsg);
          275  +    fflush(g.pLog);
          276  +  }
          277  +  sqlite3_free(zMsg);
          278  +}
          279  +
          280  +/*
          281  +** Return the length of a string omitting trailing whitespace
          282  +*/
          283  +static int clipLength(const char *z){
          284  +  int n = (int)strlen(z);
          285  +  while( n>0 && isspace(z[n-1]) ){ n--; }
          286  +  return n;
          287  +}
          288  +
          289  +/*
          290  +** Auxiliary SQL function to return the name of the VFS
          291  +*/
          292  +static void vfsNameFunc(
          293  +  sqlite3_context *context,
          294  +  int argc,
          295  +  sqlite3_value **argv
          296  +){
          297  +  sqlite3 *db = sqlite3_context_db_handle(context);
          298  +  char *zVfs = 0;
          299  +  UNUSED_PARAMETER(argc);
          300  +  UNUSED_PARAMETER(argv);
          301  +  sqlite3_file_control(db, "main", SQLITE_FCNTL_VFSNAME, &zVfs);
          302  +  if( zVfs ){
          303  +    sqlite3_result_text(context, zVfs, -1, sqlite3_free);
          304  +  }
          305  +}
          306  +
          307  +/*
          308  +** Busy handler with a g.iTimeout-millisecond timeout
          309  +*/
          310  +static int busyHandler(void *pCD, int count){
          311  +  UNUSED_PARAMETER(pCD);
          312  +  if( count*10>g.iTimeout ){
          313  +    if( g.iTimeout>0 ) errorMessage("timeout after %dms", g.iTimeout);
          314  +    return 0;
          315  +  }
          316  +  sqlite3_sleep(10);
          317  +  return 1;
          318  +}
          319  +
          320  +/*
          321  +** SQL Trace callback
          322  +*/
          323  +static void sqlTraceCallback(void *NotUsed1, const char *zSql){
          324  +  UNUSED_PARAMETER(NotUsed1);
          325  +  logMessage("[%.*s]", clipLength(zSql), zSql);
          326  +}
          327  +
          328  +/*
          329  +** SQL error log callback
          330  +*/
          331  +static void sqlErrorCallback(void *pArg, int iErrCode, const char *zMsg){
          332  +  UNUSED_PARAMETER(pArg);
          333  +  if( iErrCode==SQLITE_ERROR && g.bIgnoreSqlErrors ) return;
          334  +  if( (iErrCode&0xff)==SQLITE_SCHEMA && g.iTrace<3 ) return;
          335  +  if( g.iTimeout==0 && (iErrCode&0xff)==SQLITE_BUSY && g.iTrace<3 ) return;
          336  +  if( (iErrCode&0xff)==SQLITE_NOTICE ){
          337  +    logMessage("(info) %s", zMsg);
          338  +  }else{
          339  +    errorMessage("(errcode=%d) %s", iErrCode, zMsg);
          340  +  }
          341  +}
          342  +
          343  +/*
          344  +** Prepare an SQL statement.  Issue a fatal error if unable.
          345  +*/
          346  +static sqlite3_stmt *prepareSql(const char *zFormat, ...){
          347  +  va_list ap;
          348  +  char *zSql;
          349  +  int rc;
          350  +  sqlite3_stmt *pStmt = 0;
          351  +  va_start(ap, zFormat);
          352  +  zSql = sqlite3_vmprintf(zFormat, ap);
          353  +  va_end(ap);
          354  +  rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
          355  +  if( rc!=SQLITE_OK ){
          356  +    sqlite3_finalize(pStmt);
          357  +    fatalError("%s\n%s\n", sqlite3_errmsg(g.db), zSql);
          358  +  }
          359  +  sqlite3_free(zSql);
          360  +  return pStmt;
          361  +}
          362  +
          363  +/*
          364  +** Run arbitrary SQL.  Issue a fatal error on failure.
          365  +*/
          366  +static void runSql(const char *zFormat, ...){
          367  +  va_list ap;
          368  +  char *zSql;
          369  +  int rc;
          370  +  va_start(ap, zFormat);
          371  +  zSql = sqlite3_vmprintf(zFormat, ap);
          372  +  va_end(ap);
          373  +  rc = sqlite3_exec(g.db, zSql, 0, 0, 0);
          374  +  if( rc!=SQLITE_OK ){
          375  +    fatalError("%s\n%s\n", sqlite3_errmsg(g.db), zSql);
          376  +  }
          377  +  sqlite3_free(zSql);
          378  +}
          379  +
          380  +/*
          381  +** Try to run arbitrary SQL.  Return success code.
          382  +*/
          383  +static int trySql(const char *zFormat, ...){
          384  +  va_list ap;
          385  +  char *zSql;
          386  +  int rc;
          387  +  va_start(ap, zFormat);
          388  +  zSql = sqlite3_vmprintf(zFormat, ap);
          389  +  va_end(ap);
          390  +  rc = sqlite3_exec(g.db, zSql, 0, 0, 0);
          391  +  sqlite3_free(zSql);
          392  +  return rc;
          393  +}
          394  +
          395  +/* Structure for holding an arbitrary length string
          396  +*/
          397  +typedef struct String String;
          398  +struct String {
          399  +  char *z;         /* the string */
          400  +  int n;           /* Slots of z[] used */
          401  +  int nAlloc;      /* Slots of z[] allocated */
          402  +};
          403  +
          404  +/* Free a string */
          405  +static void stringFree(String *p){
          406  +  if( p->z ) sqlite3_free(p->z);
          407  +  memset(p, 0, sizeof(*p));
          408  +}
          409  +
          410  +/* Append n bytes of text to a string.  If n<0 append the entire string. */
          411  +static void stringAppend(String *p, const char *z, int n){
          412  +  if( n<0 ) n = (int)strlen(z);
          413  +  if( p->n+n>=p->nAlloc ){
          414  +    int nAlloc = p->nAlloc*2 + n + 100;
          415  +    char *z = sqlite3_realloc(p->z, nAlloc);
          416  +    if( z==0 ) fatalError("out of memory");
          417  +    p->z = z;
          418  +    p->nAlloc = nAlloc;
          419  +  }
          420  +  memcpy(p->z+p->n, z, n);
          421  +  p->n += n;
          422  +  p->z[p->n] = 0;
          423  +}
          424  +
          425  +/* Reset a string to an empty string */
          426  +static void stringReset(String *p){
          427  +  if( p->z==0 ) stringAppend(p, " ", 1);
          428  +  p->n = 0;
          429  +  p->z[0] = 0;
          430  +}
          431  +
          432  +/* Append a new token onto the end of the string */
          433  +static void stringAppendTerm(String *p, const char *z){
          434  +  int i;
          435  +  if( p->n ) stringAppend(p, " ", 1);
          436  +  if( z==0 ){
          437  +    stringAppend(p, "nil", 3);
          438  +    return;
          439  +  }
          440  +  for(i=0; z[i] && !isspace(z[i]); i++){}
          441  +  if( i>0 && z[i]==0 ){
          442  +    stringAppend(p, z, i);
          443  +    return;
          444  +  }
          445  +  stringAppend(p, "'", 1);
          446  +  while( z[0] ){
          447  +    for(i=0; z[i] && z[i]!='\''; i++){}
          448  +    if( z[i] ){
          449  +      stringAppend(p, z, i+1);
          450  +      stringAppend(p, "'", 1);
          451  +      z += i+1;
          452  +    }else{
          453  +      stringAppend(p, z, i);
          454  +      break;
          455  +    }
          456  +  }
          457  +  stringAppend(p, "'", 1);
          458  +}
          459  +
          460  +/*
          461  +** Callback function for evalSql()
          462  +*/
          463  +static int evalCallback(void *pCData, int argc, char **argv, char **azCol){
          464  +  String *p = (String*)pCData;
          465  +  int i;
          466  +  UNUSED_PARAMETER(azCol);
          467  +  for(i=0; i<argc; i++) stringAppendTerm(p, argv[i]);
          468  +  return 0;
          469  +}
          470  +
          471  +/*
          472  +** Run arbitrary SQL and record the results in an output string
          473  +** given by the first parameter.
          474  +*/
          475  +static int evalSql(String *p, const char *zFormat, ...){
          476  +  va_list ap;
          477  +  char *zSql;
          478  +  int rc;
          479  +  char *zErrMsg = 0;
          480  +  va_start(ap, zFormat);
          481  +  zSql = sqlite3_vmprintf(zFormat, ap);
          482  +  va_end(ap);
          483  +  assert( g.iTimeout>0 );
          484  +  rc = sqlite3_exec(g.db, zSql, evalCallback, p, &zErrMsg);
          485  +  sqlite3_free(zSql);
          486  +  if( rc ){
          487  +    char zErr[30];
          488  +    sqlite3_snprintf(sizeof(zErr), zErr, "error(%d)", rc);
          489  +    stringAppendTerm(p, zErr);
          490  +    if( zErrMsg ){
          491  +      stringAppendTerm(p, zErrMsg);
          492  +      sqlite3_free(zErrMsg);
          493  +    }
          494  +  }
          495  +  return rc;
          496  +}
          497  +
          498  +/*
          499  +** Auxiliary SQL function to recursively evaluate SQL.
          500  +*/
          501  +static void evalFunc(
          502  +  sqlite3_context *context,
          503  +  int argc,
          504  +  sqlite3_value **argv
          505  +){
          506  +  sqlite3 *db = sqlite3_context_db_handle(context);
          507  +  const char *zSql = (const char*)sqlite3_value_text(argv[0]);
          508  +  String res;
          509  +  char *zErrMsg = 0;
          510  +  int rc;
          511  +  UNUSED_PARAMETER(argc);
          512  +  memset(&res, 0, sizeof(res));
          513  +  rc = sqlite3_exec(db, zSql, evalCallback, &res, &zErrMsg);
          514  +  if( zErrMsg ){
          515  +    sqlite3_result_error(context, zErrMsg, -1);
          516  +    sqlite3_free(zErrMsg);
          517  +  }else if( rc ){
          518  +    sqlite3_result_error_code(context, rc);
          519  +  }else{
          520  +    sqlite3_result_text(context, res.z, -1, SQLITE_TRANSIENT);
          521  +  }
          522  +  stringFree(&res);
          523  +}
          524  +
          525  +/*
          526  +** Look up the next task for client iClient in the database.
          527  +** Return the task script and the task number and mark that
          528  +** task as being under way.
          529  +*/
          530  +static int startScript(
          531  +  int iClient,              /* The client number */
          532  +  char **pzScript,          /* Write task script here */
          533  +  int *pTaskId,             /* Write task number here */
          534  +  char **pzTaskName         /* Name of the task */
          535  +){
          536  +  sqlite3_stmt *pStmt = 0;
          537  +  int taskId;
          538  +  int rc;
          539  +  int totalTime = 0;
          540  +
          541  +  *pzScript = 0;
          542  +  g.iTimeout = 0;
          543  +  while(1){
          544  +    rc = trySql("BEGIN IMMEDIATE");
          545  +    if( rc==SQLITE_BUSY ){
          546  +      sqlite3_sleep(10);
          547  +      totalTime += 10;
          548  +      continue;
          549  +    }
          550  +    if( rc!=SQLITE_OK ){
          551  +      fatalError("in startScript: %s", sqlite3_errmsg(g.db));
          552  +    }
          553  +    if( g.nError || g.nTest ){
          554  +      runSql("UPDATE counters SET nError=nError+%d, nTest=nTest+%d",
          555  +             g.nError, g.nTest);
          556  +      g.nError = 0;
          557  +      g.nTest = 0;
          558  +    }
          559  +    pStmt = prepareSql("SELECT 1 FROM client WHERE id=%d AND wantHalt",iClient);
          560  +    rc = sqlite3_step(pStmt);
          561  +    sqlite3_finalize(pStmt);
          562  +    if( rc==SQLITE_ROW ){
          563  +      runSql("DELETE FROM client WHERE id=%d", iClient);
          564  +      g.iTimeout = DEFAULT_TIMEOUT;
          565  +      runSql("COMMIT TRANSACTION;");
          566  +      return SQLITE_DONE;
          567  +    }
          568  +    pStmt = prepareSql(
          569  +              "SELECT script, id, name FROM task"
          570  +              " WHERE client=%d AND starttime IS NULL"
          571  +              " ORDER BY id LIMIT 1", iClient);
          572  +    rc = sqlite3_step(pStmt);
          573  +    if( rc==SQLITE_ROW ){
          574  +      int n = sqlite3_column_bytes(pStmt, 0);
          575  +      *pzScript = sqlite3_malloc(n+1);
          576  +      strcpy(*pzScript, (const char*)sqlite3_column_text(pStmt, 0));
          577  +      *pTaskId = taskId = sqlite3_column_int(pStmt, 1);
          578  +      *pzTaskName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 2));
          579  +      sqlite3_finalize(pStmt);
          580  +      runSql("UPDATE task"
          581  +             "   SET starttime=strftime('%%Y-%%m-%%d %%H:%%M:%%f','now')"
          582  +             " WHERE id=%d;", taskId);
          583  +      g.iTimeout = DEFAULT_TIMEOUT;
          584  +      runSql("COMMIT TRANSACTION;");
          585  +      return SQLITE_OK;
          586  +    }
          587  +    sqlite3_finalize(pStmt);
          588  +    if( rc==SQLITE_DONE ){
          589  +      if( totalTime>30000 ){
          590  +        errorMessage("Waited over 30 seconds with no work.  Giving up.");
          591  +        runSql("DELETE FROM client WHERE id=%d; COMMIT;", iClient);
          592  +        sqlite3_close(g.db);
          593  +        exit(1);
          594  +      }
          595  +      while( trySql("COMMIT")==SQLITE_BUSY ){
          596  +        sqlite3_sleep(10);
          597  +        totalTime += 10;
          598  +      }
          599  +      sqlite3_sleep(100);
          600  +      totalTime += 100;
          601  +      continue;
          602  +    }
          603  +    fatalError("%s", sqlite3_errmsg(g.db));
          604  +  }
          605  +  g.iTimeout = DEFAULT_TIMEOUT;
          606  +}
          607  +
          608  +/*
          609  +** Mark a script as having finished.   Remove the CLIENT table entry
          610  +** if bShutdown is true.
          611  +*/
          612  +static int finishScript(int iClient, int taskId, int bShutdown){
          613  +  runSql("UPDATE task"
          614  +         "   SET endtime=strftime('%%Y-%%m-%%d %%H:%%M:%%f','now')"
          615  +         " WHERE id=%d;", taskId);
          616  +  if( bShutdown ){
          617  +    runSql("DELETE FROM client WHERE id=%d", iClient);
          618  +  }
          619  +  return SQLITE_OK;
          620  +}
          621  +
          622  +/*
          623  +** Start up a client process for iClient, if it is not already
          624  +** running.  If the client is already running, then this routine
          625  +** is a no-op.
          626  +*/
          627  +static void startClient(int iClient){
          628  +  runSql("INSERT OR IGNORE INTO client VALUES(%d,0)", iClient);
          629  +  if( sqlite3_changes(g.db) ){
          630  +    char *zSys;
          631  +    int rc;
          632  +    zSys = sqlite3_mprintf("%s \"%s\" --client %d --trace %d",
          633  +                 g.argv0, g.zDbFile, iClient, g.iTrace);
          634  +    if( g.bSqlTrace ){
          635  +      zSys = sqlite3_mprintf("%z --sqltrace", zSys);
          636  +    }
          637  +    if( g.bSync ){
          638  +      zSys = sqlite3_mprintf("%z --sync", zSys);
          639  +    }
          640  +    if( g.zVfs ){
          641  +      zSys = sqlite3_mprintf("%z --vfs \"%s\"", zSys, g.zVfs);
          642  +    }
          643  +    if( g.iTrace>=2 ) logMessage("system('%q')", zSys);
          644  +#if !defined(_WIN32)
          645  +    zSys = sqlite3_mprintf("%z &", zSys);
          646  +    rc = system(zSys);
          647  +    if( rc ) errorMessage("system() fails with error code %d", rc);
          648  +#else
          649  +    {
          650  +      STARTUPINFOA startupInfo;
          651  +      PROCESS_INFORMATION processInfo;
          652  +      memset(&startupInfo, 0, sizeof(startupInfo));
          653  +      startupInfo.cb = sizeof(startupInfo);
          654  +      memset(&processInfo, 0, sizeof(processInfo));
          655  +      rc = CreateProcessA(NULL, zSys, NULL, NULL, FALSE, 0, NULL, NULL,
          656  +                        &startupInfo, &processInfo);
          657  +      if( rc ){
          658  +        CloseHandle(processInfo.hThread);
          659  +        CloseHandle(processInfo.hProcess);
          660  +      }else{
          661  +        errorMessage("CreateProcessA() fails with error code %lu",
          662  +                     GetLastError());
          663  +      }
          664  +    }
          665  +#endif
          666  +    sqlite3_free(zSys);
          667  +  }
          668  +}
          669  +
          670  +/*
          671  +** Read the entire content of a file into memory
          672  +*/
          673  +static char *readFile(const char *zFilename){
          674  +  FILE *in = fopen(zFilename, "rb");
          675  +  long sz;
          676  +  char *z;
          677  +  if( in==0 ){
          678  +    fatalError("cannot open \"%s\" for reading", zFilename);
          679  +  }
          680  +  fseek(in, 0, SEEK_END);
          681  +  sz = ftell(in);
          682  +  rewind(in);
          683  +  z = sqlite3_malloc( sz+1 );
          684  +  sz = (long)fread(z, 1, sz, in);
          685  +  z[sz] = 0;
          686  +  fclose(in);
          687  +  return z;
          688  +}
          689  +
          690  +/*
          691  +** Return the length of the next token.
          692  +*/
          693  +static int tokenLength(const char *z, int *pnLine){
          694  +  int n = 0;
          695  +  if( isspace(z[0]) || (z[0]=='/' && z[1]=='*') ){
          696  +    int inC = 0;
          697  +    int c;
          698  +    if( z[0]=='/' ){
          699  +      inC = 1;
          700  +      n = 2;
          701  +    }
          702  +    while( (c = z[n++])!=0 ){
          703  +      if( c=='\n' ) (*pnLine)++;
          704  +      if( isspace(c) ) continue;
          705  +      if( inC && c=='*' && z[n]=='/' ){
          706  +        n++;
          707  +        inC = 0;
          708  +      }else if( !inC && c=='/' && z[n]=='*' ){
          709  +        n++;
          710  +        inC = 1;
          711  +      }else if( !inC ){
          712  +        break;
          713  +      }
          714  +    }
          715  +    n--;
          716  +  }else if( z[0]=='-' && z[1]=='-' ){
          717  +    for(n=2; z[n] && z[n]!='\n'; n++){}
          718  +    if( z[n] ){ (*pnLine)++; n++; }
          719  +  }else if( z[0]=='"' || z[0]=='\'' ){
          720  +    int delim = z[0];
          721  +    for(n=1; z[n]; n++){
          722  +      if( z[n]=='\n' ) (*pnLine)++;
          723  +      if( z[n]==delim ){
          724  +        n++;
          725  +        if( z[n+1]!=delim ) break;
          726  +      }
          727  +    }
          728  +  }else{
          729  +    int c;
          730  +    for(n=1; (c = z[n])!=0 && !isspace(c) && c!='"' && c!='\'' && c!=';'; n++){}
          731  +  }
          732  +  return n;
          733  +}
          734  +
          735  +/*
          736  +** Copy a single token into a string buffer.
          737  +*/
          738  +static int extractToken(const char *zIn, int nIn, char *zOut, int nOut){
          739  +  int i;
          740  +  if( nIn<=0 ){
          741  +    zOut[0] = 0;
          742  +    return 0;
          743  +  }
          744  +  for(i=0; i<nIn && i<nOut-1 && !isspace(zIn[i]); i++){ zOut[i] = zIn[i]; }
          745  +  zOut[i] = 0;
          746  +  return i;
          747  +}
          748  +
          749  +/*
          750  +** Find the number of characters up to the start of the next "--end" token.
          751  +*/
          752  +static int findEnd(const char *z, int *pnLine){
          753  +  int n = 0;
          754  +  while( z[n] && (strncmp(z+n,"--end",5) || !isspace(z[n+5])) ){
          755  +    n += tokenLength(z+n, pnLine);
          756  +  }
          757  +  return n;
          758  +}
          759  +
          760  +/*
          761  +** Find the number of characters up to the first character past the
          762  +** of the next "--endif"  or "--else" token. Nested --if commands are
          763  +** also skipped.
          764  +*/
          765  +static int findEndif(const char *z, int stopAtElse, int *pnLine){
          766  +  int n = 0;
          767  +  while( z[n] ){
          768  +    int len = tokenLength(z+n, pnLine);
          769  +    if( (strncmp(z+n,"--endif",7)==0 && isspace(z[n+7]))
          770  +     || (stopAtElse && strncmp(z+n,"--else",6)==0 && isspace(z[n+6]))
          771  +    ){
          772  +      return n+len;
          773  +    }
          774  +    if( strncmp(z+n,"--if",4)==0 && isspace(z[n+4]) ){
          775  +      int skip = findEndif(z+n+len, 0, pnLine);
          776  +      n += skip + len;
          777  +    }else{
          778  +      n += len;
          779  +    }
          780  +  }
          781  +  return n;
          782  +}
          783  +
          784  +/*
          785  +** Wait for a client process to complete all its tasks
          786  +*/
          787  +static void waitForClient(int iClient, int iTimeout, char *zErrPrefix){
          788  +  sqlite3_stmt *pStmt;
          789  +  int rc;
          790  +  if( iClient>0 ){
          791  +    pStmt = prepareSql(
          792  +               "SELECT 1 FROM task"
          793  +               " WHERE client=%d"
          794  +               "   AND client IN (SELECT id FROM client)"
          795  +               "  AND endtime IS NULL",
          796  +               iClient);
          797  +  }else{
          798  +    pStmt = prepareSql(
          799  +               "SELECT 1 FROM task"
          800  +               " WHERE client IN (SELECT id FROM client)"
          801  +               "   AND endtime IS NULL");
          802  +  }
          803  +  g.iTimeout = 0;
          804  +  while( ((rc = sqlite3_step(pStmt))==SQLITE_BUSY || rc==SQLITE_ROW)
          805  +    && iTimeout>0
          806  +  ){
          807  +    sqlite3_reset(pStmt);
          808  +    sqlite3_sleep(50);
          809  +    iTimeout -= 50;
          810  +  }
          811  +  sqlite3_finalize(pStmt);
          812  +  g.iTimeout = DEFAULT_TIMEOUT;
          813  +  if( rc!=SQLITE_DONE ){
          814  +    if( zErrPrefix==0 ) zErrPrefix = "";
          815  +    if( iClient>0 ){
          816  +      errorMessage("%stimeout waiting for client %d", zErrPrefix, iClient);
          817  +    }else{
          818  +      errorMessage("%stimeout waiting for all clients", zErrPrefix);
          819  +    }
          820  +  }
          821  +}
          822  +
          823  +/* Return a pointer to the tail of a filename
          824  +*/
          825  +static char *filenameTail(char *z){
          826  +  int i, j;
          827  +  for(i=j=0; z[i]; i++) if( z[i]=='/' ) j = i+1;
          828  +  return z+j;
          829  +}
          830  +
          831  +/*
          832  +** Interpret zArg as a boolean value.  Return either 0 or 1.
          833  +*/
          834  +static int booleanValue(char *zArg){
          835  +  int i;
          836  +  if( zArg==0 ) return 0;
          837  +  for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
          838  +  if( i>0 && zArg[i]==0 ) return atoi(zArg);
          839  +  if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
          840  +    return 1;
          841  +  }
          842  +  if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
          843  +    return 0;
          844  +  }
          845  +  errorMessage("unknown boolean: [%s]", zArg);
          846  +  return 0;
          847  +}
          848  +
          849  +
          850  +/* This routine exists as a convenient place to set a debugger
          851  +** breakpoint.
          852  +*/
          853  +static void test_breakpoint(void){ static volatile int cnt = 0; cnt++; }
          854  +
          855  +/* Maximum number of arguments to a --command */
          856  +#define MX_ARG 2
          857  +
          858  +/*
          859  +** Run a script.
          860  +*/
          861  +static void runScript(
          862  +  int iClient,       /* The client number, or 0 for the master */
          863  +  int taskId,        /* The task ID for clients.  0 for master */
          864  +  char *zScript,     /* Text of the script */
          865  +  char *zFilename    /* File from which script was read. */
          866  +){
          867  +  int lineno = 1;
          868  +  int prevLine = 1;
          869  +  int ii = 0;
          870  +  int iBegin = 0;
          871  +  int n, c, j;
          872  +  int len;
          873  +  int nArg;
          874  +  String sResult;
          875  +  char zCmd[30];
          876  +  char zError[1000];
          877  +  char azArg[MX_ARG][100];
          878  +
          879  +  memset(&sResult, 0, sizeof(sResult));
          880  +  stringReset(&sResult);
          881  +  while( (c = zScript[ii])!=0 ){
          882  +    prevLine = lineno;
          883  +    len = tokenLength(zScript+ii, &lineno);
          884  +    if( isspace(c) || (c=='/' && zScript[ii+1]=='*') ){
          885  +      ii += len;
          886  +      continue;
          887  +    }
          888  +    if( c!='-' || zScript[ii+1]!='-' || !isalpha(zScript[ii+2]) ){
          889  +      ii += len;
          890  +      continue;
          891  +    }
          892  +
          893  +    /* Run any prior SQL before processing the new --command */
          894  +    if( ii>iBegin ){
          895  +      char *zSql = sqlite3_mprintf("%.*s", ii-iBegin, zScript+iBegin);
          896  +      evalSql(&sResult, zSql);
          897  +      sqlite3_free(zSql);
          898  +      iBegin = ii + len;
          899  +    }
          900  +
          901  +    /* Parse the --command */
          902  +    if( g.iTrace>=2 ) logMessage("%.*s", len, zScript+ii);
          903  +    n = extractToken(zScript+ii+2, len-2, zCmd, sizeof(zCmd));
          904  +    for(nArg=0; n<len-2 && nArg<MX_ARG; nArg++){
          905  +      while( n<len-2 && isspace(zScript[ii+2+n]) ){ n++; }
          906  +      if( n>=len-2 ) break;
          907  +      n += extractToken(zScript+ii+2+n, len-2-n,
          908  +                        azArg[nArg], sizeof(azArg[nArg]));
          909  +    }
          910  +    for(j=nArg; j<MX_ARG; j++) azArg[j++][0] = 0;
          911  +
          912  +    /*
          913  +    **  --sleep N
          914  +    **
          915  +    ** Pause for N milliseconds
          916  +    */
          917  +    if( strcmp(zCmd, "sleep")==0 ){
          918  +      sqlite3_sleep(atoi(azArg[0]));
          919  +    }else 
          920  +
          921  +    /*
          922  +    **   --exit N
          923  +    **
          924  +    ** Exit this process.  If N>0 then exit without shutting down
          925  +    ** SQLite.  (In other words, simulate a crash.)
          926  +    */
          927  +    if( strcmp(zCmd, "exit")==0 ){
          928  +      int rc = atoi(azArg[0]);
          929  +      finishScript(iClient, taskId, 1);
          930  +      if( rc==0 ) sqlite3_close(g.db);
          931  +      exit(rc);
          932  +    }else
          933  +
          934  +    /*
          935  +    **   --testcase NAME
          936  +    **
          937  +    ** Begin a new test case.  Announce in the log that the test case
          938  +    ** has begun.
          939  +    */
          940  +    if( strcmp(zCmd, "testcase")==0 ){
          941  +      if( g.iTrace==1 ) logMessage("%.*s", len - 1, zScript+ii);
          942  +      stringReset(&sResult);
          943  +    }else
          944  +
          945  +    /*
          946  +    **   --finish
          947  +    **
          948  +    ** Mark the current task as having finished, even if it is not.
          949  +    ** This can be used in conjunction with --exit to simulate a crash.
          950  +    */
          951  +    if( strcmp(zCmd, "finish")==0 && iClient>0 ){
          952  +      finishScript(iClient, taskId, 1);
          953  +    }else
          954  +
          955  +    /*
          956  +    **  --reset
          957  +    **
          958  +    ** Reset accumulated results back to an empty string
          959  +    */
          960  +    if( strcmp(zCmd, "reset")==0 ){
          961  +      stringReset(&sResult);
          962  +    }else
          963  +
          964  +    /*
          965  +    **  --match ANSWER...
          966  +    **
          967  +    ** Check to see if output matches ANSWER.  Report an error if not.
          968  +    */
          969  +    if( strcmp(zCmd, "match")==0 ){
          970  +      int jj;
          971  +      char *zAns = zScript+ii;
          972  +      for(jj=7; jj<len-1 && isspace(zAns[jj]); jj++){}
          973  +      zAns += jj;
          974  +      if( len-jj-1!=sResult.n || strncmp(sResult.z, zAns, len-jj-1) ){
          975  +        errorMessage("line %d of %s:\nExpected [%.*s]\n     Got [%s]",
          976  +          prevLine, zFilename, len-jj-1, zAns, sResult.z);
          977  +      }
          978  +      g.nTest++;
          979  +      stringReset(&sResult);
          980  +    }else
          981  +
          982  +    /*
          983  +    **  --glob ANSWER...
          984  +    **  --notglob ANSWER....
          985  +    **
          986  +    ** Check to see if output does or does not match the glob pattern
          987  +    ** ANSWER.
          988  +    */
          989  +    if( strcmp(zCmd, "glob")==0 || strcmp(zCmd, "notglob")==0 ){
          990  +      int jj;
          991  +      char *zAns = zScript+ii;
          992  +      char *zCopy;
          993  +      int isGlob = (zCmd[0]=='g');
          994  +      for(jj=9-3*isGlob; jj<len-1 && isspace(zAns[jj]); jj++){}
          995  +      zAns += jj;
          996  +      zCopy = sqlite3_mprintf("%.*s", len-jj-1, zAns);
          997  +      if( (sqlite3_strglob(zCopy, sResult.z)==0)^isGlob ){
          998  +        errorMessage("line %d of %s:\nExpected [%s]\n     Got [%s]",
          999  +          prevLine, zFilename, zCopy, sResult.z);
         1000  +      }
         1001  +      sqlite3_free(zCopy);
         1002  +      g.nTest++;
         1003  +      stringReset(&sResult);
         1004  +    }else
         1005  +
         1006  +    /*
         1007  +    **  --output
         1008  +    **
         1009  +    ** Output the result of the previous SQL.
         1010  +    */
         1011  +    if( strcmp(zCmd, "output")==0 ){
         1012  +      logMessage("%s", sResult.z);
         1013  +    }else
         1014  +
         1015  +    /*
         1016  +    **  --source FILENAME
         1017  +    **
         1018  +    ** Run a subscript from a separate file.
         1019  +    */
         1020  +    if( strcmp(zCmd, "source")==0 ){
         1021  +      char *zNewFile, *zNewScript;
         1022  +      char *zToDel = 0;
         1023  +      zNewFile = azArg[0];
         1024  +      if( zNewFile[0]!='/' ){
         1025  +        int k;
         1026  +        for(k=(int)strlen(zFilename)-1; k>=0 && zFilename[k]!='/'; k--){}
         1027  +        if( k>0 ){
         1028  +          zNewFile = zToDel = sqlite3_mprintf("%.*s/%s", k,zFilename,zNewFile);
         1029  +        }
         1030  +      }
         1031  +      zNewScript = readFile(zNewFile);
         1032  +      if( g.iTrace ) logMessage("begin script [%s]\n", zNewFile);
         1033  +      runScript(0, 0, zNewScript, zNewFile);
         1034  +      sqlite3_free(zNewScript);
         1035  +      if( g.iTrace ) logMessage("end script [%s]\n", zNewFile);
         1036  +      sqlite3_free(zToDel);
         1037  +    }else
         1038  +
         1039  +    /*
         1040  +    **  --print MESSAGE....
         1041  +    **
         1042  +    ** Output the remainder of the line to the log file
         1043  +    */
         1044  +    if( strcmp(zCmd, "print")==0 ){
         1045  +      int jj;
         1046  +      for(jj=7; jj<len && isspace(zScript[ii+jj]); jj++){}
         1047  +      logMessage("%.*s", len-jj, zScript+ii+jj);
         1048  +    }else
         1049  +
         1050  +    /*
         1051  +    **  --if EXPR
         1052  +    **
         1053  +    ** Skip forward to the next matching --endif or --else if EXPR is false.
         1054  +    */
         1055  +    if( strcmp(zCmd, "if")==0 ){
         1056  +      int jj, rc;
         1057  +      sqlite3_stmt *pStmt;
         1058  +      for(jj=4; jj<len && isspace(zScript[ii+jj]); jj++){}
         1059  +      pStmt = prepareSql("SELECT %.*s", len-jj, zScript+ii+jj);
         1060  +      rc = sqlite3_step(pStmt);
         1061  +      if( rc!=SQLITE_ROW || sqlite3_column_int(pStmt, 0)==0 ){
         1062  +        ii += findEndif(zScript+ii+len, 1, &lineno);
         1063  +      }
         1064  +      sqlite3_finalize(pStmt);
         1065  +    }else
         1066  +
         1067  +    /*
         1068  +    **  --else
         1069  +    **
         1070  +    ** This command can only be encountered if currently inside an --if that
         1071  +    ** is true.  Skip forward to the next matching --endif.
         1072  +    */
         1073  +    if( strcmp(zCmd, "else")==0 ){
         1074  +      ii += findEndif(zScript+ii+len, 0, &lineno);
         1075  +    }else
         1076  +
         1077  +    /*
         1078  +    **  --endif
         1079  +    **
         1080  +    ** This command can only be encountered if currently inside an --if that
         1081  +    ** is true or an --else of a false if.  This is a no-op.
         1082  +    */
         1083  +    if( strcmp(zCmd, "endif")==0 ){
         1084  +      /* no-op */
         1085  +    }else
         1086  +
         1087  +    /*
         1088  +    **  --start CLIENT
         1089  +    **
         1090  +    ** Start up the given client.
         1091  +    */
         1092  +    if( strcmp(zCmd, "start")==0 && iClient==0 ){
         1093  +      int iNewClient = atoi(azArg[0]);
         1094  +      if( iNewClient>0 ){
         1095  +        startClient(iNewClient);
         1096  +      }
         1097  +    }else
         1098  +
         1099  +    /*
         1100  +    **  --wait CLIENT TIMEOUT
         1101  +    **
         1102  +    ** Wait until all tasks complete for the given client.  If CLIENT is
         1103  +    ** "all" then wait for all clients to complete.  Wait no longer than
         1104  +    ** TIMEOUT milliseconds (default 10,000)
         1105  +    */
         1106  +    if( strcmp(zCmd, "wait")==0 && iClient==0 ){
         1107  +      int iTimeout = nArg>=2 ? atoi(azArg[1]) : 10000;
         1108  +      sqlite3_snprintf(sizeof(zError),zError,"line %d of %s\n",
         1109  +                       prevLine, zFilename);
         1110  +      waitForClient(atoi(azArg[0]), iTimeout, zError);
         1111  +    }else
         1112  +
         1113  +    /*
         1114  +    **  --task CLIENT
         1115  +    **     <task-content-here>
         1116  +    **  --end
         1117  +    **
         1118  +    ** Assign work to a client.  Start the client if it is not running
         1119  +    ** already.
         1120  +    */
         1121  +    if( strcmp(zCmd, "task")==0 && iClient==0 ){
         1122  +      int iTarget = atoi(azArg[0]);
         1123  +      int iEnd;
         1124  +      char *zTask;
         1125  +      char *zTName;
         1126  +      iEnd = findEnd(zScript+ii+len, &lineno);
         1127  +      if( iTarget<0 ){
         1128  +        errorMessage("line %d of %s: bad client number: %d",
         1129  +                     prevLine, zFilename, iTarget);
         1130  +      }else{
         1131  +        zTask = sqlite3_mprintf("%.*s", iEnd, zScript+ii+len);
         1132  +        if( nArg>1 ){
         1133  +          zTName = sqlite3_mprintf("%s", azArg[1]);
         1134  +        }else{
         1135  +          zTName = sqlite3_mprintf("%s:%d", filenameTail(zFilename), prevLine);
         1136  +        }
         1137  +        startClient(iTarget);
         1138  +        runSql("INSERT INTO task(client,script,name)"
         1139  +               " VALUES(%d,'%q',%Q)", iTarget, zTask, zTName);
         1140  +        sqlite3_free(zTask);
         1141  +        sqlite3_free(zTName);
         1142  +      }
         1143  +      iEnd += tokenLength(zScript+ii+len+iEnd, &lineno);
         1144  +      len += iEnd;
         1145  +      iBegin = ii+len;
         1146  +    }else
         1147  +
         1148  +    /*
         1149  +    **  --breakpoint
         1150  +    **
         1151  +    ** This command calls "test_breakpoint()" which is a routine provided
         1152  +    ** as a convenient place to set a debugger breakpoint.
         1153  +    */
         1154  +    if( strcmp(zCmd, "breakpoint")==0 ){
         1155  +      test_breakpoint();
         1156  +    }else
         1157  +
         1158  +    /*
         1159  +    **  --show-sql-errors BOOLEAN
         1160  +    **
         1161  +    ** Turn display of SQL errors on and off.
         1162  +    */
         1163  +    if( strcmp(zCmd, "show-sql-errors")==0 ){
         1164  +      g.bIgnoreSqlErrors = nArg>=1 ? !booleanValue(azArg[0]) : 1;
         1165  +    }else
         1166  +
         1167  +
         1168  +    /* error */{
         1169  +      errorMessage("line %d of %s: unknown command --%s",
         1170  +                   prevLine, zFilename, zCmd);
         1171  +    }
         1172  +    ii += len;
         1173  +  }
         1174  +  if( iBegin<ii ){
         1175  +    char *zSql = sqlite3_mprintf("%.*s", ii-iBegin, zScript+iBegin);
         1176  +    runSql(zSql);
         1177  +    sqlite3_free(zSql);
         1178  +  }
         1179  +  stringFree(&sResult);
         1180  +}
         1181  +
         1182  +/*
         1183  +** Look for a command-line option.  If present, return a pointer.
         1184  +** Return NULL if missing.
         1185  +**
         1186  +** hasArg==0 means the option is a flag.  It is either present or not.
         1187  +** hasArg==1 means the option has an argument.  Return a pointer to the
         1188  +** argument.
         1189  +*/
         1190  +static char *findOption(
         1191  +  char **azArg,
         1192  +  int *pnArg,
         1193  +  const char *zOption,
         1194  +  int hasArg
         1195  +){
         1196  +  int i, j;
         1197  +  char *zReturn = 0;
         1198  +  int nArg = *pnArg;
         1199  +
         1200  +  assert( hasArg==0 || hasArg==1 );
         1201  +  for(i=0; i<nArg; i++){
         1202  +    const char *z;
         1203  +    if( i+hasArg >= nArg ) break;
         1204  +    z = azArg[i];
         1205  +    if( z[0]!='-' ) continue;
         1206  +    z++;
         1207  +    if( z[0]=='-' ){
         1208  +      if( z[1]==0 ) break;
         1209  +      z++;
         1210  +    }
         1211  +    if( strcmp(z,zOption)==0 ){
         1212  +      if( hasArg && i==nArg-1 ){
         1213  +        fatalError("command-line option \"--%s\" requires an argument", z);
         1214  +      }
         1215  +      if( hasArg ){
         1216  +        zReturn = azArg[i+1];
         1217  +      }else{
         1218  +        zReturn = azArg[i];
         1219  +      }
         1220  +      j = i+1+(hasArg!=0);
         1221  +      while( j<nArg ) azArg[i++] = azArg[j++];
         1222  +      *pnArg = i;
         1223  +      return zReturn;
         1224  +    }
         1225  +  }
         1226  +  return zReturn;
         1227  +}
         1228  +
         1229  +/* Print a usage message for the program and exit */
         1230  +static void usage(const char *argv0){
         1231  +  int i;
         1232  +  const char *zTail = argv0;
         1233  +  for(i=0; argv0[i]; i++){
         1234  +    if( argv0[i]=='/' ) zTail = argv0+i+1;
         1235  +  }
         1236  +  fprintf(stderr,"Usage: %s DATABASE ?OPTIONS? ?SCRIPT?\n", zTail);
         1237  +  exit(1);
         1238  +}
         1239  +
         1240  +/* Report on unrecognized arguments */
         1241  +static void unrecognizedArguments(
         1242  +  const char *argv0,
         1243  +  int nArg,
         1244  +  char **azArg
         1245  +){
         1246  +  int i;
         1247  +  fprintf(stderr,"%s: unrecognized arguments:", argv0);
         1248  +  for(i=0; i<nArg; i++){
         1249  +    fprintf(stderr," %s", azArg[i]);
         1250  +  }
         1251  +  fprintf(stderr,"\n");
         1252  +  exit(1);
         1253  +}
         1254  +
         1255  +int main(int argc, char **argv){
         1256  +  const char *zClient;
         1257  +  int iClient;
         1258  +  int n, i;
         1259  +  int openFlags = SQLITE_OPEN_READWRITE;
         1260  +  int rc;
         1261  +  char *zScript;
         1262  +  int taskId;
         1263  +  const char *zTrace;
         1264  +  const char *zCOption;
         1265  +
         1266  +  g.argv0 = argv[0];
         1267  +  g.iTrace = 1;
         1268  +  if( argc<2 ) usage(argv[0]);
         1269  +  g.zDbFile = argv[1];
         1270  +  if( strglob("*.test", g.zDbFile) ) usage(argv[0]);
         1271  +  if( strcmp(sqlite3_sourceid(), SQLITE_SOURCE_ID)!=0 ){
         1272  +    fprintf(stderr, "SQLite library and header mismatch\n"
         1273  +                    "Library: %s\n"
         1274  +                    "Header:  %s\n",
         1275  +                    sqlite3_sourceid(), SQLITE_SOURCE_ID);
         1276  +    exit(1);
         1277  +  }
         1278  +  n = argc-2;
         1279  +  sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.mptest", GETPID());
         1280  +  g.zVfs = findOption(argv+2, &n, "vfs", 1);
         1281  +  zClient = findOption(argv+2, &n, "client", 1);
         1282  +  g.zErrLog = findOption(argv+2, &n, "errlog", 1);
         1283  +  g.zLog = findOption(argv+2, &n, "log", 1);
         1284  +  zTrace = findOption(argv+2, &n, "trace", 1);
         1285  +  if( zTrace ) g.iTrace = atoi(zTrace);
         1286  +  if( findOption(argv+2, &n, "quiet", 0)!=0 ) g.iTrace = 0;
         1287  +  g.bSqlTrace = findOption(argv+2, &n, "sqltrace", 0)!=0;
         1288  +  g.bSync = findOption(argv+2, &n, "sync", 0)!=0;
         1289  +  if( g.zErrLog ){
         1290  +    g.pErrLog = fopen(g.zErrLog, "a");
         1291  +  }else{
         1292  +    g.pErrLog = stderr;
         1293  +  }
         1294  +  if( g.zLog ){
         1295  +    g.pLog = fopen(g.zLog, "a");
         1296  +  }else{
         1297  +    g.pLog = stdout;
         1298  +  }
         1299  +  
         1300  +  sqlite3_config(SQLITE_CONFIG_LOG, sqlErrorCallback, 0);
         1301  +  if( zClient ){
         1302  +    iClient = atoi(zClient);
         1303  +    if( iClient<1 ) fatalError("illegal client number: %d\n", iClient);
         1304  +    sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.client%02d",
         1305  +                     GETPID(), iClient);
         1306  +  }else{
         1307  +    if( g.iTrace>0 ){
         1308  +      printf("With SQLite " SQLITE_VERSION " " SQLITE_SOURCE_ID "\n" );
         1309  +      for(i=0; (zCOption = sqlite3_compileoption_get(i))!=0; i++){
         1310  +        printf("-DSQLITE_%s\n", zCOption);
         1311  +      }
         1312  +      fflush(stdout);
         1313  +    }
         1314  +    iClient =  0;
         1315  +    unlink(g.zDbFile);
         1316  +    openFlags |= SQLITE_OPEN_CREATE;
         1317  +  }
         1318  +  rc = sqlite3_open_v2(g.zDbFile, &g.db, openFlags, g.zVfs);
         1319  +  if( rc ) fatalError("cannot open [%s]", g.zDbFile);
         1320  +  sqlite3_enable_load_extension(g.db, 1);
         1321  +  sqlite3_busy_handler(g.db, busyHandler, 0);
         1322  +  sqlite3_create_function(g.db, "vfsname", 0, SQLITE_UTF8, 0,
         1323  +                          vfsNameFunc, 0, 0);
         1324  +  sqlite3_create_function(g.db, "eval", 1, SQLITE_UTF8, 0,
         1325  +                          evalFunc, 0, 0);
         1326  +  g.iTimeout = DEFAULT_TIMEOUT;
         1327  +  if( g.bSqlTrace ) sqlite3_trace(g.db, sqlTraceCallback, 0);
         1328  +  if( !g.bSync ) trySql("PRAGMA synchronous=OFF");
         1329  +  if( iClient>0 ){
         1330  +    if( n>0 ) unrecognizedArguments(argv[0], n, argv+2);
         1331  +    if( g.iTrace ) logMessage("start-client");
         1332  +    while(1){
         1333  +      char *zTaskName = 0;
         1334  +      rc = startScript(iClient, &zScript, &taskId, &zTaskName);
         1335  +      if( rc==SQLITE_DONE ) break;
         1336  +      if( g.iTrace ) logMessage("begin %s (%d)", zTaskName, taskId);
         1337  +      runScript(iClient, taskId, zScript, zTaskName);
         1338  +      if( g.iTrace ) logMessage("end %s (%d)", zTaskName, taskId);
         1339  +      finishScript(iClient, taskId, 0);
         1340  +      sqlite3_free(zTaskName);
         1341  +      sqlite3_sleep(10);
         1342  +    }
         1343  +    if( g.iTrace ) logMessage("end-client");
         1344  +  }else{
         1345  +    sqlite3_stmt *pStmt;
         1346  +    int iTimeout;
         1347  +    if( n==0 ){
         1348  +      fatalError("missing script filename");
         1349  +    }
         1350  +    if( n>1 ) unrecognizedArguments(argv[0], n, argv+2);
         1351  +    runSql(
         1352  +      "CREATE TABLE task(\n"
         1353  +      "  id INTEGER PRIMARY KEY,\n"
         1354  +      "  name TEXT,\n"
         1355  +      "  client INTEGER,\n"
         1356  +      "  starttime DATE,\n"
         1357  +      "  endtime DATE,\n"
         1358  +      "  script TEXT\n"
         1359  +      ");"
         1360  +      "CREATE INDEX task_i1 ON task(client, starttime);\n"
         1361  +      "CREATE INDEX task_i2 ON task(client, endtime);\n"
         1362  +      "CREATE TABLE counters(nError,nTest);\n"
         1363  +      "INSERT INTO counters VALUES(0,0);\n"
         1364  +      "CREATE TABLE client(id INTEGER PRIMARY KEY, wantHalt);\n"
         1365  +    );
         1366  +    zScript = readFile(argv[2]);
         1367  +    if( g.iTrace ) logMessage("begin script [%s]\n", argv[2]);
         1368  +    runScript(0, 0, zScript, argv[2]);
         1369  +    sqlite3_free(zScript);
         1370  +    if( g.iTrace ) logMessage("end script [%s]\n", argv[2]);
         1371  +    waitForClient(0, 2000, "during shutdown...\n");
         1372  +    trySql("UPDATE client SET wantHalt=1");
         1373  +    sqlite3_sleep(10);
         1374  +    g.iTimeout = 0;
         1375  +    iTimeout = 1000;
         1376  +    while( ((rc = trySql("SELECT 1 FROM client"))==SQLITE_BUSY
         1377  +        || rc==SQLITE_ROW) && iTimeout>0 ){
         1378  +      sqlite3_sleep(10);
         1379  +      iTimeout -= 10;
         1380  +    }
         1381  +    sqlite3_sleep(100);
         1382  +    pStmt = prepareSql("SELECT nError, nTest FROM counters");
         1383  +    iTimeout = 1000;
         1384  +    while( (rc = sqlite3_step(pStmt))==SQLITE_BUSY && iTimeout>0 ){
         1385  +      sqlite3_sleep(10);
         1386  +      iTimeout -= 10;
         1387  +    }
         1388  +    if( rc==SQLITE_ROW ){
         1389  +      g.nError += sqlite3_column_int(pStmt, 0);
         1390  +      g.nTest += sqlite3_column_int(pStmt, 1);
         1391  +    }
         1392  +    sqlite3_finalize(pStmt);
         1393  +  }
         1394  +  sqlite3_close(g.db);  
         1395  +  maybeClose(g.pLog);
         1396  +  maybeClose(g.pErrLog);
         1397  +  if( iClient==0 ){
         1398  +    printf("Summary: %d errors in %d tests\n", g.nError, g.nTest);
         1399  +  }
         1400  +  return g.nError>0;
         1401  +}

Added mptest/multiwrite01.test.

            1  +/*
            2  +** This script sets up five different tasks all writing and updating
            3  +** the database at the same time, but each in its own table.
            4  +*/
            5  +--task 1 build-t1
            6  +  DROP TABLE IF EXISTS t1;
            7  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
            8  +  --sleep 1
            9  +  INSERT INTO t1 VALUES(1, randomblob(2000));
           10  +  INSERT INTO t1 VALUES(2, randomblob(1000));
           11  +  --sleep 1
           12  +  INSERT INTO t1 SELECT a+2, randomblob(1500) FROM t1;
           13  +  INSERT INTO t1 SELECT a+4, randomblob(1500) FROM t1;
           14  +  INSERT INTO t1 SELECT a+8, randomblob(1500) FROM t1;
           15  +  --sleep 1
           16  +  INSERT INTO t1 SELECT a+16, randomblob(1500) FROM t1;
           17  +  --sleep 1
           18  +  INSERT INTO t1 SELECT a+32, randomblob(1500) FROM t1;
           19  +  SELECT count(*) FROM t1;
           20  +  --match 64
           21  +  SELECT avg(length(b)) FROM t1;
           22  +  --match 1500.0
           23  +  --sleep 2
           24  +  UPDATE t1 SET b='x'||a||'y';
           25  +  SELECT total(length(b)) FROM t1;
           26  +  --match 247
           27  +  SELECT a FROM t1 WHERE b='x17y';
           28  +  --match 17
           29  +  CREATE INDEX t1b ON t1(b);
           30  +  SELECT a FROM t1 WHERE b='x17y';
           31  +  --match 17
           32  +  SELECT a FROM t1 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           33  +  --match 29 28 27 26 25
           34  +--end
           35  +
           36  +
           37  +--task 2 build-t2
           38  +  DROP TABLE IF EXISTS t2;
           39  +  CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
           40  +  --sleep 1
           41  +  INSERT INTO t2 VALUES(1, randomblob(2000));
           42  +  INSERT INTO t2 VALUES(2, randomblob(1000));
           43  +  --sleep 1
           44  +  INSERT INTO t2 SELECT a+2, randomblob(1500) FROM t2;
           45  +  INSERT INTO t2 SELECT a+4, randomblob(1500) FROM t2;
           46  +  INSERT INTO t2 SELECT a+8, randomblob(1500) FROM t2;
           47  +  --sleep 1
           48  +  INSERT INTO t2 SELECT a+16, randomblob(1500) FROM t2;
           49  +  --sleep 1
           50  +  INSERT INTO t2 SELECT a+32, randomblob(1500) FROM t2;
           51  +  SELECT count(*) FROM t2;
           52  +  --match 64
           53  +  SELECT avg(length(b)) FROM t2;
           54  +  --match 1500.0
           55  +  --sleep 2
           56  +  UPDATE t2 SET b='x'||a||'y';
           57  +  SELECT total(length(b)) FROM t2;
           58  +  --match 247
           59  +  SELECT a FROM t2 WHERE b='x17y';
           60  +  --match 17
           61  +  CREATE INDEX t2b ON t2(b);
           62  +  SELECT a FROM t2 WHERE b='x17y';
           63  +  --match 17
           64  +  SELECT a FROM t2 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           65  +  --match 29 28 27 26 25
           66  +--end
           67  +
           68  +--task 3 build-t3
           69  +  DROP TABLE IF EXISTS t3;
           70  +  CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
           71  +  --sleep 1
           72  +  INSERT INTO t3 VALUES(1, randomblob(2000));
           73  +  INSERT INTO t3 VALUES(2, randomblob(1000));
           74  +  --sleep 1
           75  +  INSERT INTO t3 SELECT a+2, randomblob(1500) FROM t3;
           76  +  INSERT INTO t3 SELECT a+4, randomblob(1500) FROM t3;
           77  +  INSERT INTO t3 SELECT a+8, randomblob(1500) FROM t3;
           78  +  --sleep 1
           79  +  INSERT INTO t3 SELECT a+16, randomblob(1500) FROM t3;
           80  +  --sleep 1
           81  +  INSERT INTO t3 SELECT a+32, randomblob(1500) FROM t3;
           82  +  SELECT count(*) FROM t3;
           83  +  --match 64
           84  +  SELECT avg(length(b)) FROM t3;
           85  +  --match 1500.0
           86  +  --sleep 2
           87  +  UPDATE t3 SET b='x'||a||'y';
           88  +  SELECT total(length(b)) FROM t3;
           89  +  --match 247
           90  +  SELECT a FROM t3 WHERE b='x17y';
           91  +  --match 17
           92  +  CREATE INDEX t3b ON t3(b);
           93  +  SELECT a FROM t3 WHERE b='x17y';
           94  +  --match 17
           95  +  SELECT a FROM t3 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
           96  +  --match 29 28 27 26 25
           97  +--end
           98  +
           99  +--task 4 build-t4
          100  +  DROP TABLE IF EXISTS t4;
          101  +  CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
          102  +  --sleep 1
          103  +  INSERT INTO t4 VALUES(1, randomblob(2000));
          104  +  INSERT INTO t4 VALUES(2, randomblob(1000));
          105  +  --sleep 1
          106  +  INSERT INTO t4 SELECT a+2, randomblob(1500) FROM t4;
          107  +  INSERT INTO t4 SELECT a+4, randomblob(1500) FROM t4;
          108  +  INSERT INTO t4 SELECT a+8, randomblob(1500) FROM t4;
          109  +  --sleep 1
          110  +  INSERT INTO t4 SELECT a+16, randomblob(1500) FROM t4;
          111  +  --sleep 1
          112  +  INSERT INTO t4 SELECT a+32, randomblob(1500) FROM t4;
          113  +  SELECT count(*) FROM t4;
          114  +  --match 64
          115  +  SELECT avg(length(b)) FROM t4;
          116  +  --match 1500.0
          117  +  --sleep 2
          118  +  UPDATE t4 SET b='x'||a||'y';
          119  +  SELECT total(length(b)) FROM t4;
          120  +  --match 247
          121  +  SELECT a FROM t4 WHERE b='x17y';
          122  +  --match 17
          123  +  CREATE INDEX t4b ON t4(b);
          124  +  SELECT a FROM t4 WHERE b='x17y';
          125  +  --match 17
          126  +  SELECT a FROM t4 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
          127  +  --match 29 28 27 26 25
          128  +--end
          129  +
          130  +--task 5 build-t5
          131  +  DROP TABLE IF EXISTS t5;
          132  +  CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
          133  +  --sleep 1
          134  +  INSERT INTO t5 VALUES(1, randomblob(2000));
          135  +  INSERT INTO t5 VALUES(2, randomblob(1000));
          136  +  --sleep 1
          137  +  INSERT INTO t5 SELECT a+2, randomblob(1500) FROM t5;
          138  +  INSERT INTO t5 SELECT a+4, randomblob(1500) FROM t5;
          139  +  INSERT INTO t5 SELECT a+8, randomblob(1500) FROM t5;
          140  +  --sleep 1
          141  +  INSERT INTO t5 SELECT a+16, randomblob(1500) FROM t5;
          142  +  --sleep 1
          143  +  INSERT INTO t5 SELECT a+32, randomblob(1500) FROM t5;
          144  +  SELECT count(*) FROM t5;
          145  +  --match 64
          146  +  SELECT avg(length(b)) FROM t5;
          147  +  --match 1500.0
          148  +  --sleep 2
          149  +  UPDATE t5 SET b='x'||a||'y';
          150  +  SELECT total(length(b)) FROM t5;
          151  +  --match 247
          152  +  SELECT a FROM t5 WHERE b='x17y';
          153  +  --match 17
          154  +  CREATE INDEX t5b ON t5(b);
          155  +  SELECT a FROM t5 WHERE b='x17y';
          156  +  --match 17
          157  +  SELECT a FROM t5 WHERE b GLOB 'x2?y' ORDER BY b DESC LIMIT 5;
          158  +  --match 29 28 27 26 25
          159  +--end
          160  +
          161  +--wait all
          162  +SELECT count(*), total(length(b)) FROM t1;
          163  +--match 64 247
          164  +SELECT count(*), total(length(b)) FROM t2;
          165  +--match 64 247
          166  +SELECT count(*), total(length(b)) FROM t3;
          167  +--match 64 247
          168  +SELECT count(*), total(length(b)) FROM t4;
          169  +--match 64 247
          170  +SELECT count(*), total(length(b)) FROM t5;
          171  +--match 64 247
          172  +
          173  +--task 1
          174  +  SELECT t1.a FROM t1, t2
          175  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          176  +   ORDER BY t1.a LIMIT 4
          177  +  --match 33 34 35 36
          178  +  SELECT t3.a FROM t3, t4
          179  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          180  +   ORDER BY t3.a LIMIT 7
          181  +  --match 45 46 47 48 49 50 51
          182  +--end
          183  +--task 5
          184  +  SELECT t1.a FROM t1, t2
          185  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          186  +   ORDER BY t1.a LIMIT 4
          187  +  --match 33 34 35 36
          188  +  SELECT t3.a FROM t3, t4
          189  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          190  +   ORDER BY t3.a LIMIT 7
          191  +  --match 45 46 47 48 49 50 51
          192  +--end
          193  +--task 3
          194  +  SELECT t1.a FROM t1, t2
          195  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          196  +   ORDER BY t1.a LIMIT 4
          197  +  --match 33 34 35 36
          198  +  SELECT t3.a FROM t3, t4
          199  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          200  +   ORDER BY t3.a LIMIT 7
          201  +  --match 45 46 47 48 49 50 51
          202  +--end
          203  +--task 2
          204  +  SELECT t1.a FROM t1, t2
          205  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          206  +   ORDER BY t1.a LIMIT 4
          207  +  --match 33 34 35 36
          208  +  SELECT t3.a FROM t3, t4
          209  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          210  +   ORDER BY t3.a LIMIT 7
          211  +  --match 45 46 47 48 49 50 51
          212  +--end
          213  +--task 4
          214  +  SELECT t1.a FROM t1, t2
          215  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          216  +   ORDER BY t1.a LIMIT 4
          217  +  --match 33 34 35 36
          218  +  SELECT t3.a FROM t3, t4
          219  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          220  +   ORDER BY t3.a LIMIT 7
          221  +  --match 45 46 47 48 49 50 51
          222  +--end
          223  +--wait all
          224  +
          225  +--task 5
          226  +  DROP INDEX t5b;
          227  +  --sleep 5
          228  +  PRAGMA integrity_check(10);
          229  +  --match ok
          230  +  CREATE INDEX t5b ON t5(b DESC);
          231  +--end
          232  +--task 3
          233  +  DROP INDEX t3b;
          234  +  --sleep 5
          235  +  PRAGMA integrity_check(10);
          236  +  --match ok
          237  +  CREATE INDEX t3b ON t3(b DESC);
          238  +--end
          239  +--task 1
          240  +  DROP INDEX t1b;
          241  +  --sleep 5
          242  +  PRAGMA integrity_check(10);
          243  +  --match ok
          244  +  CREATE INDEX t1b ON t1(b DESC);
          245  +--end
          246  +--task 2
          247  +  DROP INDEX t2b;
          248  +  --sleep 5
          249  +  PRAGMA integrity_check(10);
          250  +  --match ok
          251  +  CREATE INDEX t2b ON t2(b DESC);
          252  +--end
          253  +--task 4
          254  +  DROP INDEX t4b;
          255  +  --sleep 5
          256  +  PRAGMA integrity_check(10);
          257  +  --match ok
          258  +  CREATE INDEX t4b ON t4(b DESC);
          259  +--end
          260  +--wait all
          261  +
          262  +--task 1
          263  +  SELECT t1.a FROM t1, t2
          264  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          265  +   ORDER BY t1.a LIMIT 4
          266  +  --match 33 34 35 36
          267  +  SELECT t3.a FROM t3, t4
          268  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          269  +   ORDER BY t3.a LIMIT 7
          270  +  --match 45 46 47 48 49 50 51
          271  +--end
          272  +--task 5
          273  +  SELECT t1.a FROM t1, t2
          274  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          275  +   ORDER BY t1.a LIMIT 4
          276  +  --match 33 34 35 36
          277  +  SELECT t3.a FROM t3, t4
          278  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          279  +   ORDER BY t3.a LIMIT 7
          280  +  --match 45 46 47 48 49 50 51
          281  +--end
          282  +--task 3
          283  +  SELECT t1.a FROM t1, t2
          284  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          285  +   ORDER BY t1.a LIMIT 4
          286  +  --match 33 34 35 36
          287  +  SELECT t3.a FROM t3, t4
          288  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          289  +   ORDER BY t3.a LIMIT 7
          290  +  --match 45 46 47 48 49 50 51
          291  +--end
          292  +--task 2
          293  +  SELECT t1.a FROM t1, t2
          294  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          295  +   ORDER BY t1.a LIMIT 4
          296  +  --match 33 34 35 36
          297  +  SELECT t3.a FROM t3, t4
          298  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          299  +   ORDER BY t3.a LIMIT 7
          300  +  --match 45 46 47 48 49 50 51
          301  +--end
          302  +--task 4
          303  +  SELECT t1.a FROM t1, t2
          304  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          305  +   ORDER BY t1.a LIMIT 4
          306  +  --match 33 34 35 36
          307  +  SELECT t3.a FROM t3, t4
          308  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          309  +   ORDER BY t3.a LIMIT 7
          310  +  --match 45 46 47 48 49 50 51
          311  +--end
          312  +--wait all
          313  +
          314  +VACUUM;
          315  +PRAGMA integrity_check(10);
          316  +--match ok
          317  +
          318  +--task 1
          319  +  UPDATE t1 SET b=randomblob(20000);
          320  +  --sleep 5
          321  +  UPDATE t1 SET b='x'||a||'y';
          322  +  SELECT a FROM t1 WHERE b='x63y';
          323  +  --match 63
          324  +--end
          325  +--task 2
          326  +  UPDATE t2 SET b=randomblob(20000);
          327  +  --sleep 5
          328  +  UPDATE t2 SET b='x'||a||'y';
          329  +  SELECT a FROM t2 WHERE b='x63y';
          330  +  --match 63
          331  +--end
          332  +--task 3
          333  +  UPDATE t3 SET b=randomblob(20000);
          334  +  --sleep 5
          335  +  UPDATE t3 SET b='x'||a||'y';
          336  +  SELECT a FROM t3 WHERE b='x63y';
          337  +  --match 63
          338  +--end
          339  +--task 4
          340  +  UPDATE t4 SET b=randomblob(20000);
          341  +  --sleep 5
          342  +  UPDATE t4 SET b='x'||a||'y';
          343  +  SELECT a FROM t4 WHERE b='x63y';
          344  +  --match 63
          345  +--end
          346  +--task 5
          347  +  UPDATE t5 SET b=randomblob(20000);
          348  +  --sleep 5
          349  +  UPDATE t5 SET b='x'||a||'y';
          350  +  SELECT a FROM t5 WHERE b='x63y';
          351  +  --match 63
          352  +--end
          353  +--wait all
          354  +
          355  +--task 1
          356  +  SELECT t1.a FROM t1, t2
          357  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          358  +   ORDER BY t1.a LIMIT 4
          359  +  --match 33 34 35 36
          360  +  SELECT t3.a FROM t3, t4
          361  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          362  +   ORDER BY t3.a LIMIT 7
          363  +  --match 45 46 47 48 49 50 51
          364  +--end
          365  +--task 5
          366  +  SELECT t1.a FROM t1, t2
          367  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          368  +   ORDER BY t1.a LIMIT 4
          369  +  --match 33 34 35 36
          370  +  SELECT t3.a FROM t3, t4
          371  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          372  +   ORDER BY t3.a LIMIT 7
          373  +  --match 45 46 47 48 49 50 51
          374  +--end
          375  +--task 3
          376  +  SELECT t1.a FROM t1, t2
          377  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          378  +   ORDER BY t1.a LIMIT 4
          379  +  --match 33 34 35 36
          380  +  SELECT t3.a FROM t3, t4
          381  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          382  +   ORDER BY t3.a LIMIT 7
          383  +  --match 45 46 47 48 49 50 51
          384  +--end
          385  +--task 2
          386  +  SELECT t1.a FROM t1, t2
          387  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          388  +   ORDER BY t1.a LIMIT 4
          389  +  --match 33 34 35 36
          390  +  SELECT t3.a FROM t3, t4
          391  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          392  +   ORDER BY t3.a LIMIT 7
          393  +  --match 45 46 47 48 49 50 51
          394  +--end
          395  +--task 4
          396  +  SELECT t1.a FROM t1, t2
          397  +   WHERE t2.b GLOB 'x3?y' AND t1.b=('x'||(t2.a+3)||'y')
          398  +   ORDER BY t1.a LIMIT 4
          399  +  --match 33 34 35 36
          400  +  SELECT t3.a FROM t3, t4
          401  +   WHERE t4.b GLOB 'x4?y' AND t3.b=('x'||(t4.a+5)||'y')
          402  +   ORDER BY t3.a LIMIT 7
          403  +  --match 45 46 47 48 49 50 51
          404  +--end
          405  +--wait all

Changes to src/backup.c.

   393    393       */
   394    394       nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
   395    395       assert( nSrcPage>=0 );
   396    396       for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
   397    397         const Pgno iSrcPg = p->iNext;                 /* Source page number */
   398    398         if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
   399    399           DbPage *pSrcPg;                             /* Source page object */
   400         -        rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
          400  +        rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
          401  +                                 PAGER_ACQUIRE_READONLY);
   401    402           if( rc==SQLITE_OK ){
   402    403             rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
   403    404             sqlite3PagerUnref(pSrcPg);
   404    405           }
   405    406         }
   406    407         p->iNext++;
   407    408       }

Changes to src/btree.c.

  1577   1577   ** means we have started to be concerned about content and the disk
  1578   1578   ** read should occur at that point.
  1579   1579   */
  1580   1580   static int btreeGetPage(
  1581   1581     BtShared *pBt,       /* The btree */
  1582   1582     Pgno pgno,           /* Number of the page to fetch */
  1583   1583     MemPage **ppPage,    /* Return the page in this parameter */
  1584         -  int noContent        /* Do not load page content if true */
         1584  +  int noContent,       /* Do not load page content if true */
         1585  +  int bReadonly        /* True if a read-only (mmap) page is ok */
  1585   1586   ){
  1586   1587     int rc;
  1587   1588     DbPage *pDbPage;
         1589  +  int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0) 
         1590  +            | (bReadonly ? PAGER_ACQUIRE_READONLY : 0);
  1588   1591   
         1592  +  assert( noContent==0 || bReadonly==0 );
  1589   1593     assert( sqlite3_mutex_held(pBt->mutex) );
  1590         -  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
         1594  +  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
  1591   1595     if( rc ) return rc;
  1592   1596     *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
  1593   1597     return SQLITE_OK;
  1594   1598   }
  1595   1599   
  1596   1600   /*
  1597   1601   ** Retrieve a page from the pager cache. If the requested page is not
................................................................................
  1626   1630   ** convenience wrapper around separate calls to btreeGetPage() and 
  1627   1631   ** btreeInitPage().
  1628   1632   **
  1629   1633   ** If an error occurs, then the value *ppPage is set to is undefined. It
  1630   1634   ** may remain unchanged, or it may be set to an invalid value.
  1631   1635   */
  1632   1636   static int getAndInitPage(
  1633         -  BtShared *pBt,          /* The database file */
  1634         -  Pgno pgno,           /* Number of the page to get */
  1635         -  MemPage **ppPage     /* Write the page pointer here */
         1637  +  BtShared *pBt,                  /* The database file */
         1638  +  Pgno pgno,                      /* Number of the page to get */
         1639  +  MemPage **ppPage,               /* Write the page pointer here */
         1640  +  int bReadonly                   /* True if a read-only (mmap) page is ok */
  1636   1641   ){
  1637   1642     int rc;
  1638   1643     assert( sqlite3_mutex_held(pBt->mutex) );
  1639   1644   
  1640   1645     if( pgno>btreePagecount(pBt) ){
  1641   1646       rc = SQLITE_CORRUPT_BKPT;
  1642   1647     }else{
  1643         -    rc = btreeGetPage(pBt, pgno, ppPage, 0);
         1648  +    rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly);
  1644   1649       if( rc==SQLITE_OK ){
  1645   1650         rc = btreeInitPage(*ppPage);
  1646   1651         if( rc!=SQLITE_OK ){
  1647   1652           releasePage(*ppPage);
  1648   1653         }
  1649   1654       }
  1650   1655     }
................................................................................
  1867   1872       if( pBt==0 ){
  1868   1873         rc = SQLITE_NOMEM;
  1869   1874         goto btree_open_out;
  1870   1875       }
  1871   1876       rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
  1872   1877                             EXTRA_SIZE, flags, vfsFlags, pageReinit);
  1873   1878       if( rc==SQLITE_OK ){
         1879  +      sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap);
  1874   1880         rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
  1875   1881       }
  1876   1882       if( rc!=SQLITE_OK ){
  1877   1883         goto btree_open_out;
  1878   1884       }
  1879   1885       pBt->openFlags = (u8)flags;
  1880   1886       pBt->db = db;
................................................................................
  2132   2138     BtShared *pBt = p->pBt;
  2133   2139     assert( sqlite3_mutex_held(p->db->mutex) );
  2134   2140     sqlite3BtreeEnter(p);
  2135   2141     sqlite3PagerSetCachesize(pBt->pPager, mxPage);
  2136   2142     sqlite3BtreeLeave(p);
  2137   2143     return SQLITE_OK;
  2138   2144   }
         2145  +
         2146  +/*
         2147  +** Change the limit on the amount of the database file that may be
         2148  +** memory mapped.
         2149  +*/
         2150  +int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
         2151  +  BtShared *pBt = p->pBt;
         2152  +  assert( sqlite3_mutex_held(p->db->mutex) );
         2153  +  sqlite3BtreeEnter(p);
         2154  +  sqlite3PagerSetMmapLimit(pBt->pPager, szMmap);
         2155  +  sqlite3BtreeLeave(p);
         2156  +  return SQLITE_OK;
         2157  +}
  2139   2158   
  2140   2159   /*
  2141   2160   ** Change the way data is synced to disk in order to increase or decrease
  2142   2161   ** how well the database resists damage due to OS crashes and power
  2143   2162   ** failures.  Level 1 is the same as asynchronous (no syncs() occur and
  2144   2163   ** there is a high probability of damage)  Level 2 is the default.  There
  2145   2164   ** is a very low but non-zero probability of damage.  Level 3 reduces the
................................................................................
  2358   2377     int nPageFile = 0;   /* Number of pages in the database file */
  2359   2378     int nPageHeader;     /* Number of pages in the database according to hdr */
  2360   2379   
  2361   2380     assert( sqlite3_mutex_held(pBt->mutex) );
  2362   2381     assert( pBt->pPage1==0 );
  2363   2382     rc = sqlite3PagerSharedLock(pBt->pPager);
  2364   2383     if( rc!=SQLITE_OK ) return rc;
  2365         -  rc = btreeGetPage(pBt, 1, &pPage1, 0);
         2384  +  rc = btreeGetPage(pBt, 1, &pPage1, 0, 0);
  2366   2385     if( rc!=SQLITE_OK ) return rc;
  2367   2386   
  2368   2387     /* Do some checking to help insure the file we opened really is
  2369   2388     ** a valid database file. 
  2370   2389     */
  2371   2390     nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
  2372   2391     sqlite3PagerPagecount(pBt->pPager, &nPageFile);
................................................................................
  2917   2936     }
  2918   2937   
  2919   2938     /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
  2920   2939     ** that it points at iFreePage. Also fix the pointer map entry for
  2921   2940     ** iPtrPage.
  2922   2941     */
  2923   2942     if( eType!=PTRMAP_ROOTPAGE ){
  2924         -    rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
         2943  +    rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0);
  2925   2944       if( rc!=SQLITE_OK ){
  2926   2945         return rc;
  2927   2946       }
  2928   2947       rc = sqlite3PagerWrite(pPtrPage->pDbPage);
  2929   2948       if( rc!=SQLITE_OK ){
  2930   2949         releasePage(pPtrPage);
  2931   2950         return rc;
................................................................................
  3001   3020         }
  3002   3021       } else {
  3003   3022         Pgno iFreePg;             /* Index of free page to move pLastPg to */
  3004   3023         MemPage *pLastPg;
  3005   3024         u8 eMode = BTALLOC_ANY;   /* Mode parameter for allocateBtreePage() */
  3006   3025         Pgno iNear = 0;           /* nearby parameter for allocateBtreePage() */
  3007   3026   
  3008         -      rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
         3027  +      rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0);
  3009   3028         if( rc!=SQLITE_OK ){
  3010   3029           return rc;
  3011   3030         }
  3012   3031   
  3013   3032         /* If bCommit is zero, this loop runs exactly once and page pLastPg
  3014   3033         ** is swapped with the first free page pulled off the free list.
  3015   3034         **
................................................................................
  3093   3112       Pgno nOrig = btreePagecount(pBt);
  3094   3113       Pgno nFree = get4byte(&pBt->pPage1->aData[36]);
  3095   3114       Pgno nFin = finalDbSize(pBt, nOrig, nFree);
  3096   3115   
  3097   3116       if( nOrig<nFin ){
  3098   3117         rc = SQLITE_CORRUPT_BKPT;
  3099   3118       }else if( nFree>0 ){
  3100         -      invalidateAllOverflowCache(pBt);
  3101         -      rc = incrVacuumStep(pBt, nFin, nOrig, 0);
         3119  +      rc = saveAllCursors(pBt, 0, 0);
         3120  +      if( rc==SQLITE_OK ){
         3121  +        invalidateAllOverflowCache(pBt);
         3122  +        rc = incrVacuumStep(pBt, nFin, nOrig, 0);
         3123  +      }
  3102   3124         if( rc==SQLITE_OK ){
  3103   3125           rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  3104   3126           put4byte(&pBt->pPage1->aData[28], pBt->nPage);
  3105   3127         }
  3106   3128       }else{
  3107   3129         rc = SQLITE_DONE;
  3108   3130       }
................................................................................
  3142   3164         */
  3143   3165         return SQLITE_CORRUPT_BKPT;
  3144   3166       }
  3145   3167   
  3146   3168       nFree = get4byte(&pBt->pPage1->aData[36]);
  3147   3169       nFin = finalDbSize(pBt, nOrig, nFree);
  3148   3170       if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
  3149         -
         3171  +    if( nFin<nOrig ){
         3172  +      rc = saveAllCursors(pBt, 0, 0);
         3173  +    }
  3150   3174       for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
  3151   3175         rc = incrVacuumStep(pBt, nFin, iFree, 1);
  3152   3176       }
  3153   3177       if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
  3154   3178         rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  3155   3179         put4byte(&pBt->pPage1->aData[32], 0);
  3156   3180         put4byte(&pBt->pPage1->aData[36], 0);
................................................................................
  3159   3183         pBt->nPage = nFin;
  3160   3184       }
  3161   3185       if( rc!=SQLITE_OK ){
  3162   3186         sqlite3PagerRollback(pPager);
  3163   3187       }
  3164   3188     }
  3165   3189   
  3166         -  assert( nRef==sqlite3PagerRefcount(pPager) );
         3190  +  assert( nRef>=sqlite3PagerRefcount(pPager) );
  3167   3191     return rc;
  3168   3192   }
  3169   3193   
  3170   3194   #else /* ifndef SQLITE_OMIT_AUTOVACUUM */
  3171   3195   # define setChildPtrmaps(x) SQLITE_OK
  3172   3196   #endif
  3173   3197   
................................................................................
  3415   3439       if( rc2!=SQLITE_OK ){
  3416   3440         rc = rc2;
  3417   3441       }
  3418   3442   
  3419   3443       /* The rollback may have destroyed the pPage1->aData value.  So
  3420   3444       ** call btreeGetPage() on page 1 again to make
  3421   3445       ** sure pPage1->aData is set correctly. */
  3422         -    if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
         3446  +    if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){
  3423   3447         int nPage = get4byte(28+(u8*)pPage1->aData);
  3424   3448         testcase( nPage==0 );
  3425   3449         if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
  3426   3450         testcase( pBt->nPage!=nPage );
  3427   3451         pBt->nPage = nPage;
  3428   3452         releasePage(pPage1);
  3429   3453       }
................................................................................
  3849   3873         }
  3850   3874       }
  3851   3875     }
  3852   3876   #endif
  3853   3877   
  3854   3878     assert( next==0 || rc==SQLITE_DONE );
  3855   3879     if( rc==SQLITE_OK ){
  3856         -    rc = btreeGetPage(pBt, ovfl, &pPage, 0);
         3880  +    rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0));
  3857   3881       assert( rc==SQLITE_OK || pPage==0 );
  3858   3882       if( rc==SQLITE_OK ){
  3859   3883         next = get4byte(pPage->aData);
  3860   3884       }
  3861   3885     }
  3862   3886   
  3863   3887     *pPgnoNext = next;
................................................................................
  4070   4094             nextPage = get4byte(aWrite);
  4071   4095             memcpy(aWrite, aSave, 4);
  4072   4096           }else
  4073   4097   #endif
  4074   4098   
  4075   4099           {
  4076   4100             DbPage *pDbPage;
  4077         -          rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
         4101  +          rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
         4102  +              (eOp==0 ? PAGER_ACQUIRE_READONLY : 0)
         4103  +          );
  4078   4104             if( rc==SQLITE_OK ){
  4079   4105               aPayload = sqlite3PagerGetData(pDbPage);
  4080   4106               nextPage = get4byte(aPayload);
  4081   4107               rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
  4082   4108               sqlite3PagerUnref(pDbPage);
  4083   4109               offset = 0;
  4084   4110             }
................................................................................
  4249   4275     int i = pCur->iPage;
  4250   4276     MemPage *pNewPage;
  4251   4277     BtShared *pBt = pCur->pBt;
  4252   4278   
  4253   4279     assert( cursorHoldsMutex(pCur) );
  4254   4280     assert( pCur->eState==CURSOR_VALID );
  4255   4281     assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
         4282  +  assert( pCur->iPage>=0 );
  4256   4283     if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
  4257   4284       return SQLITE_CORRUPT_BKPT;
  4258   4285     }
  4259         -  rc = getAndInitPage(pBt, newPgno, &pNewPage);
         4286  +  rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0));
  4260   4287     if( rc ) return rc;
  4261   4288     pCur->apPage[i+1] = pNewPage;
  4262   4289     pCur->aiIdx[i+1] = 0;
  4263   4290     pCur->iPage++;
  4264   4291   
  4265   4292     pCur->info.nSize = 0;
  4266   4293     pCur->validNKey = 0;
................................................................................
  4369   4396         releasePage(pCur->apPage[i]);
  4370   4397       }
  4371   4398       pCur->iPage = 0;
  4372   4399     }else if( pCur->pgnoRoot==0 ){
  4373   4400       pCur->eState = CURSOR_INVALID;
  4374   4401       return SQLITE_OK;
  4375   4402     }else{
  4376         -    rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]);
         4403  +    rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);
  4377   4404       if( rc!=SQLITE_OK ){
  4378   4405         pCur->eState = CURSOR_INVALID;
  4379   4406         return rc;
  4380   4407       }
  4381   4408       pCur->iPage = 0;
  4382   4409   
  4383   4410       /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
................................................................................
  4983   5010         }else{
  4984   5011           iTrunk = get4byte(&pPage1->aData[32]);
  4985   5012         }
  4986   5013         testcase( iTrunk==mxPage );
  4987   5014         if( iTrunk>mxPage ){
  4988   5015           rc = SQLITE_CORRUPT_BKPT;
  4989   5016         }else{
  4990         -        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
         5017  +        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
  4991   5018         }
  4992   5019         if( rc ){
  4993   5020           pTrunk = 0;
  4994   5021           goto end_allocate_page;
  4995   5022         }
  4996   5023         assert( pTrunk!=0 );
  4997   5024         assert( pTrunk->aData!=0 );
................................................................................
  5047   5074             MemPage *pNewTrunk;
  5048   5075             Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
  5049   5076             if( iNewTrunk>mxPage ){ 
  5050   5077               rc = SQLITE_CORRUPT_BKPT;
  5051   5078               goto end_allocate_page;
  5052   5079             }
  5053   5080             testcase( iNewTrunk==mxPage );
  5054         -          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
         5081  +          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0);
  5055   5082             if( rc!=SQLITE_OK ){
  5056   5083               goto end_allocate_page;
  5057   5084             }
  5058   5085             rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
  5059   5086             if( rc!=SQLITE_OK ){
  5060   5087               releasePage(pNewTrunk);
  5061   5088               goto end_allocate_page;
................................................................................
  5127   5154             rc = sqlite3PagerWrite(pTrunk->pDbPage);
  5128   5155             if( rc ) goto end_allocate_page;
  5129   5156             if( closest<k-1 ){
  5130   5157               memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
  5131   5158             }
  5132   5159             put4byte(&aData[4], k-1);
  5133   5160             noContent = !btreeGetHasContent(pBt, *pPgno);
  5134         -          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
         5161  +          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0);
  5135   5162             if( rc==SQLITE_OK ){
  5136   5163               rc = sqlite3PagerWrite((*ppPage)->pDbPage);
  5137   5164               if( rc!=SQLITE_OK ){
  5138   5165                 releasePage(*ppPage);
  5139   5166               }
  5140   5167             }
  5141   5168             searchList = 0;
................................................................................
  5175   5202         /* If *pPgno refers to a pointer-map page, allocate two new pages
  5176   5203         ** at the end of the file instead of one. The first allocated page
  5177   5204         ** becomes a new pointer-map page, the second is used by the caller.
  5178   5205         */
  5179   5206         MemPage *pPg = 0;
  5180   5207         TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
  5181   5208         assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
  5182         -      rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
         5209  +      rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0);
  5183   5210         if( rc==SQLITE_OK ){
  5184   5211           rc = sqlite3PagerWrite(pPg->pDbPage);
  5185   5212           releasePage(pPg);
  5186   5213         }
  5187   5214         if( rc ) return rc;
  5188   5215         pBt->nPage++;
  5189   5216         if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; }
  5190   5217       }
  5191   5218   #endif
  5192   5219       put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
  5193   5220       *pPgno = pBt->nPage;
  5194   5221   
  5195   5222       assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
  5196         -    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
         5223  +    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0);
  5197   5224       if( rc ) return rc;
  5198   5225       rc = sqlite3PagerWrite((*ppPage)->pDbPage);
  5199   5226       if( rc!=SQLITE_OK ){
  5200   5227         releasePage(*ppPage);
  5201   5228       }
  5202   5229       TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
  5203   5230     }
................................................................................
  5257   5284     nFree = get4byte(&pPage1->aData[36]);
  5258   5285     put4byte(&pPage1->aData[36], nFree+1);
  5259   5286   
  5260   5287     if( pBt->btsFlags & BTS_SECURE_DELETE ){
  5261   5288       /* If the secure_delete option is enabled, then
  5262   5289       ** always fully overwrite deleted information with zeros.
  5263   5290       */
  5264         -    if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
         5291  +    if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) )
  5265   5292        ||            ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
  5266   5293       ){
  5267   5294         goto freepage_out;
  5268   5295       }
  5269   5296       memset(pPage->aData, 0, pPage->pBt->pageSize);
  5270   5297     }
  5271   5298   
................................................................................
  5284   5311     ** first trunk page in the current free-list. This block tests if it
  5285   5312     ** is possible to add the page as a new free-list leaf.
  5286   5313     */
  5287   5314     if( nFree!=0 ){
  5288   5315       u32 nLeaf;                /* Initial number of leaf cells on trunk page */
  5289   5316   
  5290   5317       iTrunk = get4byte(&pPage1->aData[32]);
  5291         -    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
         5318  +    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
  5292   5319       if( rc!=SQLITE_OK ){
  5293   5320         goto freepage_out;
  5294   5321       }
  5295   5322   
  5296   5323       nLeaf = get4byte(&pTrunk->aData[4]);
  5297   5324       assert( pBt->usableSize>32 );
  5298   5325       if( nLeaf > (u32)pBt->usableSize/4 - 2 ){
................................................................................
  5330   5357   
  5331   5358     /* If control flows to this point, then it was not possible to add the
  5332   5359     ** the page being freed as a leaf page of the first trunk in the free-list.
  5333   5360     ** Possibly because the free-list is empty, or possibly because the 
  5334   5361     ** first trunk in the free-list is full. Either way, the page being freed
  5335   5362     ** will become the new first trunk page in the free-list.
  5336   5363     */
  5337         -  if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
         5364  +  if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){
  5338   5365       goto freepage_out;
  5339   5366     }
  5340   5367     rc = sqlite3PagerWrite(pPage->pDbPage);
  5341   5368     if( rc!=SQLITE_OK ){
  5342   5369       goto freepage_out;
  5343   5370     }
  5344   5371     put4byte(pPage->aData, iTrunk);
................................................................................
  6131   6158     if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
  6132   6159       pRight = &pParent->aData[pParent->hdrOffset+8];
  6133   6160     }else{
  6134   6161       pRight = findCell(pParent, i+nxDiv-pParent->nOverflow);
  6135   6162     }
  6136   6163     pgno = get4byte(pRight);
  6137   6164     while( 1 ){
  6138         -    rc = getAndInitPage(pBt, pgno, &apOld[i]);
         6165  +    rc = getAndInitPage(pBt, pgno, &apOld[i], 0);
  6139   6166       if( rc ){
  6140   6167         memset(apOld, 0, (i+1)*sizeof(MemPage*));
  6141   6168         goto balance_cleanup;
  6142   6169       }
  6143   6170       nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
  6144   6171       if( (i--)==0 ) break;
  6145   6172   
................................................................................
  7219   7246         ** allocated pgnoMove. If required (i.e. if it was not allocated
  7220   7247         ** by extending the file), the current page at position pgnoMove
  7221   7248         ** is already journaled.
  7222   7249         */
  7223   7250         u8 eType = 0;
  7224   7251         Pgno iPtrPage = 0;
  7225   7252   
         7253  +      /* Save the positions of any open cursors. This is required in
         7254  +      ** case they are holding a reference to an xFetch reference
         7255  +      ** corresponding to page pgnoRoot.  */
         7256  +      rc = saveAllCursors(pBt, 0, 0);
  7226   7257         releasePage(pPageMove);
         7258  +      if( rc!=SQLITE_OK ){
         7259  +        return rc;
         7260  +      }
  7227   7261   
  7228   7262         /* Move the page currently at pgnoRoot to pgnoMove. */
  7229         -      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
         7263  +      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
  7230   7264         if( rc!=SQLITE_OK ){
  7231   7265           return rc;
  7232   7266         }
  7233   7267         rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
  7234   7268         if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
  7235   7269           rc = SQLITE_CORRUPT_BKPT;
  7236   7270         }
................................................................................
  7243   7277         rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
  7244   7278         releasePage(pRoot);
  7245   7279   
  7246   7280         /* Obtain the page at pgnoRoot */
  7247   7281         if( rc!=SQLITE_OK ){
  7248   7282           return rc;
  7249   7283         }
  7250         -      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
         7284  +      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
  7251   7285         if( rc!=SQLITE_OK ){
  7252   7286           return rc;
  7253   7287         }
  7254   7288         rc = sqlite3PagerWrite(pRoot->pDbPage);
  7255   7289         if( rc!=SQLITE_OK ){
  7256   7290           releasePage(pRoot);
  7257   7291           return rc;
................................................................................
  7319   7353     int i;
  7320   7354   
  7321   7355     assert( sqlite3_mutex_held(pBt->mutex) );
  7322   7356     if( pgno>btreePagecount(pBt) ){
  7323   7357       return SQLITE_CORRUPT_BKPT;
  7324   7358     }
  7325   7359   
  7326         -  rc = getAndInitPage(pBt, pgno, &pPage);
         7360  +  rc = getAndInitPage(pBt, pgno, &pPage, 0);
  7327   7361     if( rc ) return rc;
  7328   7362     for(i=0; i<pPage->nCell; i++){
  7329   7363       pCell = findCell(pPage, i);
  7330   7364       if( !pPage->leaf ){
  7331   7365         rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
  7332   7366         if( rc ) goto cleardatabasepage_out;
  7333   7367       }
................................................................................
  7421   7455     ** This error is caught long before control reaches this point.
  7422   7456     */
  7423   7457     if( NEVER(pBt->pCursor) ){
  7424   7458       sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
  7425   7459       return SQLITE_LOCKED_SHAREDCACHE;
  7426   7460     }
  7427   7461   
  7428         -  rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
         7462  +  rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0);
  7429   7463     if( rc ) return rc;
  7430   7464     rc = sqlite3BtreeClearTable(p, iTable, 0);
  7431   7465     if( rc ){
  7432   7466       releasePage(pPage);
  7433   7467       return rc;
  7434   7468     }
  7435   7469   
................................................................................
  7456   7490         }else{
  7457   7491           /* The table being dropped does not have the largest root-page
  7458   7492           ** number in the database. So move the page that does into the 
  7459   7493           ** gap left by the deleted root-page.
  7460   7494           */
  7461   7495           MemPage *pMove;
  7462   7496           releasePage(pPage);
  7463         -        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
         7497  +        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
  7464   7498           if( rc!=SQLITE_OK ){
  7465   7499             return rc;
  7466   7500           }
  7467   7501           rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
  7468   7502           releasePage(pMove);
  7469   7503           if( rc!=SQLITE_OK ){
  7470   7504             return rc;
  7471   7505           }
  7472   7506           pMove = 0;
  7473         -        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
         7507  +        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
  7474   7508           freePage(pMove, &rc);
  7475   7509           releasePage(pMove);
  7476   7510           if( rc!=SQLITE_OK ){
  7477   7511             return rc;
  7478   7512           }
  7479   7513           *piMoved = maxRootPgno;
  7480   7514         }
................................................................................
  7878   7912   
  7879   7913     /* Check that the page exists
  7880   7914     */
  7881   7915     pBt = pCheck->pBt;
  7882   7916     usableSize = pBt->usableSize;
  7883   7917     if( iPage==0 ) return 0;
  7884   7918     if( checkRef(pCheck, iPage, zParentContext) ) return 0;
  7885         -  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
         7919  +  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){
  7886   7920       checkAppendMsg(pCheck, zContext,
  7887   7921          "unable to get the page. error code=%d", rc);
  7888   7922       return 0;
  7889   7923     }
  7890   7924   
  7891   7925     /* Clear MemPage.isInit to make sure the corruption detection code in
  7892   7926     ** btreeInitPage() is executed.  */
................................................................................
  8349   8383     if( rc!=SQLITE_OK ){
  8350   8384       return rc;
  8351   8385     }
  8352   8386     assert( pCsr->eState!=CURSOR_REQUIRESEEK );
  8353   8387     if( pCsr->eState!=CURSOR_VALID ){
  8354   8388       return SQLITE_ABORT;
  8355   8389     }
         8390  +
         8391  +  /* Save the positions of all other cursors open on this table. This is
         8392  +  ** required in case any of them are holding references to an xFetch
         8393  +  ** version of the b-tree page modified by the accessPayload call below.
         8394  +  **
         8395  +  ** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition()
         8396  +  ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
         8397  +  ** saveAllCursors can only return SQLITE_OK.
         8398  +  */
         8399  +  VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
         8400  +  assert( rc==SQLITE_OK );
  8356   8401   
  8357   8402     /* Check some assumptions: 
  8358   8403     **   (a) the cursor is open for writing,
  8359   8404     **   (b) there is a read/write transaction open,
  8360   8405     **   (c) the connection holds a write-lock on the table (if required),
  8361   8406     **   (d) there are no conflicting read-locks, and
  8362   8407     **   (e) the cursor points at a valid row of an intKey table.

Changes to src/btree.h.

    59     59   #define BTREE_OMIT_JOURNAL  1  /* Do not create or use a rollback journal */
    60     60   #define BTREE_MEMORY        2  /* This is an in-memory DB */
    61     61   #define BTREE_SINGLE        4  /* The file contains at most 1 b-tree */
    62     62   #define BTREE_UNORDERED     8  /* Use of a hash implementation is OK */
    63     63   
    64     64   int sqlite3BtreeClose(Btree*);
    65     65   int sqlite3BtreeSetCacheSize(Btree*,int);
           66  +int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
    66     67   int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
    67     68   int sqlite3BtreeSyncDisabled(Btree*);
    68     69   int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
    69     70   int sqlite3BtreeGetPageSize(Btree*);
    70     71   int sqlite3BtreeMaxPageCount(Btree*,int);
    71     72   u32 sqlite3BtreeLastPage(Btree*);
    72     73   int sqlite3BtreeSecureDelete(Btree*,int);

Changes to src/ctime.c.

    44     44   #endif
    45     45   #ifdef SQLITE_CHECK_PAGES
    46     46     "CHECK_PAGES",
    47     47   #endif
    48     48   #ifdef SQLITE_COVERAGE_TEST
    49     49     "COVERAGE_TEST",
    50     50   #endif
    51         -#ifdef SQLITE_CURDIR
    52         -  "CURDIR",
    53         -#endif
    54     51   #ifdef SQLITE_DEBUG
    55     52     "DEBUG",
    56     53   #endif
    57     54   #ifdef SQLITE_DEFAULT_LOCKING_MODE
    58     55     "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
           56  +#endif
           57  +#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
           58  +  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
    59     59   #endif
    60     60   #ifdef SQLITE_DISABLE_DIRSYNC
    61     61     "DISABLE_DIRSYNC",
    62     62   #endif
    63     63   #ifdef SQLITE_DISABLE_LFS
    64     64     "DISABLE_LFS",
    65     65   #endif
................................................................................
   143    143   #endif
   144    144   #ifdef SQLITE_INT64_TYPE
   145    145     "INT64_TYPE",
   146    146   #endif
   147    147   #ifdef SQLITE_LOCK_TRACE
   148    148     "LOCK_TRACE",
   149    149   #endif
          150  +#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
          151  +  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
          152  +#endif
   150    153   #ifdef SQLITE_MAX_SCHEMA_RETRY
   151    154     "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
   152    155   #endif
   153    156   #ifdef SQLITE_MEMDEBUG
   154    157     "MEMDEBUG",
   155    158   #endif
   156    159   #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
................................................................................
   200    203   #endif
   201    204   #ifdef SQLITE_OMIT_CAST
   202    205     "OMIT_CAST",
   203    206   #endif
   204    207   #ifdef SQLITE_OMIT_CHECK
   205    208     "OMIT_CHECK",
   206    209   #endif
   207         -/* // redundant
   208         -** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
   209         -**   "OMIT_COMPILEOPTION_DIAGS",
   210         -** #endif
   211         -*/
   212    210   #ifdef SQLITE_OMIT_COMPLETE
   213    211     "OMIT_COMPLETE",
   214    212   #endif
   215    213   #ifdef SQLITE_OMIT_COMPOUND_SELECT
   216    214     "OMIT_COMPOUND_SELECT",
   217    215   #endif
   218    216   #ifdef SQLITE_OMIT_DATETIME_FUNCS
................................................................................
   346    344   #endif
   347    345   #ifdef SQLITE_SOUNDEX
   348    346     "SOUNDEX",
   349    347   #endif
   350    348   #ifdef SQLITE_TCL
   351    349     "TCL",
   352    350   #endif
   353         -#ifdef SQLITE_TEMP_STORE
          351  +#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
   354    352     "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
   355    353   #endif
   356    354   #ifdef SQLITE_TEST
   357    355     "TEST",
   358    356   #endif
   359         -#ifdef SQLITE_THREADSAFE
          357  +#if defined(SQLITE_THREADSAFE)
   360    358     "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
   361    359   #endif
   362    360   #ifdef SQLITE_USE_ALLOCA
   363    361     "USE_ALLOCA",
   364    362   #endif
   365    363   #ifdef SQLITE_ZERO_MALLOC
   366    364     "ZERO_MALLOC"
................................................................................
   378    376     int i, n;
   379    377     if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
   380    378     n = sqlite3Strlen30(zOptName);
   381    379   
   382    380     /* Since ArraySize(azCompileOpt) is normally in single digits, a
   383    381     ** linear search is adequate.  No need for a binary search. */
   384    382     for(i=0; i<ArraySize(azCompileOpt); i++){
   385         -    if(   (sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0)
   386         -       && ( (azCompileOpt[i][n]==0) || (azCompileOpt[i][n]=='=') ) ) return 1;
          383  +    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
          384  +     && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0
          385  +    ){
          386  +      return 1;
          387  +    }
   387    388     }
   388    389     return 0;
   389    390   }
   390    391   
   391    392   /*
   392    393   ** Return the N-th compile-time option string.  If N is out of range,
   393    394   ** return a NULL pointer.

Changes to src/func.c.

   688    688           return 0;
   689    689         }
   690    690         prevEscape = 0;
   691    691       }
   692    692     }
   693    693     return *zString==0;
   694    694   }
          695  +
          696  +/*
          697  +** The sqlite3_strglob() interface.
          698  +*/
          699  +int sqlite3_strglob(const char *zGlobPattern, const char *zString){
          700  +  return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
          701  +}
   695    702   
   696    703   /*
   697    704   ** Count the number of times that the LIKE operator (or GLOB which is
   698    705   ** just a variation of LIKE) gets called.  This is used for testing
   699    706   ** only.
   700    707   */
   701    708   #ifdef SQLITE_TEST

Changes to src/global.c.

   152    152      500,                       /* nLookaside */
   153    153      {0,0,0,0,0,0,0,0},         /* m */
   154    154      {0,0,0,0,0,0,0,0,0},       /* mutex */
   155    155      {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
   156    156      (void*)0,                  /* pHeap */
   157    157      0,                         /* nHeap */
   158    158      0, 0,                      /* mnHeap, mxHeap */
          159  +   SQLITE_DEFAULT_MMAP_SIZE,  /* szMmap */
          160  +   SQLITE_MAX_MMAP_SIZE,      /* mxMmap */
   159    161      (void*)0,                  /* pScratch */
   160    162      0,                         /* szScratch */
   161    163      0,                         /* nScratch */
   162    164      (void*)0,                  /* pPage */
   163    165      0,                         /* szPage */
   164    166      0,                         /* nPage */
   165    167      0,                         /* mxParserStack */

Changes to src/legacy.c.

    34     34     void *pArg,                 /* First argument to xCallback() */
    35     35     char **pzErrMsg             /* Write error messages here */
    36     36   ){
    37     37     int rc = SQLITE_OK;         /* Return code */
    38     38     const char *zLeftover;      /* Tail of unprocessed SQL */
    39     39     sqlite3_stmt *pStmt = 0;    /* The current SQL statement */
    40     40     char **azCols = 0;          /* Names of result columns */
    41         -  int nRetry = 0;             /* Number of retry attempts */
    42     41     int callbackIsInit;         /* True if callback data is initialized */
    43     42   
    44     43     if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
    45     44     if( zSql==0 ) zSql = "";
    46     45   
    47     46     sqlite3_mutex_enter(db->mutex);
    48     47     sqlite3Error(db, SQLITE_OK, 0);
    49         -  while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
           48  +  while( rc==SQLITE_OK && zSql[0] ){
    50     49       int nCol;
    51     50       char **azVals = 0;
    52     51   
    53     52       pStmt = 0;
    54         -    rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
           53  +    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
    55     54       assert( rc==SQLITE_OK || pStmt==0 );
    56     55       if( rc!=SQLITE_OK ){
    57     56         continue;
    58     57       }
    59     58       if( !pStmt ){
    60     59         /* this happens for a comment or white-space */
    61     60         zSql = zLeftover;
................................................................................
   104    103             goto exec_out;
   105    104           }
   106    105         }
   107    106   
   108    107         if( rc!=SQLITE_ROW ){
   109    108           rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
   110    109           pStmt = 0;
   111         -        if( rc!=SQLITE_SCHEMA ){
   112         -          nRetry = 0;
   113         -          zSql = zLeftover;
   114         -          while( sqlite3Isspace(zSql[0]) ) zSql++;
   115         -        }
          110  +        zSql = zLeftover;
          111  +        while( sqlite3Isspace(zSql[0]) ) zSql++;
   116    112           break;
   117    113         }
   118    114       }
   119    115   
   120    116       sqlite3DbFree(db, azCols);
   121    117       azCols = 0;
   122    118     }

Changes to src/loadext.c.

   411    411     const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
   412    412     char **pzErrMsg       /* Put error message here if not 0 */
   413    413   ){
   414    414     sqlite3_vfs *pVfs = db->pVfs;
   415    415     void *handle;
   416    416     int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   417    417     char *zErrmsg = 0;
          418  +  const char *zEntry;
          419  +  char *zAltEntry = 0;
   418    420     void **aHandle;
   419    421     int nMsg = 300 + sqlite3Strlen30(zFile);
          422  +  int ii;
          423  +
          424  +  /* Shared library endings to try if zFile cannot be loaded as written */
          425  +  static const char *azEndings[] = {
          426  +#if SQLITE_OS_WIN
          427  +     "dll"   
          428  +#elif defined(__APPLE__)
          429  +     "dylib"
          430  +#else
          431  +     "so"
          432  +#endif
          433  +  };
          434  +
   420    435   
   421    436     if( pzErrMsg ) *pzErrMsg = 0;
   422    437   
   423    438     /* Ticket #1863.  To avoid a creating security problems for older
   424    439     ** applications that relink against newer versions of SQLite, the
   425    440     ** ability to run load_extension is turned off by default.  One
   426    441     ** must call sqlite3_enable_load_extension() to turn on extension
................................................................................
   429    444     if( (db->flags & SQLITE_LoadExtension)==0 ){
   430    445       if( pzErrMsg ){
   431    446         *pzErrMsg = sqlite3_mprintf("not authorized");
   432    447       }
   433    448       return SQLITE_ERROR;
   434    449     }
   435    450   
   436         -  if( zProc==0 ){
   437         -    zProc = "sqlite3_extension_init";
   438         -  }
          451  +  zEntry = zProc ? zProc : "sqlite3_extension_init";
   439    452   
   440    453     handle = sqlite3OsDlOpen(pVfs, zFile);
          454  +#if SQLITE_OS_UNIX || SQLITE_OS_WIN
          455  +  for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
          456  +    char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
          457  +    if( zAltFile==0 ) return SQLITE_NOMEM;
          458  +    handle = sqlite3OsDlOpen(pVfs, zAltFile);
          459  +    sqlite3_free(zAltFile);
          460  +  }
          461  +#endif
   441    462     if( handle==0 ){
   442    463       if( pzErrMsg ){
   443    464         *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
   444    465         if( zErrmsg ){
   445    466           sqlite3_snprintf(nMsg, zErrmsg, 
   446    467               "unable to open shared library [%s]", zFile);
   447    468           sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
   448    469         }
   449    470       }
   450    471       return SQLITE_ERROR;
   451    472     }
   452    473     xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
   453         -                   sqlite3OsDlSym(pVfs, handle, zProc);
          474  +                   sqlite3OsDlSym(pVfs, handle, zEntry);
          475  +
          476  +  /* If no entry point was specified and the default legacy
          477  +  ** entry point name "sqlite3_extension_init" was not found, then
          478  +  ** construct an entry point name "sqlite3_X_init" where the X is
          479  +  ** replaced by the lowercase value of every ASCII alphabetic 
          480  +  ** character in the filename after the last "/" upto the first ".",
          481  +  ** and eliding the first three characters if they are "lib".  
          482  +  ** Examples:
          483  +  **
          484  +  **    /usr/local/lib/libExample5.4.3.so ==>  sqlite3_example_init
          485  +  **    C:/lib/mathfuncs.dll              ==>  sqlite3_mathfuncs_init
          486  +  */
          487  +  if( xInit==0 && zProc==0 ){
          488  +    int iFile, iEntry, c;
          489  +    int ncFile = sqlite3Strlen30(zFile);
          490  +    zAltEntry = sqlite3_malloc(ncFile+30);
          491  +    if( zAltEntry==0 ){
          492  +      sqlite3OsDlClose(pVfs, handle);
          493  +      return SQLITE_NOMEM;
          494  +    }
          495  +    memcpy(zAltEntry, "sqlite3_", 8);
          496  +    for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
          497  +    iFile++;
          498  +    if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
          499  +    for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
          500  +      if( sqlite3Isalpha(c) ){
          501  +        zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
          502  +      }
          503  +    }
          504  +    memcpy(zAltEntry+iEntry, "_init", 6);
          505  +    zEntry = zAltEntry;
          506  +    xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
          507  +                     sqlite3OsDlSym(pVfs, handle, zEntry);
          508  +  }
   454    509     if( xInit==0 ){
   455    510       if( pzErrMsg ){
   456         -      nMsg += sqlite3Strlen30(zProc);
          511  +      nMsg += sqlite3Strlen30(zEntry);
   457    512         *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
   458    513         if( zErrmsg ){
   459    514           sqlite3_snprintf(nMsg, zErrmsg,
   460         -            "no entry point [%s] in shared library [%s]", zProc,zFile);
          515  +            "no entry point [%s] in shared library [%s]", zEntry, zFile);
   461    516           sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
   462    517         }
   463         -      sqlite3OsDlClose(pVfs, handle);
   464    518       }
          519  +    sqlite3OsDlClose(pVfs, handle);
          520  +    sqlite3_free(zAltEntry);
   465    521       return SQLITE_ERROR;
   466         -  }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){
          522  +  }
          523  +  sqlite3_free(zAltEntry);
          524  +  if( xInit(db, &zErrmsg, &sqlite3Apis) ){
   467    525       if( pzErrMsg ){
   468    526         *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
   469    527       }
   470    528       sqlite3_free(zErrmsg);
   471    529       sqlite3OsDlClose(pVfs, handle);
   472    530       return SQLITE_ERROR;
   473    531     }

Changes to src/main.c.

   491    491       case SQLITE_CONFIG_SQLLOG: {
   492    492         typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
   493    493         sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
   494    494         sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
   495    495         break;
   496    496       }
   497    497   #endif
          498  +
          499  +    case SQLITE_CONFIG_MMAP_SIZE: {
          500  +      sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64);
          501  +      sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);
          502  +      if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){
          503  +        mxMmap = SQLITE_MAX_MMAP_SIZE;
          504  +      }
          505  +      sqlite3GlobalConfig.mxMmap = mxMmap;
          506  +      if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
          507  +      if( szMmap>mxMmap) szMmap = mxMmap;
          508  +      sqlite3GlobalConfig.szMmap = szMmap;
          509  +      break;
          510  +    }
   498    511   
   499    512       default: {
   500    513         rc = SQLITE_ERROR;
   501    514         break;
   502    515       }
   503    516     }
   504    517     va_end(ap);
................................................................................
  2333   2346     db->magic = SQLITE_MAGIC_BUSY;
  2334   2347     db->aDb = db->aDbStatic;
  2335   2348   
  2336   2349     assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  2337   2350     memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  2338   2351     db->autoCommit = 1;
  2339   2352     db->nextAutovac = -1;
         2353  +  db->szMmap = sqlite3GlobalConfig.szMmap;
  2340   2354     db->nextPagesize = 0;
  2341   2355     db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
  2342   2356   #if SQLITE_DEFAULT_FILE_FORMAT<4
  2343   2357                    | SQLITE_LegacyFileFmt
  2344   2358   #endif
  2345   2359   #ifdef SQLITE_ENABLE_LOAD_EXTENSION
  2346   2360                    | SQLITE_LoadExtension

Changes to src/memjournal.c.

   226    226     0,                /* xCheckReservedLock */
   227    227     0,                /* xFileControl */
   228    228     0,                /* xSectorSize */
   229    229     0,                /* xDeviceCharacteristics */
   230    230     0,                /* xShmMap */
   231    231     0,                /* xShmLock */
   232    232     0,                /* xShmBarrier */
   233         -  0                 /* xShmUnlock */
          233  +  0,                /* xShmUnmap */
          234  +  0,                /* xFetch */
          235  +  0                 /* xUnfetch */
   234    236   };
   235    237   
   236    238   /* 
   237    239   ** Open a journal file.
   238    240   */
   239    241   void sqlite3MemJournalOpen(sqlite3_file *pJfd){
   240    242     MemJournal *p = (MemJournal *)pJfd;

Changes to src/os.c.

   136    136     int pgsz,
   137    137     int bExtend,                    /* True to extend file if necessary */
   138    138     void volatile **pp              /* OUT: Pointer to mapping */
   139    139   ){
   140    140     DO_OS_MALLOC_TEST(id);
   141    141     return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
   142    142   }
          143  +
          144  +#if SQLITE_MAX_MMAP_SIZE>0
          145  +/* The real implementation of xFetch and xUnfetch */
          146  +int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
          147  +  DO_OS_MALLOC_TEST(id);
          148  +  return id->pMethods->xFetch(id, iOff, iAmt, pp);
          149  +}
          150  +int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
          151  +  return id->pMethods->xUnfetch(id, iOff, p);
          152  +}
          153  +#else
          154  +/* No-op stubs to use when memory-mapped I/O is disabled */
          155  +int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
          156  +  *pp = 0;
          157  +  return SQLITE_OK;
          158  +}
          159  +int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
          160  +  return SQLITE_OK;
          161  +}
          162  +#endif
   143    163   
   144    164   /*
   145    165   ** The next group of routines are convenience wrappers around the
   146    166   ** VFS methods.
   147    167   */
   148    168   int sqlite3OsOpen(
   149    169     sqlite3_vfs *pVfs, 

Changes to src/os.h.

    95     95   ** Determine if we are dealing with WinRT, which provides only a subset of
    96     96   ** the full Win32 API.
    97     97   */
    98     98   #if !defined(SQLITE_OS_WINRT)
    99     99   # define SQLITE_OS_WINRT 0
   100    100   #endif
   101    101   
   102         -/*
   103         -** When compiled for WinCE or WinRT, there is no concept of the current
   104         -** directory.
   105         - */
   106         -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
   107         -# define SQLITE_CURDIR 1
   108         -#endif
   109         -
   110    102   /* If the SET_FULLSYNC macro is not defined above, then make it
   111    103   ** a no-op
   112    104   */
   113    105   #ifndef SET_FULLSYNC
   114    106   # define SET_FULLSYNC(x,y)
   115    107   #endif
   116    108   
................................................................................
   255    247   #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
   256    248   int sqlite3OsSectorSize(sqlite3_file *id);
   257    249   int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
   258    250   int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
   259    251   int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
   260    252   void sqlite3OsShmBarrier(sqlite3_file *id);
   261    253   int sqlite3OsShmUnmap(sqlite3_file *id, int);
          254  +int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
          255  +int sqlite3OsUnfetch(sqlite3_file *, i64, void *);
   262    256   
   263    257   
   264    258   /* 
   265    259   ** Functions for accessing sqlite3_vfs methods 
   266    260   */
   267    261   int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
   268    262   int sqlite3OsDelete(sqlite3_vfs *, const char *, int);

Changes to src/os_unix.c.

   221    221     unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
   222    222     int lastErrno;                      /* The unix errno from last I/O error */
   223    223     void *lockingContext;               /* Locking style specific state */
   224    224     UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
   225    225     const char *zPath;                  /* Name of the file */
   226    226     unixShm *pShm;                      /* Shared memory segment information */
   227    227     int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
          228  +  int nFetchOut;                      /* Number of outstanding xFetch refs */
          229  +  sqlite3_int64 mmapSize;             /* Usable size of mapping at pMapRegion */
          230  +  sqlite3_int64 mmapSizeActual;       /* Actual size of mapping at pMapRegion */
          231  +  sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
          232  +  void *pMapRegion;                   /* Memory mapped region */
   228    233   #ifdef __QNXNTO__
   229    234     int sectorSize;                     /* Device sector size */
   230    235     int deviceCharacteristics;          /* Precomputed device characteristics */
   231    236   #endif
   232    237   #if SQLITE_ENABLE_LOCKING_STYLE
   233    238     int openFlags;                      /* The flags specified at open() */
   234    239   #endif
................................................................................
   245    250     ** occur if a file is updated without also updating the transaction
   246    251     ** counter.  This test is made to avoid new problems similar to the
   247    252     ** one described by ticket #3584. 
   248    253     */
   249    254     unsigned char transCntrChng;   /* True if the transaction counter changed */
   250    255     unsigned char dbUpdate;        /* True if any part of database file changed */
   251    256     unsigned char inNormalWrite;   /* True if in a normal write operation */
          257  +
   252    258   #endif
          259  +
   253    260   #ifdef SQLITE_TEST
   254    261     /* In test mode, increase the size of this structure a bit so that 
   255    262     ** it is larger than the struct CrashFile defined in test6.c.
   256    263     */
   257    264     char aPadding[32];
   258    265   #endif
   259    266   };
................................................................................
   269    276   #else
   270    277   # define UNIXFILE_DIRSYNC    0x00
   271    278   #endif
   272    279   #define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
   273    280   #define UNIXFILE_DELETE      0x20     /* Delete on close */
   274    281   #define UNIXFILE_URI         0x40     /* Filename might have query parameters */
   275    282   #define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
          283  +#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() warnings have been issued */
   276    284   
   277    285   /*
   278    286   ** Include code that is common to all os_*.c files
   279    287   */
   280    288   #include "os_common.h"
   281    289   
   282    290   /*
................................................................................
   302    310   */
   303    311   #if SQLITE_THREADSAFE
   304    312   #define threadid pthread_self()
   305    313   #else
   306    314   #define threadid 0
   307    315   #endif
   308    316   
          317  +/*
          318  +** HAVE_MREMAP defaults to true on Linux and false everywhere else.
          319  +*/
          320  +#if !defined(HAVE_MREMAP)
          321  +# if defined(__linux__) && defined(_GNU_SOURCE)
          322  +#  define HAVE_MREMAP 1
          323  +# else
          324  +#  define HAVE_MREMAP 0
          325  +# endif
          326  +#endif
          327  +
   309    328   /*
   310    329   ** Different Unix systems declare open() in different ways.  Same use
   311    330   ** open(const char*,int,mode_t).  Others use open(const char*,int,...).
   312    331   ** The difference is important when using a pointer to the function.
   313    332   **
   314    333   ** The safest way to deal with the problem is to always use this wrapper
   315    334   ** which always has the same well-defined interface.
................................................................................
   433    452   
   434    453     { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
   435    454   #define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)
   436    455   
   437    456     { "fchown",       (sqlite3_syscall_ptr)posixFchown,     0 },
   438    457   #define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
   439    458   
          459  +  { "mmap",       (sqlite3_syscall_ptr)mmap,     0 },
          460  +#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
          461  +
          462  +  { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
          463  +#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
          464  +
          465  +#if HAVE_MREMAP
          466  +  { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
          467  +#else
          468  +  { "mremap",       (sqlite3_syscall_ptr)0,               0 },
          469  +#endif
          470  +#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
          471  +
   440    472   }; /* End of the overrideable system calls */
   441    473   
   442    474   /*
   443    475   ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
   444    476   ** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
   445    477   ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
   446    478   ** system call named zName.
................................................................................
   762    794     case ENOSYS:
   763    795       /* these should force the client to close the file and reconnect */
   764    796       
   765    797     default: 
   766    798       return sqliteIOErr;
   767    799     }
   768    800   }
   769         -
   770    801   
   771    802   
   772    803   /******************************************************************************
   773    804   ****************** Begin Unique File ID Utility Used By VxWorks ***************
   774    805   **
   775    806   ** On most versions of unix, we can get a unique ID for a file by concatenating
   776    807   ** the device number and the inode number.  But this does not work on VxWorks.
................................................................................
  1100   1131     /* This is a threadsafe build, but strerror_r() is not available. */
  1101   1132     zErr = "";
  1102   1133   #else
  1103   1134     /* Non-threadsafe build, use strerror(). */
  1104   1135     zErr = strerror(iErrno);
  1105   1136   #endif
  1106   1137   
  1107         -  assert( errcode!=SQLITE_OK );
  1108   1138     if( zPath==0 ) zPath = "";
  1109   1139     sqlite3_log(errcode,
  1110   1140         "os_unix.c:%d: (%d) %s(%s) - %s",
  1111   1141         iLine, iErrno, zFunc, zPath, zErr
  1112   1142     );
  1113   1143   
  1114   1144     return errcode;
................................................................................
  1265   1295     }else{
  1266   1296       pInode->nRef++;
  1267   1297     }
  1268   1298     *ppInode = pInode;
  1269   1299     return SQLITE_OK;
  1270   1300   }
  1271   1301   
         1302  +
         1303  +/*
         1304  +** Check a unixFile that is a database.  Verify the following:
         1305  +**
         1306  +** (1) There is exactly one hard link on the file
         1307  +** (2) The file is not a symbolic link
         1308  +** (3) The file has not been renamed or unlinked
         1309  +**
         1310  +** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
         1311  +*/
         1312  +static void verifyDbFile(unixFile *pFile){
         1313  +  struct stat buf;
         1314  +  int rc;
         1315  +  if( pFile->ctrlFlags & UNIXFILE_WARNED ){
         1316  +    /* One or more of the following warnings have already been issued.  Do not
         1317  +    ** repeat them so as not to clutter the error log */
         1318  +    return;
         1319  +  }
         1320  +  rc = osFstat(pFile->h, &buf);
         1321  +  if( rc!=0 ){
         1322  +    sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
         1323  +    pFile->ctrlFlags |= UNIXFILE_WARNED;
         1324  +    return;
         1325  +  }
         1326  +  if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
         1327  +    sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
         1328  +    pFile->ctrlFlags |= UNIXFILE_WARNED;
         1329  +    return;
         1330  +  }
         1331  +  if( buf.st_nlink>1 ){
         1332  +    sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
         1333  +    pFile->ctrlFlags |= UNIXFILE_WARNED;
         1334  +    return;
         1335  +  }
         1336  +  if( pFile->pInode!=0
         1337  +   && ((rc = osStat(pFile->zPath, &buf))!=0
         1338  +       || buf.st_ino!=pFile->pInode->fileId.ino)
         1339  +  ){
         1340  +    sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
         1341  +    pFile->ctrlFlags |= UNIXFILE_WARNED;
         1342  +    return;
         1343  +  }
         1344  +}
         1345  +
  1272   1346   
  1273   1347   /*
  1274   1348   ** This routine checks if there is a RESERVED lock held on the specified
  1275   1349   ** file by this or any other process. If such a lock is held, set *pResOut
  1276   1350   ** to a non-zero value otherwise *pResOut is set to zero.  The return value
  1277   1351   ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
  1278   1352   */
................................................................................
  1796   1870   ** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
  1797   1871   ** must be either NO_LOCK or SHARED_LOCK.
  1798   1872   **
  1799   1873   ** If the locking level of the file descriptor is already at or below
  1800   1874   ** the requested locking level, this routine is a no-op.
  1801   1875   */
  1802   1876   static int unixUnlock(sqlite3_file *id, int eFileLock){
         1877  +  assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
  1803   1878     return posixUnlock(id, eFileLock, 0);
  1804   1879   }
         1880  +
         1881  +static int unixMapfile(unixFile *pFd, i64 nByte);
         1882  +static void unixUnmapfile(unixFile *pFd);
  1805   1883   
  1806   1884   /*
  1807   1885   ** This function performs the parts of the "close file" operation 
  1808   1886   ** common to all locking schemes. It closes the directory and file
  1809   1887   ** handles, if they are valid, and sets all fields of the unixFile
  1810   1888   ** structure to 0.
  1811   1889   **
  1812   1890   ** It is *not* necessary to hold the mutex when this routine is called,
  1813   1891   ** even on VxWorks.  A mutex will be acquired on VxWorks by the
  1814   1892   ** vxworksReleaseFileId() routine.
  1815   1893   */
  1816   1894   static int closeUnixFile(sqlite3_file *id){
  1817   1895     unixFile *pFile = (unixFile*)id;
         1896  +  unixUnmapfile(pFile);
  1818   1897     if( pFile->h>=0 ){
  1819   1898       robust_close(pFile, pFile->h, __LINE__);
  1820   1899       pFile->h = -1;
  1821   1900     }
  1822   1901   #if OS_VXWORKS
  1823   1902     if( pFile->pId ){
  1824   1903       if( pFile->ctrlFlags & UNIXFILE_DELETE ){
................................................................................
  1837   1916   
  1838   1917   /*
  1839   1918   ** Close a file.
  1840   1919   */
  1841   1920   static int unixClose(sqlite3_file *id){
  1842   1921     int rc = SQLITE_OK;
  1843   1922     unixFile *pFile = (unixFile *)id;
         1923  +  verifyDbFile(pFile);
  1844   1924     unixUnlock(id, NO_LOCK);
  1845   1925     unixEnterMutex();
  1846   1926   
  1847   1927     /* unixFile.pInode is always valid here. Otherwise, a different close
  1848   1928     ** routine (e.g. nolockClose()) would be called instead.
  1849   1929     */
  1850   1930     assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
................................................................................
  3077   3157     ** file), the bytes in the locking range should never be read or written. */
  3078   3158   #if 0
  3079   3159     assert( pFile->pUnused==0
  3080   3160          || offset>=PENDING_BYTE+512
  3081   3161          || offset+amt<=PENDING_BYTE 
  3082   3162     );
  3083   3163   #endif
         3164  +
         3165  +#if SQLITE_MAX_MMAP_SIZE>0
         3166  +  /* Deal with as much of this read request as possible by transfering
         3167  +  ** data from the memory mapping using memcpy().  */
         3168  +  if( offset<pFile->mmapSize ){
         3169  +    if( offset+amt <= pFile->mmapSize ){
         3170  +      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
         3171  +      return SQLITE_OK;
         3172  +    }else{
         3173  +      int nCopy = pFile->mmapSize - offset;
         3174  +      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
         3175  +      pBuf = &((u8 *)pBuf)[nCopy];
         3176  +      amt -= nCopy;
         3177  +      offset += nCopy;
         3178  +    }
         3179  +  }
         3180  +#endif
  3084   3181   
  3085   3182     got = seekAndRead(pFile, offset, pBuf, amt);
  3086   3183     if( got==amt ){
  3087   3184       return SQLITE_OK;
  3088   3185     }else if( got<0 ){
  3089   3186       /* lastErrno set by seekAndRead */
  3090   3187       return SQLITE_IOERR_READ;
................................................................................
  3179   3276         SimulateIOErrorBenign(1);
  3180   3277         rc = seekAndRead(pFile, 24, oldCntr, 4);
  3181   3278         SimulateIOErrorBenign(0);
  3182   3279         if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
  3183   3280           pFile->transCntrChng = 1;  /* The transaction counter has changed */
  3184   3281         }
  3185   3282       }
         3283  +  }
         3284  +#endif
         3285  +
         3286  +#if SQLITE_MAX_MMAP_SIZE>0
         3287  +  /* Deal with as much of this write request as possible by transfering
         3288  +  ** data from the memory mapping using memcpy().  */
         3289  +  if( offset<pFile->mmapSize ){
         3290  +    if( offset+amt <= pFile->mmapSize ){
         3291  +      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
         3292  +      return SQLITE_OK;
         3293  +    }else{
         3294  +      int nCopy = pFile->mmapSize - offset;
         3295  +      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
         3296  +      pBuf = &((u8 *)pBuf)[nCopy];
         3297  +      amt -= nCopy;
         3298  +      offset += nCopy;
         3299  +    }
  3186   3300     }
  3187   3301   #endif
  3188   3302   
  3189   3303     while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
  3190   3304       amt -= wrote;
  3191   3305       offset += wrote;
  3192   3306       pBuf = &((char*)pBuf)[wrote];
................................................................................
  3463   3577       ** when restoring a database using the backup API from a zero-length
  3464   3578       ** source.
  3465   3579       */
  3466   3580       if( pFile->inNormalWrite && nByte==0 ){
  3467   3581         pFile->transCntrChng = 1;
  3468   3582       }
  3469   3583   #endif
         3584  +
         3585  +    /* If the file was just truncated to a size smaller than the currently
         3586  +    ** mapped region, reduce the effective mapping size as well. SQLite will
         3587  +    ** use read() and write() to access data beyond this point from now on.  
         3588  +    */
         3589  +    if( nByte<pFile->mmapSize ){
         3590  +      pFile->mmapSize = nByte;
         3591  +    }
  3470   3592   
  3471   3593       return SQLITE_OK;
  3472   3594     }
  3473   3595   }
  3474   3596   
  3475   3597   /*
  3476   3598   ** Determine the current size of a file in bytes
................................................................................
  3551   3673           int nWrite = seekAndWrite(pFile, iWrite, "", 1);
  3552   3674           if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
  3553   3675           iWrite += nBlk;
  3554   3676         }
  3555   3677   #endif
  3556   3678       }
  3557   3679     }
         3680  +
         3681  +  if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
         3682  +    int rc;
         3683  +    if( pFile->szChunk<=0 ){
         3684  +      if( robust_ftruncate(pFile->h, nByte) ){
         3685  +        pFile->lastErrno = errno;
         3686  +        return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
         3687  +      }
         3688  +    }
         3689  +
         3690  +    rc = unixMapfile(pFile, nByte);
         3691  +    return rc;
         3692  +  }
  3558   3693   
  3559   3694     return SQLITE_OK;
  3560   3695   }
  3561   3696   
  3562   3697   /*
  3563   3698   ** If *pArg is inititially negative then this is a query.  Set *pArg to
  3564   3699   ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
................................................................................
  3618   3753       case SQLITE_FCNTL_TEMPFILENAME: {
  3619   3754         char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
  3620   3755         if( zTFile ){
  3621   3756           unixGetTempname(pFile->pVfs->mxPathname, zTFile);
  3622   3757           *(char**)pArg = zTFile;
  3623   3758         }
  3624   3759         return SQLITE_OK;
         3760  +    }
         3761  +    case SQLITE_FCNTL_MMAP_SIZE: {
         3762  +      i64 newLimit = *(i64*)pArg;
         3763  +      if( newLimit>sqlite3GlobalConfig.mxMmap ){
         3764  +        newLimit = sqlite3GlobalConfig.mxMmap;
         3765  +      }
         3766  +      *(i64*)pArg = pFile->mmapSizeMax;
         3767  +      if( newLimit>=0 ){
         3768  +        pFile->mmapSizeMax = newLimit;
         3769  +        if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;
         3770  +      }
         3771  +      return SQLITE_OK;
  3625   3772       }
  3626   3773   #ifdef SQLITE_DEBUG
  3627   3774       /* The pager calls this method to signal that it has done
  3628   3775       ** a rollback and that the database is therefore unchanged and
  3629   3776       ** it hence it is OK for the transaction change counter to be
  3630   3777       ** unchanged.
  3631   3778       */
................................................................................
  3931   4078     assert( unixMutexHeld() );
  3932   4079     if( p && p->nRef==0 ){
  3933   4080       int i;
  3934   4081       assert( p->pInode==pFd->pInode );
  3935   4082       sqlite3_mutex_free(p->mutex);
  3936   4083       for(i=0; i<p->nRegion; i++){
  3937   4084         if( p->h>=0 ){
  3938         -        munmap(p->apRegion[i], p->szRegion);
         4085  +        osMunmap(p->apRegion[i], p->szRegion);
  3939   4086         }else{
  3940   4087           sqlite3_free(p->apRegion[i]);
  3941   4088         }
  3942   4089       }
  3943   4090       sqlite3_free(p->apRegion);
  3944   4091       if( p->h>=0 ){
  3945   4092         robust_close(pFd, p->h, __LINE__);
................................................................................
  4204   4351         rc = SQLITE_IOERR_NOMEM;
  4205   4352         goto shmpage_out;
  4206   4353       }
  4207   4354       pShmNode->apRegion = apNew;
  4208   4355       while(pShmNode->nRegion<=iRegion){
  4209   4356         void *pMem;
  4210   4357         if( pShmNode->h>=0 ){
  4211         -        pMem = mmap(0, szRegion,
         4358  +        pMem = osMmap(0, szRegion,
  4212   4359               pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
  4213   4360               MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
  4214   4361           );
  4215   4362           if( pMem==MAP_FAILED ){
  4216   4363             rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
  4217   4364             goto shmpage_out;
  4218   4365           }
................................................................................
  4420   4567   
  4421   4568   #else
  4422   4569   # define unixShmMap     0
  4423   4570   # define unixShmLock    0
  4424   4571   # define unixShmBarrier 0
  4425   4572   # define unixShmUnmap   0
  4426   4573   #endif /* #ifndef SQLITE_OMIT_WAL */
         4574  +
         4575  +/*
         4576  +** If it is currently memory mapped, unmap file pFd.
         4577  +*/
         4578  +static void unixUnmapfile(unixFile *pFd){
         4579  +  assert( pFd->nFetchOut==0 );
         4580  +#if SQLITE_MAX_MMAP_SIZE>0
         4581  +  if( pFd->pMapRegion ){
         4582  +    osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
         4583  +    pFd->pMapRegion = 0;
         4584  +    pFd->mmapSize = 0;
         4585  +    pFd->mmapSizeActual = 0;
         4586  +  }
         4587  +#endif
         4588  +}
         4589  +
         4590  +#if SQLITE_MAX_MMAP_SIZE>0
         4591  +/*
         4592  +** Return the system page size.
         4593  +*/
         4594  +static int unixGetPagesize(void){
         4595  +#if HAVE_MREMAP
         4596  +  return 512;
         4597  +#elif defined(_BSD_SOURCE)
         4598  +  return getpagesize();
         4599  +#else
         4600  +  return (int)sysconf(_SC_PAGESIZE);
         4601  +#endif
         4602  +}
         4603  +#endif /* SQLITE_MAX_MMAP_SIZE>0 */
         4604  +
         4605  +#if SQLITE_MAX_MMAP_SIZE>0
         4606  +/*
         4607  +** Attempt to set the size of the memory mapping maintained by file 
         4608  +** descriptor pFd to nNew bytes. Any existing mapping is discarded.
         4609  +**
         4610  +** If successful, this function sets the following variables:
         4611  +**
         4612  +**       unixFile.pMapRegion
         4613  +**       unixFile.mmapSize
         4614  +**       unixFile.mmapSizeActual
         4615  +**
         4616  +** If unsuccessful, an error message is logged via sqlite3_log() and
         4617  +** the three variables above are zeroed. In this case SQLite should
         4618  +** continue accessing the database using the xRead() and xWrite()
         4619  +** methods.
         4620  +*/
         4621  +static void unixRemapfile(
         4622  +  unixFile *pFd,                  /* File descriptor object */
         4623  +  i64 nNew                        /* Required mapping size */
         4624  +){
         4625  +  const char *zErr = "mmap";
         4626  +  int h = pFd->h;                      /* File descriptor open on db file */
         4627  +  u8 *pOrig = (u8 *)pFd->pMapRegion;   /* Pointer to current file mapping */
         4628  +  i64 nOrig = pFd->mmapSizeActual;     /* Size of pOrig region in bytes */
         4629  +  u8 *pNew = 0;                        /* Location of new mapping */
         4630  +  int flags = PROT_READ;               /* Flags to pass to mmap() */
         4631  +
         4632  +  assert( pFd->nFetchOut==0 );
         4633  +  assert( nNew>pFd->mmapSize );
         4634  +  assert( nNew<=pFd->mmapSizeMax );
         4635  +  assert( nNew>0 );
         4636  +  assert( pFd->mmapSizeActual>=pFd->mmapSize );
         4637  +  assert( MAP_FAILED!=0 );
         4638  +
         4639  +  if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
         4640  +
         4641  +  if( pOrig ){
         4642  +    const int szSyspage = unixGetPagesize();
         4643  +    i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
         4644  +    u8 *pReq = &pOrig[nReuse];
         4645  +
         4646  +    /* Unmap any pages of the existing mapping that cannot be reused. */
         4647  +    if( nReuse!=nOrig ){
         4648  +      osMunmap(pReq, nOrig-nReuse);
         4649  +    }
         4650  +
         4651  +#if HAVE_MREMAP
         4652  +    pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE);
         4653  +    zErr = "mremap";
         4654  +#else
         4655  +    pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse);
         4656  +    if( pNew!=MAP_FAILED ){
         4657  +      if( pNew!=pReq ){
         4658  +        osMunmap(pNew, nNew - nReuse);
         4659  +        pNew = 0;
         4660  +      }else{
         4661  +        pNew = pOrig;
         4662  +      }
         4663  +    }
         4664  +#endif
         4665  +
         4666  +    /* The attempt to extend the existing mapping failed. Free it. */
         4667  +    if( pNew==MAP_FAILED || pNew==0 ){
         4668  +      osMunmap(pOrig, nReuse);
         4669  +    }
         4670  +  }
         4671  +
         4672  +  /* If pNew is still NULL, try to create an entirely new mapping. */
         4673  +  if( pNew==0 ){
         4674  +    pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0);
         4675  +  }
         4676  +
         4677  +  if( pNew==MAP_FAILED ){
         4678  +    pNew = 0;
         4679  +    nNew = 0;
         4680  +    unixLogError(SQLITE_OK, zErr, pFd->zPath);
         4681  +
         4682  +    /* If the mmap() above failed, assume that all subsequent mmap() calls
         4683  +    ** will probably fail too. Fall back to using xRead/xWrite exclusively
         4684  +    ** in this case.  */
         4685  +    pFd->mmapSizeMax = 0;
         4686  +  }
         4687  +  pFd->pMapRegion = (void *)pNew;
         4688  +  pFd->mmapSize = pFd->mmapSizeActual = nNew;
         4689  +}
         4690  +#endif
         4691  +
         4692  +/*
         4693  +** Memory map or remap the file opened by file-descriptor pFd (if the file
         4694  +** is already mapped, the existing mapping is replaced by the new). Or, if 
         4695  +** there already exists a mapping for this file, and there are still 
         4696  +** outstanding xFetch() references to it, this function is a no-op.
         4697  +**
         4698  +** If parameter nByte is non-negative, then it is the requested size of 
         4699  +** the mapping to create. Otherwise, if nByte is less than zero, then the 
         4700  +** requested size is the size of the file on disk. The actual size of the
         4701  +** created mapping is either the requested size or the value configured 
         4702  +** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
         4703  +**
         4704  +** SQLITE_OK is returned if no error occurs (even if the mapping is not
         4705  +** recreated as a result of outstanding references) or an SQLite error
         4706  +** code otherwise.
         4707  +*/
         4708  +static int unixMapfile(unixFile *pFd, i64 nByte){
         4709  +#if SQLITE_MAX_MMAP_SIZE>0
         4710  +  i64 nMap = nByte;
         4711  +  int rc;
         4712  +
         4713  +  assert( nMap>=0 || pFd->nFetchOut==0 );
         4714  +  if( pFd->nFetchOut>0 ) return SQLITE_OK;
         4715  +
         4716  +  if( nMap<0 ){
         4717  +    struct stat statbuf;          /* Low-level file information */
         4718  +    rc = osFstat(pFd->h, &statbuf);
         4719  +    if( rc!=SQLITE_OK ){
         4720  +      return SQLITE_IOERR_FSTAT;
         4721  +    }
         4722  +    nMap = statbuf.st_size;
         4723  +  }
         4724  +  if( nMap>pFd->mmapSizeMax ){
         4725  +    nMap = pFd->mmapSizeMax;
         4726  +  }
         4727  +
         4728  +  if( nMap!=pFd->mmapSize ){
         4729  +    if( nMap>0 ){
         4730  +      unixRemapfile(pFd, nMap);
         4731  +    }else{
         4732  +      unixUnmapfile(pFd);
         4733  +    }
         4734  +  }
         4735  +#endif
         4736  +
         4737  +  return SQLITE_OK;
         4738  +}
         4739  +
         4740  +/*
         4741  +** If possible, return a pointer to a mapping of file fd starting at offset
         4742  +** iOff. The mapping must be valid for at least nAmt bytes.
         4743  +**
         4744  +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
         4745  +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
         4746  +** Finally, if an error does occur, return an SQLite error code. The final
         4747  +** value of *pp is undefined in this case.
         4748  +**
         4749  +** If this function does return a pointer, the caller must eventually 
         4750  +** release the reference by calling unixUnfetch().
         4751  +*/
         4752  +static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
         4753  +#if SQLITE_MAX_MMAP_SIZE>0
         4754  +  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
         4755  +#endif
         4756  +  *pp = 0;
         4757  +
         4758  +#if SQLITE_MAX_MMAP_SIZE>0
         4759  +  if( pFd->mmapSizeMax>0 ){
         4760  +    if( pFd->pMapRegion==0 ){
         4761  +      int rc = unixMapfile(pFd, -1);
         4762  +      if( rc!=SQLITE_OK ) return rc;
         4763  +    }
         4764  +    if( pFd->mmapSize >= iOff+nAmt ){
         4765  +      *pp = &((u8 *)pFd->pMapRegion)[iOff];
         4766  +      pFd->nFetchOut++;
         4767  +    }
         4768  +  }
         4769  +#endif
         4770  +  return SQLITE_OK;
         4771  +}
         4772  +
         4773  +/*
         4774  +** If the third argument is non-NULL, then this function releases a 
         4775  +** reference obtained by an earlier call to unixFetch(). The second
         4776  +** argument passed to this function must be the same as the corresponding
         4777  +** argument that was passed to the unixFetch() invocation. 
         4778  +**
         4779  +** Or, if the third argument is NULL, then this function is being called 
         4780  +** to inform the VFS layer that, according to POSIX, any existing mapping 
         4781  +** may now be invalid and should be unmapped.
         4782  +*/
         4783  +static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
         4784  +  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
         4785  +  UNUSED_PARAMETER(iOff);
         4786  +
         4787  +  /* If p==0 (unmap the entire file) then there must be no outstanding 
         4788  +  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
         4789  +  ** then there must be at least one outstanding.  */
         4790  +  assert( (p==0)==(pFd->nFetchOut==0) );
         4791  +
         4792  +  /* If p!=0, it must match the iOff value. */
         4793  +  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
         4794  +
         4795  +  if( p ){
         4796  +    pFd->nFetchOut--;
         4797  +  }else{
         4798  +    unixUnmapfile(pFd);
         4799  +  }
         4800  +
         4801  +  assert( pFd->nFetchOut>=0 );
         4802  +  return SQLITE_OK;
         4803  +}
  4427   4804   
  4428   4805   /*
  4429   4806   ** Here ends the implementation of all sqlite3_file methods.
  4430   4807   **
  4431   4808   ********************** End sqlite3_file Methods *******************************
  4432   4809   ******************************************************************************/
  4433   4810   
................................................................................
  4479   4856      CKLOCK,                     /* xCheckReservedLock */                      \
  4480   4857      unixFileControl,            /* xFileControl */                            \
  4481   4858      unixSectorSize,             /* xSectorSize */                             \
  4482   4859      unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
  4483   4860      unixShmMap,                 /* xShmMap */                                 \
  4484   4861      unixShmLock,                /* xShmLock */                                \
  4485   4862      unixShmBarrier,             /* xShmBarrier */                             \
  4486         -   unixShmUnmap                /* xShmUnmap */                               \
         4863  +   unixShmUnmap,               /* xShmUnmap */                               \
         4864  +   unixFetch,                  /* xFetch */                                  \
         4865  +   unixUnfetch,                /* xUnfetch */                                \
  4487   4866   };                                                                           \
  4488   4867   static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
  4489   4868     UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \
  4490   4869     return &METHOD;                                                            \
  4491   4870   }                                                                            \
  4492   4871   static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p)    \
  4493   4872       = FINDER##Impl;
................................................................................
  4496   4875   ** Here are all of the sqlite3_io_methods objects for each of the
  4497   4876   ** locking strategies.  Functions that return pointers to these methods
  4498   4877   ** are also created.
  4499   4878   */
  4500   4879   IOMETHODS(
  4501   4880     posixIoFinder,            /* Finder function name */
  4502   4881     posixIoMethods,           /* sqlite3_io_methods object name */
  4503         -  2,                        /* shared memory is enabled */
         4882  +  3,                        /* shared memory and mmap are enabled */
  4504   4883     unixClose,                /* xClose method */
  4505   4884     unixLock,                 /* xLock method */
  4506   4885     unixUnlock,               /* xUnlock method */
  4507   4886     unixCheckReservedLock     /* xCheckReservedLock method */
  4508   4887   )
  4509   4888   IOMETHODS(
  4510   4889     nolockIoFinder,           /* Finder function name */
................................................................................
  4747   5126     assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
  4748   5127   
  4749   5128     OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  4750   5129     pNew->h = h;
  4751   5130     pNew->pVfs = pVfs;
  4752   5131     pNew->zPath = zFilename;
  4753   5132     pNew->ctrlFlags = (u8)ctrlFlags;
         5133  +  pNew->mmapSizeMax = sqlite3GlobalConfig.mxMmap;
  4754   5134     if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
  4755   5135                              "psow", SQLITE_POWERSAFE_OVERWRITE) ){
  4756   5136       pNew->ctrlFlags |= UNIXFILE_PSOW;
  4757   5137     }
  4758   5138     if( strcmp(pVfs->zName,"unix-excl")==0 ){
  4759   5139       pNew->ctrlFlags |= UNIXFILE_EXCL;
  4760   5140     }
................................................................................
  4891   5271     if( isDelete ) pNew->ctrlFlags |= UNIXFILE_DELETE;
  4892   5272   #endif
  4893   5273     if( rc!=SQLITE_OK ){
  4894   5274       if( h>=0 ) robust_close(pNew, h, __LINE__);
  4895   5275     }else{
  4896   5276       pNew->pMethod = pLockingStyle;
  4897   5277       OpenCounter(+1);
         5278  +    verifyDbFile(pNew);
  4898   5279     }
  4899   5280     return rc;
  4900   5281   }
  4901   5282   
  4902   5283   /*
  4903   5284   ** Return the name of a directory in which to put temporary files.
  4904   5285   ** If no suitable temporary file directory can be found, return NULL.
................................................................................
  6984   7365       UNIXVFS("unix-proxy",    proxyIoFinder ),
  6985   7366   #endif
  6986   7367     };
  6987   7368     unsigned int i;          /* Loop counter */
  6988   7369   
  6989   7370     /* Double-check that the aSyscall[] array has been constructed
  6990   7371     ** correctly.  See ticket [bb3a86e890c8e96ab] */
  6991         -  assert( ArraySize(aSyscall)==21 );
         7372  +  assert( ArraySize(aSyscall)==24 );
  6992   7373   
  6993   7374     /* Register all VFSes defined in the aVfs[] array */
  6994   7375     for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
  6995   7376       sqlite3_vfs_register(&aVfs[i], i==0);
  6996   7377     }
  6997   7378     return SQLITE_OK; 
  6998   7379   }

Changes to src/os_win.c.

   146    146   #if SQLITE_OS_WINCE
   147    147     LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
   148    148     HANDLE hMutex;          /* Mutex used to control access to shared lock */  
   149    149     HANDLE hShared;         /* Shared memory segment used for locking */
   150    150     winceLock local;        /* Locks obtained by this instance of winFile */
   151    151     winceLock *shared;      /* Global shared lock memory for the file  */
   152    152   #endif
          153  +#if SQLITE_MAX_MMAP_SIZE>0
          154  +  int nFetchOut;                /* Number of outstanding xFetch references */
          155  +  HANDLE hMap;                  /* Handle for accessing memory mapping */
          156  +  void *pMapRegion;             /* Area memory mapped */
          157  +  sqlite3_int64 mmapSize;       /* Usable size of mapped region */
          158  +  sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
          159  +  sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
          160  +#endif
   153    161   };
   154    162   
   155    163   /*
   156    164   ** Allowed values for winFile.ctrlFlags
   157    165   */
          166  +#define WINFILE_RDONLY          0x02   /* Connection is read only */
   158    167   #define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
   159    168   #define WINFILE_PSOW            0x10   /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
   160    169   
   161    170   /*
   162    171    * The size of the buffer used by sqlite3_win32_write_debug().
   163    172    */
   164    173   #ifndef SQLITE_WIN32_DBG_BUF_SIZE
................................................................................
  2057   2066       return 1;
  2058   2067     }
  2059   2068   
  2060   2069     return 0;
  2061   2070   #endif
  2062   2071   }
  2063   2072   
         2073  +#if SQLITE_MAX_MMAP_SIZE>0
         2074  +/* Forward references to VFS methods */
         2075  +static int winUnmapfile(winFile*);
         2076  +#endif
         2077  +
  2064   2078   /*
  2065   2079   ** Close a file.
  2066   2080   **
  2067   2081   ** It is reported that an attempt to close a handle might sometimes
  2068   2082   ** fail.  This is a very unreasonable result, but Windows is notorious
  2069   2083   ** for being unreasonable so I do not doubt that it might happen.  If
  2070   2084   ** the close fails, we pause for 100 milliseconds and try again.  As
................................................................................
  2078   2092   
  2079   2093     assert( id!=0 );
  2080   2094   #ifndef SQLITE_OMIT_WAL
  2081   2095     assert( pFile->pShm==0 );
  2082   2096   #endif
  2083   2097     OSTRACE(("CLOSE %d\n", pFile->h));
  2084   2098     assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
         2099  +
         2100  +#if SQLITE_MAX_MMAP_SIZE>0
         2101  +  rc = winUnmapfile(pFile);
         2102  +  if( rc!=SQLITE_OK ) return rc;
         2103  +#endif
         2104  +
  2085   2105     do{
  2086   2106       rc = osCloseHandle(pFile->h);
  2087   2107       /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
  2088   2108     }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
  2089   2109   #if SQLITE_OS_WINCE
  2090   2110   #define WINCE_DELETION_ATTEMPTS 3
  2091   2111     winceDestroyLock(pFile);
................................................................................
  2126   2146     OVERLAPPED overlapped;          /* The offset for ReadFile. */
  2127   2147   #endif
  2128   2148     winFile *pFile = (winFile*)id;  /* file handle */
  2129   2149     DWORD nRead;                    /* Number of bytes actually read from file */
  2130   2150     int nRetry = 0;                 /* Number of retrys */
  2131   2151   
  2132   2152     assert( id!=0 );
         2153  +  assert( amt>0 );
  2133   2154     SimulateIOError(return SQLITE_IOERR_READ);
  2134   2155     OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
         2156  +
         2157  +#if SQLITE_MAX_MMAP_SIZE>0
         2158  +  /* Deal with as much of this read request as possible by transfering
         2159  +  ** data from the memory mapping using memcpy().  */
         2160  +  if( offset<pFile->mmapSize ){
         2161  +    if( offset+amt <= pFile->mmapSize ){
         2162  +      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
         2163  +      return SQLITE_OK;
         2164  +    }else{
         2165  +      int nCopy = (int)(pFile->mmapSize - offset);
         2166  +      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
         2167  +      pBuf = &((u8 *)pBuf)[nCopy];
         2168  +      amt -= nCopy;
         2169  +      offset += nCopy;
         2170  +    }
         2171  +  }
         2172  +#endif
  2135   2173   
  2136   2174   #if SQLITE_OS_WINCE
  2137   2175     if( seekWinFile(pFile, offset) ){
  2138   2176       return SQLITE_FULL;
  2139   2177     }
  2140   2178     while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
  2141   2179   #else
................................................................................
  2177   2215   
  2178   2216     assert( amt>0 );
  2179   2217     assert( pFile );
  2180   2218     SimulateIOError(return SQLITE_IOERR_WRITE);
  2181   2219     SimulateDiskfullError(return SQLITE_FULL);
  2182   2220   
  2183   2221     OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
         2222  +
         2223  +#if SQLITE_MAX_MMAP_SIZE>0
         2224  +  /* Deal with as much of this write request as possible by transfering
         2225  +  ** data from the memory mapping using memcpy().  */
         2226  +  if( offset<pFile->mmapSize ){
         2227  +    if( offset+amt <= pFile->mmapSize ){
         2228  +      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
         2229  +      return SQLITE_OK;
         2230  +    }else{
         2231  +      int nCopy = (int)(pFile->mmapSize - offset);
         2232  +      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
         2233  +      pBuf = &((u8 *)pBuf)[nCopy];
         2234  +      amt -= nCopy;
         2235  +      offset += nCopy;
         2236  +    }
         2237  +  }
         2238  +#endif
  2184   2239   
  2185   2240   #if SQLITE_OS_WINCE
  2186   2241     rc = seekWinFile(pFile, offset);
  2187   2242     if( rc==0 ){
  2188   2243   #else
  2189   2244     {
  2190   2245   #endif
................................................................................
  2245   2300   
  2246   2301   /*
  2247   2302   ** Truncate an open file to a specified size
  2248   2303   */
  2249   2304   static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
  2250   2305     winFile *pFile = (winFile*)id;  /* File handle object */
  2251   2306     int rc = SQLITE_OK;             /* Return code for this function */
         2307  +  DWORD lastErrno;
  2252   2308   
  2253   2309     assert( pFile );
  2254   2310   
  2255   2311     OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
  2256   2312     SimulateIOError(return SQLITE_IOERR_TRUNCATE);
  2257   2313   
  2258   2314     /* If the user has configured a chunk-size for this file, truncate the
................................................................................
  2263   2319     if( pFile->szChunk>0 ){
  2264   2320       nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  2265   2321     }
  2266   2322   
  2267   2323     /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  2268   2324     if( seekWinFile(pFile, nByte) ){
  2269   2325       rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
  2270         -             "winTruncate1", pFile->zPath);
  2271         -  }else if( 0==osSetEndOfFile(pFile->h) ){
  2272         -    pFile->lastErrno = osGetLastError();
         2326  +                     "winTruncate1", pFile->zPath);
         2327  +  }else if( 0==osSetEndOfFile(pFile->h) &&
         2328  +            ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
         2329  +    pFile->lastErrno = lastErrno;
  2273   2330       rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
  2274         -             "winTruncate2", pFile->zPath);
         2331  +                     "winTruncate2", pFile->zPath);
  2275   2332     }
         2333  +
         2334  +#if SQLITE_MAX_MMAP_SIZE>0
         2335  +  /* If the file was truncated to a size smaller than the currently
         2336  +  ** mapped region, reduce the effective mapping size as well. SQLite will
         2337  +  ** use read() and write() to access data beyond this point from now on.
         2338  +  */
         2339  +  if( pFile->pMapRegion && nByte<pFile->mmapSize ){
         2340  +    pFile->mmapSize = nByte;
         2341  +  }
         2342  +#endif
  2276   2343   
  2277   2344     OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
  2278   2345     return rc;
  2279   2346   }
  2280   2347   
  2281   2348   #ifdef SQLITE_TEST
  2282   2349   /*
................................................................................
  2777   2844         char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
  2778   2845         if( zTFile ){
  2779   2846           getTempname(pFile->pVfs->mxPathname, zTFile);
  2780   2847           *(char**)pArg = zTFile;
  2781   2848         }
  2782   2849         return SQLITE_OK;
  2783   2850       }
         2851  +#if SQLITE_MAX_MMAP_SIZE>0
         2852  +    case SQLITE_FCNTL_MMAP_SIZE: {
         2853  +      i64 newLimit = *(i64*)pArg;
         2854  +      if( newLimit>sqlite3GlobalConfig.mxMmap ){
         2855  +        newLimit = sqlite3GlobalConfig.mxMmap;
         2856  +      }
         2857  +      *(i64*)pArg = pFile->mmapSizeMax;
         2858  +      if( newLimit>=0 ) pFile->mmapSizeMax = newLimit;
         2859  +      return SQLITE_OK;
         2860  +    }
         2861  +#endif
  2784   2862     }
  2785   2863     return SQLITE_NOTFOUND;
  2786   2864   }
  2787   2865   
  2788   2866   /*
  2789   2867   ** Return the sector size in bytes of the underlying block device for
  2790   2868   ** the specified file. This is almost always 512 bytes, but may be
................................................................................
  3446   3524   
  3447   3525   #else
  3448   3526   # define winShmMap     0
  3449   3527   # define winShmLock    0
  3450   3528   # define winShmBarrier 0
  3451   3529   # define winShmUnmap   0
  3452   3530   #endif /* #ifndef SQLITE_OMIT_WAL */
         3531  +
         3532  +/*
         3533  +** Cleans up the mapped region of the specified file, if any.
         3534  +*/
         3535  +#if SQLITE_MAX_MMAP_SIZE>0
         3536  +static int winUnmapfile(winFile *pFile){
         3537  +  assert( pFile!=0 );
         3538  +  if( pFile->pMapRegion ){
         3539  +    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
         3540  +      pFile->lastErrno = osGetLastError();
         3541  +      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
         3542  +                         "winUnmap1", pFile->zPath);
         3543  +    }
         3544  +    pFile->pMapRegion = 0;
         3545  +    pFile->mmapSize = 0;
         3546  +    pFile->mmapSizeActual = 0;
         3547  +  }
         3548  +  if( pFile->hMap!=NULL ){
         3549  +    if( !osCloseHandle(pFile->hMap) ){
         3550  +      pFile->lastErrno = osGetLastError();
         3551  +      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
         3552  +                         "winUnmap2", pFile->zPath);
         3553  +    }
         3554  +    pFile->hMap = NULL;
         3555  +  }
         3556  +  return SQLITE_OK;
         3557  +}
         3558  +
         3559  +/*
         3560  +** Memory map or remap the file opened by file-descriptor pFd (if the file
         3561  +** is already mapped, the existing mapping is replaced by the new). Or, if 
         3562  +** there already exists a mapping for this file, and there are still 
         3563  +** outstanding xFetch() references to it, this function is a no-op.
         3564  +**
         3565  +** If parameter nByte is non-negative, then it is the requested size of 
         3566  +** the mapping to create. Otherwise, if nByte is less than zero, then the 
         3567  +** requested size is the size of the file on disk. The actual size of the
         3568  +** created mapping is either the requested size or the value configured 
         3569  +** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
         3570  +**
         3571  +** SQLITE_OK is returned if no error occurs (even if the mapping is not
         3572  +** recreated as a result of outstanding references) or an SQLite error
         3573  +** code otherwise.
         3574  +*/
         3575  +static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
         3576  +  sqlite3_int64 nMap = nByte;
         3577  +  int rc;
         3578  +
         3579  +  assert( nMap>=0 || pFd->nFetchOut==0 );
         3580  +  if( pFd->nFetchOut>0 ) return SQLITE_OK;
         3581  +
         3582  +  if( nMap<0 ){
         3583  +    rc = winFileSize((sqlite3_file*)pFd, &nMap);
         3584  +    if( rc ){
         3585  +      return SQLITE_IOERR_FSTAT;
         3586  +    }
         3587  +  }
         3588  +  if( nMap>pFd->mmapSizeMax ){
         3589  +    nMap = pFd->mmapSizeMax;
         3590  +  }
         3591  +  nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
         3592  + 
         3593  +  if( nMap==0 && pFd->mmapSize>0 ){
         3594  +    winUnmapfile(pFd);
         3595  +  }
         3596  +  if( nMap!=pFd->mmapSize ){
         3597  +    void *pNew = 0;
         3598  +    DWORD protect = PAGE_READONLY;
         3599  +    DWORD flags = FILE_MAP_READ;
         3600  +
         3601  +    winUnmapfile(pFd);
         3602  +    if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
         3603  +      protect = PAGE_READWRITE;
         3604  +      flags |= FILE_MAP_WRITE;
         3605  +    }
         3606  +#if SQLITE_OS_WINRT
         3607  +    pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
         3608  +#elif defined(SQLITE_WIN32_HAS_WIDE)
         3609  +    pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
         3610  +                                (DWORD)((nMap>>32) & 0xffffffff),
         3611  +                                (DWORD)(nMap & 0xffffffff), NULL);
         3612  +#elif defined(SQLITE_WIN32_HAS_ANSI)
         3613  +    pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
         3614  +                                (DWORD)((nMap>>32) & 0xffffffff),
         3615  +                                (DWORD)(nMap & 0xffffffff), NULL);
         3616  +#endif
         3617  +    if( pFd->hMap==NULL ){
         3618  +      pFd->lastErrno = osGetLastError();
         3619  +      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
         3620  +                       "winMapfile", pFd->zPath);
         3621  +      /* Log the error, but continue normal operation using xRead/xWrite */
         3622  +      return SQLITE_OK;
         3623  +    }
         3624  +    assert( (nMap % winSysInfo.dwPageSize)==0 );
         3625  +#if SQLITE_OS_WINRT
         3626  +    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
         3627  +#else
         3628  +    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
         3629  +    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
         3630  +#endif
         3631  +    if( pNew==NULL ){
         3632  +      osCloseHandle(pFd->hMap);
         3633  +      pFd->hMap = NULL;
         3634  +      pFd->lastErrno = osGetLastError();
         3635  +      winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
         3636  +                  "winMapfile", pFd->zPath);
         3637  +      return SQLITE_OK;
         3638  +    }
         3639  +    pFd->pMapRegion = pNew;
         3640  +    pFd->mmapSize = nMap;
         3641  +    pFd->mmapSizeActual = nMap;
         3642  +  }
         3643  +
         3644  +  return SQLITE_OK;
         3645  +}
         3646  +#endif /* SQLITE_MAX_MMAP_SIZE>0 */
         3647  +
         3648  +/*
         3649  +** If possible, return a pointer to a mapping of file fd starting at offset
         3650  +** iOff. The mapping must be valid for at least nAmt bytes.
         3651  +**
         3652  +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
         3653  +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
         3654  +** Finally, if an error does occur, return an SQLite error code. The final
         3655  +** value of *pp is undefined in this case.
         3656  +**
         3657  +** If this function does return a pointer, the caller must eventually 
         3658  +** release the reference by calling unixUnfetch().
         3659  +*/
         3660  +static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
         3661  +#if SQLITE_MAX_MMAP_SIZE>0
         3662  +  winFile *pFd = (winFile*)fd;   /* The underlying database file */
         3663  +#endif
         3664  +  *pp = 0;
         3665  +
         3666  +#if SQLITE_MAX_MMAP_SIZE>0
         3667  +  if( pFd->mmapSizeMax>0 ){
         3668  +    if( pFd->pMapRegion==0 ){
         3669  +      int rc = winMapfile(pFd, -1);
         3670  +      if( rc!=SQLITE_OK ) return rc;
         3671  +    }
         3672  +    if( pFd->mmapSize >= iOff+nAmt ){
         3673  +      *pp = &((u8 *)pFd->pMapRegion)[iOff];
         3674  +      pFd->nFetchOut++;
         3675  +    }
         3676  +  }
         3677  +#endif
         3678  +  return SQLITE_OK;
         3679  +}
         3680  +
         3681  +/*
         3682  +** If the third argument is non-NULL, then this function releases a 
         3683  +** reference obtained by an earlier call to unixFetch(). The second
         3684  +** argument passed to this function must be the same as the corresponding
         3685  +** argument that was passed to the unixFetch() invocation. 
         3686  +**
         3687  +** Or, if the third argument is NULL, then this function is being called 
         3688  +** to inform the VFS layer that, according to POSIX, any existing mapping 
         3689  +** may now be invalid and should be unmapped.
         3690  +*/
         3691  +static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
         3692  +#if SQLITE_MAX_MMAP_SIZE>0
         3693  +  winFile *pFd = (winFile*)fd;   /* The underlying database file */
         3694  +
         3695  +  /* If p==0 (unmap the entire file) then there must be no outstanding 
         3696  +  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
         3697  +  ** then there must be at least one outstanding.  */
         3698  +  assert( (p==0)==(pFd->nFetchOut==0) );
         3699  +
         3700  +  /* If p!=0, it must match the iOff value. */
         3701  +  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
         3702  +
         3703  +  if( p ){
         3704  +    pFd->nFetchOut--;
         3705  +  }else{
         3706  +    /* FIXME:  If Windows truly always prevents truncating or deleting a
         3707  +    ** file while a mapping is held, then the following winUnmapfile() call
         3708  +    ** is unnecessary can can be omitted - potentially improving
         3709  +    ** performance.  */
         3710  +    winUnmapfile(pFd);
         3711  +  }
         3712  +
         3713  +  assert( pFd->nFetchOut>=0 );
         3714  +#endif
         3715  +  return SQLITE_OK;
         3716  +}
  3453   3717   
  3454   3718   /*
  3455   3719   ** Here ends the implementation of all sqlite3_file methods.
  3456   3720   **
  3457   3721   ********************** End sqlite3_file Methods *******************************
  3458   3722   ******************************************************************************/
  3459   3723   
  3460   3724   /*
  3461   3725   ** This vector defines all the methods that can operate on an
  3462   3726   ** sqlite3_file for win32.
  3463   3727   */
  3464   3728   static const sqlite3_io_methods winIoMethod = {
  3465         -  2,                              /* iVersion */
         3729  +  3,                              /* iVersion */
  3466   3730     winClose,                       /* xClose */
  3467   3731     winRead,                        /* xRead */
  3468   3732     winWrite,                       /* xWrite */
  3469   3733     winTruncate,                    /* xTruncate */
  3470   3734     winSync,                        /* xSync */
  3471   3735     winFileSize,                    /* xFileSize */
  3472   3736     winLock,                        /* xLock */
................................................................................
  3474   3738     winCheckReservedLock,           /* xCheckReservedLock */
  3475   3739     winFileControl,                 /* xFileControl */
  3476   3740     winSectorSize,                  /* xSectorSize */
  3477   3741     winDeviceCharacteristics,       /* xDeviceCharacteristics */
  3478   3742     winShmMap,                      /* xShmMap */
  3479   3743     winShmLock,                     /* xShmLock */
  3480   3744     winShmBarrier,                  /* xShmBarrier */
  3481         -  winShmUnmap                     /* xShmUnmap */
         3745  +  winShmUnmap,                    /* xShmUnmap */
         3746  +  winFetch,                       /* xFetch */
         3747  +  winUnfetch                      /* xUnfetch */
  3482   3748   };
  3483   3749   
  3484   3750   /****************************************************************************
  3485   3751   **************************** sqlite3_vfs methods ****************************
  3486   3752   **
  3487   3753   ** This division contains the implementation of methods on the
  3488   3754   ** sqlite3_vfs object.
................................................................................
  3650   3916   #if !defined(NDEBUG) || SQLITE_OS_WINCE
  3651   3917     int eType = flags&0xFFFFFF00;  /* Type of file to open */
  3652   3918   #endif
  3653   3919   
  3654   3920     int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
  3655   3921     int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
  3656   3922     int isCreate     = (flags & SQLITE_OPEN_CREATE);
  3657         -#ifndef NDEBUG
  3658   3923     int isReadonly   = (flags & SQLITE_OPEN_READONLY);
  3659         -#endif
  3660   3924     int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
  3661   3925   
  3662   3926   #ifndef NDEBUG
  3663   3927     int isOpenJournal = (isCreate && (
  3664   3928           eType==SQLITE_OPEN_MASTER_JOURNAL 
  3665   3929        || eType==SQLITE_OPEN_MAIN_JOURNAL 
  3666   3930        || eType==SQLITE_OPEN_WAL
................................................................................
  3863   4127     {
  3864   4128       sqlite3_free(zConverted);
  3865   4129     }
  3866   4130   
  3867   4131     pFile->pMethod = &winIoMethod;
  3868   4132     pFile->pVfs = pVfs;
  3869   4133     pFile->h = h;
         4134  +  if( isReadonly ){
         4135  +    pFile->ctrlFlags |= WINFILE_RDONLY;
         4136  +  }
  3870   4137     if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
  3871   4138       pFile->ctrlFlags |= WINFILE_PSOW;
  3872   4139     }
  3873   4140     pFile->lastErrno = NO_ERROR;
  3874   4141     pFile->zPath = zName;
         4142  +#if SQLITE_MAX_MMAP_SIZE>0
         4143  +  pFile->hMap = NULL;
         4144  +  pFile->pMapRegion = 0;
         4145  +  pFile->mmapSize = 0;
         4146  +  pFile->mmapSizeActual = 0;
         4147  +  pFile->mmapSizeMax = sqlite3GlobalConfig.mxMmap;
         4148  +#endif
  3875   4149   
  3876   4150     OpenCounter(+1);
  3877   4151     return rc;
  3878   4152   }
  3879   4153   
  3880   4154   /*
  3881   4155   ** Delete the named file.
................................................................................
  4496   4770       winNextSystemCall,   /* xNextSystemCall */
  4497   4771     };
  4498   4772   
  4499   4773     /* Double-check that the aSyscall[] array has been constructed
  4500   4774     ** correctly.  See ticket [bb3a86e890c8e96ab] */
  4501   4775     assert( ArraySize(aSyscall)==74 );
  4502   4776   
  4503         -#ifndef SQLITE_OMIT_WAL
  4504   4777     /* get memory map allocation granularity */
  4505   4778     memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
  4506   4779   #if SQLITE_OS_WINRT
  4507   4780     osGetNativeSystemInfo(&winSysInfo);
  4508   4781   #else
  4509   4782     osGetSystemInfo(&winSysInfo);
  4510   4783   #endif
  4511         -  assert(winSysInfo.dwAllocationGranularity > 0);
  4512         -#endif
         4784  +  assert( winSysInfo.dwAllocationGranularity>0 );
         4785  +  assert( winSysInfo.dwPageSize>0 );
  4513   4786   
  4514   4787     sqlite3_vfs_register(&winVfs, 1);
  4515   4788     return SQLITE_OK; 
  4516   4789   }
  4517   4790   
  4518   4791   int sqlite3_os_end(void){ 
  4519   4792   #if SQLITE_OS_WINRT

Changes to src/pager.c.

   651    651     sqlite3_file *sjfd;         /* File descriptor for sub-journal */
   652    652     i64 journalOff;             /* Current write offset in the journal file */
   653    653     i64 journalHdr;             /* Byte offset to previous journal header */
   654    654     sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
   655    655     PagerSavepoint *aSavepoint; /* Array of active savepoints */
   656    656     int nSavepoint;             /* Number of elements in aSavepoint[] */
   657    657     char dbFileVers[16];        /* Changes whenever database file changes */
          658  +
          659  +  u8 bUseFetch;               /* True to use xFetch() */
          660  +  int nMmapOut;               /* Number of mmap pages currently outstanding */
          661  +  sqlite3_int64 szMmap;       /* Desired maximum mmap size */
          662  +  PgHdr *pMmapFreelist;       /* List of free mmap page headers (pDirty) */
   658    663     /*
   659    664     ** End of the routinely-changing class members
   660    665     ***************************************************************************/
   661    666   
   662    667     u16 nExtra;                 /* Add this many bytes to each in-memory page */
   663    668     i16 nReserve;               /* Number of unused bytes at end of each page */
   664    669     u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
................................................................................
   761    766   */
   762    767   #ifdef SQLITE_OMIT_MEMORYDB
   763    768   # define MEMDB 0
   764    769   #else
   765    770   # define MEMDB pPager->memDb
   766    771   #endif
   767    772   
          773  +/*
          774  +** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
          775  +** interfaces to access the database using memory-mapped I/O.
          776  +*/
          777  +#if SQLITE_MAX_MMAP_SIZE>0
          778  +# define USEFETCH(x) ((x)->bUseFetch)
          779  +#else
          780  +# define USEFETCH(x) 0
          781  +#endif
          782  +
   768    783   /*
   769    784   ** The maximum legal page number is (2^31 - 1).
   770    785   */
   771    786   #define PAGER_MAX_PGNO 2147483647
   772    787   
   773    788   /*
   774    789   ** The argument to this macro is a file descriptor (type sqlite3_file*).
................................................................................
  2248   2263     if( isOpen(pPager->fd)
  2249   2264      && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
  2250   2265      && isSynced
  2251   2266     ){
  2252   2267       i64 ofst = (pgno-1)*(i64)pPager->pageSize;
  2253   2268       testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
  2254   2269       assert( !pagerUseWal(pPager) );
  2255         -    rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst);
         2270  +    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
  2256   2271       if( pgno>pPager->dbFileSize ){
  2257   2272         pPager->dbFileSize = pgno;
  2258   2273       }
  2259   2274       if( pPager->pBackup ){
  2260   2275         CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
  2261   2276         sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
  2262   2277         CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
................................................................................
  2639   2654     u32 nRec;                /* Number of Records in the journal */
  2640   2655     u32 u;                   /* Unsigned loop counter */
  2641   2656     Pgno mxPg = 0;           /* Size of the original file in pages */
  2642   2657     int rc;                  /* Result code of a subroutine */
  2643   2658     int res = 1;             /* Value returned by sqlite3OsAccess() */
  2644   2659     char *zMaster = 0;       /* Name of master journal file if any */
  2645   2660     int needPagerReset;      /* True to reset page prior to first page rollback */
         2661  +  int nPlayback = 0;       /* Total number of pages restored from journal */
  2646   2662   
  2647   2663     /* Figure out how many records are in the journal.  Abort early if
  2648   2664     ** the journal is empty.
  2649   2665     */
  2650   2666     assert( isOpen(pPager->jfd) );
  2651   2667     rc = sqlite3OsFileSize(pPager->jfd, &szJ);
  2652   2668     if( rc!=SQLITE_OK ){
................................................................................
  2739   2755       */
  2740   2756       for(u=0; u<nRec; u++){
  2741   2757         if( needPagerReset ){
  2742   2758           pager_reset(pPager);
  2743   2759           needPagerReset = 0;
  2744   2760         }
  2745   2761         rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
  2746         -      if( rc!=SQLITE_OK ){
         2762  +      if( rc==SQLITE_OK ){
         2763  +        nPlayback++;
         2764  +      }else{
  2747   2765           if( rc==SQLITE_DONE ){
  2748   2766             pPager->journalOff = szJ;
  2749   2767             break;
  2750   2768           }else if( rc==SQLITE_IOERR_SHORT_READ ){
  2751   2769             /* If the journal has been truncated, simply stop reading and
  2752   2770             ** processing the journal. This might happen if the journal was
  2753   2771             ** not completely written and synced prior to a crash.  In that
................................................................................
  2809   2827     if( rc==SQLITE_OK && zMaster[0] && res ){
  2810   2828       /* If there was a master journal and this routine will return success,
  2811   2829       ** see if it is possible to delete the master journal.
  2812   2830       */
  2813   2831       rc = pager_delmaster(pPager, zMaster);
  2814   2832       testcase( rc!=SQLITE_OK );
  2815   2833     }
         2834  +  if( isHot && nPlayback ){
         2835  +    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
         2836  +                nPlayback, pPager->zJournal);
         2837  +  }
  2816   2838   
  2817   2839     /* The Pager.sectorSize variable may have been updated while rolling
  2818   2840     ** back a journal created by a process with a different sector size
  2819   2841     ** value. Reset it to the correct value for this process.
  2820   2842     */
  2821   2843     setSectorSize(pPager);
  2822   2844     return rc;
................................................................................
  2830   2852   **
  2831   2853   ** If page 1 is read, then the value of Pager.dbFileVers[] is set to
  2832   2854   ** the value read from the database file.
  2833   2855   **
  2834   2856   ** If an IO error occurs, then the IO error is returned to the caller.
  2835   2857   ** Otherwise, SQLITE_OK is returned.
  2836   2858   */
  2837         -static int readDbPage(PgHdr *pPg){
         2859  +static int readDbPage(PgHdr *pPg, u32 iFrame){
  2838   2860     Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
  2839   2861     Pgno pgno = pPg->pgno;       /* Page number to read */
  2840   2862     int rc = SQLITE_OK;          /* Return code */
  2841         -  int isInWal = 0;             /* True if page is in log file */
  2842   2863     int pgsz = pPager->pageSize; /* Number of bytes to read */
  2843   2864   
  2844   2865     assert( pPager->eState>=PAGER_READER && !MEMDB );
  2845   2866     assert( isOpen(pPager->fd) );
  2846   2867   
  2847   2868     if( NEVER(!isOpen(pPager->fd)) ){
  2848   2869       assert( pPager->tempFile );
  2849   2870       memset(pPg->pData, 0, pPager->pageSize);
  2850   2871       return SQLITE_OK;
  2851   2872     }
  2852   2873   
  2853         -  if( pagerUseWal(pPager) ){
         2874  +  if( iFrame ){
  2854   2875       /* Try to pull the page from the write-ahead log. */
  2855         -    rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData);
  2856         -  }
  2857         -  if( rc==SQLITE_OK && !isInWal ){
         2876  +    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
         2877  +  }else{
  2858   2878       i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
  2859   2879       rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
  2860   2880       if( rc==SQLITE_IOERR_SHORT_READ ){
  2861   2881         rc = SQLITE_OK;
  2862   2882       }
  2863   2883     }
  2864   2884   
................................................................................
  2929   2949   ** return an SQLite error code. Otherwise, SQLITE_OK.
  2930   2950   */
  2931   2951   static int pagerUndoCallback(void *pCtx, Pgno iPg){
  2932   2952     int rc = SQLITE_OK;
  2933   2953     Pager *pPager = (Pager *)pCtx;
  2934   2954     PgHdr *pPg;
  2935   2955   
         2956  +  assert( pagerUseWal(pPager) );
  2936   2957     pPg = sqlite3PagerLookup(pPager, iPg);
  2937   2958     if( pPg ){
  2938   2959       if( sqlite3PcachePageRefcount(pPg)==1 ){
  2939   2960         sqlite3PcacheDrop(pPg);
  2940   2961       }else{
  2941         -      rc = readDbPage(pPg);
         2962  +      u32 iFrame = 0;
         2963  +      rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
         2964  +      if( rc==SQLITE_OK ){
         2965  +        rc = readDbPage(pPg, iFrame);
         2966  +      }
  2942   2967         if( rc==SQLITE_OK ){
  2943   2968           pPager->xReiniter(pPg);
  2944   2969         }
  2945   2970         sqlite3PagerUnref(pPg);
  2946   2971       }
  2947   2972     }
  2948   2973   
................................................................................
  3078   3103     ** the duplicate call is harmless.
  3079   3104     */
  3080   3105     sqlite3WalEndReadTransaction(pPager->pWal);
  3081   3106   
  3082   3107     rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
  3083   3108     if( rc!=SQLITE_OK || changed ){
  3084   3109       pager_reset(pPager);
         3110  +    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
  3085   3111     }
  3086   3112   
  3087   3113     return rc;
  3088   3114   }
  3089   3115   #endif
  3090   3116   
  3091   3117   /*
................................................................................
  3338   3364   
  3339   3365   /*
  3340   3366   ** Change the maximum number of in-memory pages that are allowed.
  3341   3367   */
  3342   3368   void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
  3343   3369     sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
  3344   3370   }
         3371  +
         3372  +/*
         3373  +** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
         3374  +*/
         3375  +static void pagerFixMaplimit(Pager *pPager){
         3376  +#if SQLITE_MAX_MMAP_SIZE>0
         3377  +  sqlite3_file *fd = pPager->fd;
         3378  +  if( isOpen(fd) ){
         3379  +    sqlite3_int64 sz;
         3380  +    pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
         3381  +    sz = pPager->szMmap;
         3382  +    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
         3383  +  }
         3384  +#endif
         3385  +}
         3386  +
         3387  +/*
         3388  +** Change the maximum size of any memory mapping made of the database file.
         3389  +*/
         3390  +void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){
         3391  +  pPager->szMmap = szMmap;
         3392  +  pagerFixMaplimit(pPager);
         3393  +}
  3345   3394   
  3346   3395   /*
  3347   3396   ** Free as much memory as possible from the pager.
  3348   3397   */
  3349   3398   void sqlite3PagerShrink(Pager *pPager){
  3350   3399     sqlite3PcacheShrink(pPager->pPCache);
  3351   3400   }
................................................................................
  3574   3623   
  3575   3624     *pPageSize = pPager->pageSize;
  3576   3625     if( rc==SQLITE_OK ){
  3577   3626       if( nReserve<0 ) nReserve = pPager->nReserve;
  3578   3627       assert( nReserve>=0 && nReserve<1000 );
  3579   3628       pPager->nReserve = (i16)nReserve;
  3580   3629       pagerReportSize(pPager);
         3630  +    pagerFixMaplimit(pPager);
  3581   3631     }
  3582   3632     return rc;
  3583   3633   }
  3584   3634   
  3585   3635   /*
  3586   3636   ** Return a pointer to the "temporary page" buffer held internally
  3587   3637   ** by the pager.  This is a buffer that is big enough to hold the
................................................................................
  3798   3848       rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
  3799   3849     }
  3800   3850     if( rc==SQLITE_OK ){
  3801   3851       rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
  3802   3852     }
  3803   3853     return rc;
  3804   3854   }
         3855  +
         3856  +/*
         3857  +** Obtain a reference to a memory mapped page object for page number pgno. 
         3858  +** The new object will use the pointer pData, obtained from xFetch().
         3859  +** If successful, set *ppPage to point to the new page reference
         3860  +** and return SQLITE_OK. Otherwise, return an SQLite error code and set
         3861  +** *ppPage to zero.
         3862  +**
         3863  +** Page references obtained by calling this function should be released
         3864  +** by calling pagerReleaseMapPage().
         3865  +*/
         3866  +static int pagerAcquireMapPage(
         3867  +  Pager *pPager,                  /* Pager object */
         3868  +  Pgno pgno,                      /* Page number */
         3869  +  void *pData,                    /* xFetch()'d data for this page */
         3870  +  PgHdr **ppPage                  /* OUT: Acquired page object */
         3871  +){
         3872  +  PgHdr *p;                       /* Memory mapped page to return */
         3873  +
         3874  +  if( pPager->pMmapFreelist ){
         3875  +    *ppPage = p = pPager->pMmapFreelist;
         3876  +    pPager->pMmapFreelist = p->pDirty;
         3877  +    p->pDirty = 0;
         3878  +    memset(p->pExtra, 0, pPager->nExtra);
         3879  +  }else{
         3880  +    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
         3881  +    if( p==0 ){
         3882  +      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
         3883  +      return SQLITE_NOMEM;
         3884  +    }
         3885  +    p->pExtra = (void *)&p[1];
         3886  +    p->flags = PGHDR_MMAP;
         3887  +    p->nRef = 1;
         3888  +    p->pPager = pPager;
         3889  +  }
         3890  +
         3891  +  assert( p->pExtra==(void *)&p[1] );
         3892  +  assert( p->pPage==0 );
         3893  +  assert( p->flags==PGHDR_MMAP );
         3894  +  assert( p->pPager==pPager );
         3895  +  assert( p->nRef==1 );
         3896  +
         3897  +  p->pgno = pgno;
         3898  +  p->pData = pData;
         3899  +  pPager->nMmapOut++;
         3900  +
         3901  +  return SQLITE_OK;
         3902  +}
         3903  +
         3904  +/*
         3905  +** Release a reference to page pPg. pPg must have been returned by an 
         3906  +** earlier call to pagerAcquireMapPage().
         3907  +*/
         3908  +static void pagerReleaseMapPage(PgHdr *pPg){
         3909  +  Pager *pPager = pPg->pPager;
         3910  +  pPager->nMmapOut--;
         3911  +  pPg->pDirty = pPager->pMmapFreelist;
         3912  +  pPager->pMmapFreelist = pPg;
         3913  +
         3914  +  assert( pPager->fd->pMethods->iVersion>=3 );
         3915  +  sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
         3916  +}
         3917  +
         3918  +/*
         3919  +** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
         3920  +*/
         3921  +static void pagerFreeMapHdrs(Pager *pPager){
         3922  +  PgHdr *p;
         3923  +  PgHdr *pNext;
         3924  +  for(p=pPager->pMmapFreelist; p; p=pNext){
         3925  +    pNext = p->pDirty;
         3926  +    sqlite3_free(p);
         3927  +  }
         3928  +}
         3929  +
  3805   3930   
  3806   3931   /*
  3807   3932   ** Shutdown the page cache.  Free all memory and close all files.
  3808   3933   **
  3809   3934   ** If a transaction was in progress when this routine is called, that
  3810   3935   ** transaction is rolled back.  All outstanding pages are invalidated
  3811   3936   ** and their memory is freed.  Any attempt to use a page associated
................................................................................
  3819   3944   */
  3820   3945   int sqlite3PagerClose(Pager *pPager){
  3821   3946     u8 *pTmp = (u8 *)pPager->pTmpSpace;
  3822   3947   
  3823   3948     assert( assert_pager_state(pPager) );
  3824   3949     disable_simulated_io_errors();
  3825   3950     sqlite3BeginBenignMalloc();
         3951  +  pagerFreeMapHdrs(pPager);
  3826   3952     /* pPager->errCode = 0; */
  3827   3953     pPager->exclusiveMode = 0;
  3828   3954   #ifndef SQLITE_OMIT_WAL
  3829   3955     sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
  3830   3956     pPager->pWal = 0;
  3831   3957   #endif
  3832   3958     pager_reset(pPager);
................................................................................
  4080   4206       rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
  4081   4207     }
  4082   4208   
  4083   4209     /* Before the first write, give the VFS a hint of what the final
  4084   4210     ** file size will be.
  4085   4211     */
  4086   4212     assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
  4087         -  if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){
         4213  +  if( rc==SQLITE_OK 
         4214  +   && (pList->pDirty ? pPager->dbSize : pList->pgno+1)>pPager->dbHintSize 
         4215  +  ){
  4088   4216       sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
  4089   4217       sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
  4090   4218       pPager->dbHintSize = pPager->dbSize;
  4091   4219     }
  4092   4220   
  4093   4221     while( rc==SQLITE_OK && pList ){
  4094   4222       Pgno pgno = pList->pgno;
................................................................................
  4634   4762     }else if( memDb ){
  4635   4763       pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
  4636   4764     }
  4637   4765     /* pPager->xBusyHandler = 0; */
  4638   4766     /* pPager->pBusyHandlerArg = 0; */
  4639   4767     pPager->xReiniter = xReinit;
  4640   4768     /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
         4769  +  /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
  4641   4770   
  4642   4771     *ppPager = pPager;
  4643   4772     return SQLITE_OK;
  4644   4773   }
  4645   4774   
  4646   4775   
  4647   4776   
................................................................................
  4925   5054   
  4926   5055         assert( pPager->eState==PAGER_OPEN );
  4927   5056         assert( (pPager->eLock==SHARED_LOCK)
  4928   5057              || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
  4929   5058         );
  4930   5059       }
  4931   5060   
  4932         -    if( !pPager->tempFile 
  4933         -     && (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0) 
  4934         -    ){
         5061  +    if( !pPager->tempFile && (
         5062  +        pPager->pBackup 
         5063  +     || sqlite3PcachePagecount(pPager->pPCache)>0 
         5064  +     || USEFETCH(pPager)
         5065  +    )){
  4935   5066         /* The shared-lock has just been acquired on the database file
  4936   5067         ** and there are already pages in the cache (from a previous
  4937   5068         ** read or write transaction).  Check to see if the database
  4938   5069         ** has been modified.  If the database has changed, flush the
  4939   5070         ** cache.
  4940   5071         **
  4941   5072         ** Database changes is detected by looking at 15 bytes beginning
................................................................................
  4953   5084   
  4954   5085         rc = pagerPagecount(pPager, &nPage);
  4955   5086         if( rc ) goto failed;
  4956   5087   
  4957   5088         if( nPage>0 ){
  4958   5089           IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
  4959   5090           rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
  4960         -        if( rc!=SQLITE_OK ){
         5091  +        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
  4961   5092             goto failed;
  4962   5093           }
  4963   5094         }else{
  4964   5095           memset(dbFileVers, 0, sizeof(dbFileVers));
  4965   5096         }
  4966   5097   
  4967   5098         if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
  4968   5099           pager_reset(pPager);
         5100  +
         5101  +        /* Unmap the database file. It is possible that external processes
         5102  +        ** may have truncated the database file and then extended it back
         5103  +        ** to its original size while this process was not holding a lock.
         5104  +        ** In this case there may exist a Pager.pMap mapping that appears
         5105  +        ** to be the right size but is not actually valid. Avoid this
         5106  +        ** possibility by unmapping the db here. */
         5107  +        if( USEFETCH(pPager) ){
         5108  +          sqlite3OsUnfetch(pPager->fd, 0, 0);
         5109  +        }
  4969   5110         }
  4970   5111       }
  4971   5112   
  4972   5113       /* If there is a WAL file in the file-system, open this database in WAL
  4973   5114       ** mode. Otherwise, the following function call is a no-op.
  4974   5115       */
  4975   5116       rc = pagerOpenWalIfPresent(pPager);
................................................................................
  5003   5144   ** transaction and unlock the pager.
  5004   5145   **
  5005   5146   ** Except, in locking_mode=EXCLUSIVE when there is nothing to in
  5006   5147   ** the rollback journal, the unlock is not performed and there is
  5007   5148   ** nothing to rollback, so this routine is a no-op.
  5008   5149   */ 
  5009   5150   static void pagerUnlockIfUnused(Pager *pPager){
  5010         -  if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
         5151  +  if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
  5011   5152       pagerUnlockAndRollback(pPager);
  5012   5153     }
  5013   5154   }
  5014   5155   
  5015   5156   /*
  5016   5157   ** Acquire a reference to page number pgno in pager pPager (a page
  5017   5158   ** reference has type DbPage*). If the requested reference is 
................................................................................
  5062   5203   ** Since Lookup() never goes to disk, it never has to deal with locks
  5063   5204   ** or journal files.
  5064   5205   */
  5065   5206   int sqlite3PagerAcquire(
  5066   5207     Pager *pPager,      /* The pager open on the database file */
  5067   5208     Pgno pgno,          /* Page number to fetch */
  5068   5209     DbPage **ppPage,    /* Write a pointer to the page here */
  5069         -  int noContent       /* Do not bother reading content from disk if true */
         5210  +  int flags           /* PAGER_ACQUIRE_XXX flags */
  5070   5211   ){
  5071         -  int rc;
  5072         -  PgHdr *pPg;
         5212  +  int rc = SQLITE_OK;
         5213  +  PgHdr *pPg = 0;
         5214  +  u32 iFrame = 0;                 /* Frame to read from WAL file */
         5215  +  const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);
         5216  +
         5217  +  /* It is acceptable to use a read-only (mmap) page for any page except
         5218  +  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
         5219  +  ** flag was specified by the caller. And so long as the db is not a 
         5220  +  ** temporary or in-memory database.  */
         5221  +  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
         5222  +   && (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY))
         5223  +#ifdef SQLITE_HAS_CODEC
         5224  +   && pPager->xCodec==0
         5225  +#endif
         5226  +  );
  5073   5227   
  5074   5228     assert( pPager->eState>=PAGER_READER );
  5075   5229     assert( assert_pager_state(pPager) );
         5230  +  assert( noContent==0 || bMmapOk==0 );
  5076   5231   
  5077   5232     if( pgno==0 ){
  5078   5233       return SQLITE_CORRUPT_BKPT;
  5079   5234     }
  5080   5235   
  5081   5236     /* If the pager is in the error state, return an error immediately. 
  5082   5237     ** Otherwise, request the page from the PCache layer. */
  5083   5238     if( pPager->errCode!=SQLITE_OK ){
  5084   5239       rc = pPager->errCode;
  5085   5240     }else{
         5241  +
         5242  +    if( bMmapOk && pagerUseWal(pPager) ){
         5243  +      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
         5244  +      if( rc!=SQLITE_OK ) goto pager_acquire_err;
         5245  +    }
         5246  +
         5247  +    if( iFrame==0 && bMmapOk ){
         5248  +      void *pData = 0;
         5249  +
         5250  +      rc = sqlite3OsFetch(pPager->fd, 
         5251  +          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
         5252  +      );
         5253  +
         5254  +      if( rc==SQLITE_OK && pData ){
         5255  +        if( pPager->eState>PAGER_READER ){
         5256  +          (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
         5257  +        }
         5258  +        if( pPg==0 ){
         5259  +          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
         5260  +        }else{
         5261  +          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
         5262  +        }
         5263  +        if( pPg ){
         5264  +          assert( rc==SQLITE_OK );
         5265  +          *ppPage = pPg;
         5266  +          return SQLITE_OK;
         5267  +        }
         5268  +      }
         5269  +      if( rc!=SQLITE_OK ){
         5270  +        goto pager_acquire_err;
         5271  +      }
         5272  +    }
         5273  +
  5086   5274       rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
  5087   5275     }
  5088   5276   
  5089   5277     if( rc!=SQLITE_OK ){
  5090   5278       /* Either the call to sqlite3PcacheFetch() returned an error or the
  5091   5279       ** pager was already in the error-state when this function was called.
  5092   5280       ** Set pPg to 0 and jump to the exception handler.  */
................................................................................
  5137   5325           TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
  5138   5326           testcase( rc==SQLITE_NOMEM );
  5139   5327           sqlite3EndBenignMalloc();
  5140   5328         }
  5141   5329         memset(pPg->pData, 0, pPager->pageSize);
  5142   5330         IOTRACE(("ZERO %p %d\n", pPager, pgno));
  5143   5331       }else{
         5332  +      if( pagerUseWal(pPager) && bMmapOk==0 ){
         5333  +        rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
         5334  +        if( rc!=SQLITE_OK ) goto pager_acquire_err;
         5335  +      }
  5144   5336         assert( pPg->pPager==pPager );
  5145   5337         pPager->aStat[PAGER_STAT_MISS]++;
  5146         -      rc = readDbPage(pPg);
         5338  +      rc = readDbPage(pPg, iFrame);
  5147   5339         if( rc!=SQLITE_OK ){
  5148   5340           goto pager_acquire_err;
  5149   5341         }
  5150   5342       }
  5151   5343       pager_set_pagehash(pPg);
  5152   5344     }
  5153   5345   
................................................................................
  5192   5384   ** page is added to the LRU list.  When all references to all pages
  5193   5385   ** are released, a rollback occurs and the lock on the database is
  5194   5386   ** removed.
  5195   5387   */
  5196   5388   void sqlite3PagerUnref(DbPage *pPg){
  5197   5389     if( pPg ){
  5198   5390       Pager *pPager = pPg->pPager;
  5199         -    sqlite3PcacheRelease(pPg);
         5391  +    if( pPg->flags & PGHDR_MMAP ){
         5392  +      pagerReleaseMapPage(pPg);
         5393  +    }else{
         5394  +      sqlite3PcacheRelease(pPg);
         5395  +    }
  5200   5396       pagerUnlockIfUnused(pPager);
  5201   5397     }
  5202   5398   }
  5203   5399   
  5204   5400   /*
  5205   5401   ** This function is called at the start of every write transaction.
  5206   5402   ** There must already be a RESERVED or EXCLUSIVE lock on the database 
................................................................................
  5527   5723   int sqlite3PagerWrite(DbPage *pDbPage){
  5528   5724     int rc = SQLITE_OK;
  5529   5725   
  5530   5726     PgHdr *pPg = pDbPage;
  5531   5727     Pager *pPager = pPg->pPager;
  5532   5728     Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
  5533   5729   
         5730  +  assert( (pPg->flags & PGHDR_MMAP)==0 );
  5534   5731     assert( pPager->eState>=PAGER_WRITER_LOCKED );
  5535   5732     assert( pPager->eState!=PAGER_ERROR );
  5536   5733     assert( assert_pager_state(pPager) );
  5537   5734   
  5538   5735     if( nPagePerSector>1 ){
  5539   5736       Pgno nPageCount;          /* Total number of pages in database file */
  5540   5737       Pgno pg1;                 /* First page of the sector pPg is located on. */
................................................................................
  6083   6280         return rc;
  6084   6281       }
  6085   6282     }else{
  6086   6283       rc = pager_playback(pPager, 0);
  6087   6284     }
  6088   6285   
  6089   6286     assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
  6090         -  assert( rc==SQLITE_OK || rc==SQLITE_FULL
         6287  +  assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
  6091   6288             || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR );
  6092   6289   
  6093   6290     /* If an error occurs during a ROLLBACK, we can no longer trust the pager
  6094   6291     ** cache. So call pager_error() on the way out to make any error persistent.
  6095   6292     */
  6096   6293     return pager_error(pPager, rc);
  6097   6294   }
................................................................................
  6817   7014       rc = pagerExclusiveLock(pPager);
  6818   7015     }
  6819   7016   
  6820   7017     /* Open the connection to the log file. If this operation fails, 
  6821   7018     ** (e.g. due to malloc() failure), return an error code.
  6822   7019     */
  6823   7020     if( rc==SQLITE_OK ){
  6824         -    rc = sqlite3WalOpen(pPager->pVfs, 
         7021  +    rc = sqlite3WalOpen(pPager->pVfs,
  6825   7022           pPager->fd, pPager->zWal, pPager->exclusiveMode,
  6826   7023           pPager->journalSizeLimit, &pPager->pWal
  6827   7024       );
  6828   7025     }
         7026  +  pagerFixMaplimit(pPager);
  6829   7027   
  6830   7028     return rc;
  6831   7029   }
  6832   7030   
  6833   7031   
  6834   7032   /*
  6835   7033   ** The caller must be holding a SHARED lock on the database file to call
................................................................................
  6912   7110     */
  6913   7111     if( rc==SQLITE_OK && pPager->pWal ){
  6914   7112       rc = pagerExclusiveLock(pPager);
  6915   7113       if( rc==SQLITE_OK ){
  6916   7114         rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
  6917   7115                              pPager->pageSize, (u8*)pPager->pTmpSpace);
  6918   7116         pPager->pWal = 0;
         7117  +      pagerFixMaplimit(pPager);
  6919   7118       }
  6920   7119     }
  6921   7120     return rc;
  6922   7121   }
  6923   7122   
  6924   7123   #endif /* !SQLITE_OMIT_WAL */
  6925   7124   

Changes to src/pager.h.

    74     74   #define PAGER_JOURNALMODE_DELETE      0   /* Commit by deleting journal file */
    75     75   #define PAGER_JOURNALMODE_PERSIST     1   /* Commit by zeroing journal header */
    76     76   #define PAGER_JOURNALMODE_OFF         2   /* Journal omitted.  */
    77     77   #define PAGER_JOURNALMODE_TRUNCATE    3   /* Commit by truncating journal */
    78     78   #define PAGER_JOURNALMODE_MEMORY      4   /* In-memory journal file */
    79     79   #define PAGER_JOURNALMODE_WAL         5   /* Use write-ahead logging */
    80     80   
           81  +/*
           82  +** Flags that make up the mask passed to sqlite3PagerAcquire().
           83  +*/
           84  +#define PAGER_ACQUIRE_NOCONTENT     0x01  /* Do not load data from disk */
           85  +#define PAGER_ACQUIRE_READONLY      0x02  /* Read-only page is acceptable */
           86  +
    81     87   /*
    82     88   ** The remainder of this file contains the declarations of the functions
    83     89   ** that make up the Pager sub-system API. See source code comments for 
    84     90   ** a detailed description of each routine.
    85     91   */
    86     92   
    87     93   /* Open and close a Pager connection. */ 
................................................................................
    98    104   int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
    99    105   
   100    106   /* Functions used to configure a Pager object. */
   101    107   void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
   102    108   int sqlite3PagerSetPagesize(Pager*, u32*, int);
   103    109   int sqlite3PagerMaxPageCount(Pager*, int);
   104    110   void sqlite3PagerSetCachesize(Pager*, int);
          111  +void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
   105    112   void sqlite3PagerShrink(Pager*);
   106    113   void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
   107    114   int sqlite3PagerLockingMode(Pager *, int);
   108    115   int sqlite3PagerSetJournalMode(Pager *, int);
   109    116   int sqlite3PagerGetJournalMode(Pager*);
   110    117   int sqlite3PagerOkToChangeJournalMode(Pager*);
   111    118   i64 sqlite3PagerJournalSizeLimit(Pager *, i64);

Changes to src/pcache.h.

    48     48   /* Bit values for PgHdr.flags */
    49     49   #define PGHDR_DIRTY             0x002  /* Page has changed */
    50     50   #define PGHDR_NEED_SYNC         0x004  /* Fsync the rollback journal before
    51     51                                          ** writing this page to the database */
    52     52   #define PGHDR_NEED_READ         0x008  /* Content is unread */
    53     53   #define PGHDR_REUSE_UNLIKELY    0x010  /* A hint that reuse is unlikely */
    54     54   #define PGHDR_DONT_WRITE        0x020  /* Do not write content to disk */
           55  +
           56  +#define PGHDR_MMAP              0x040  /* This is an mmap page object */
    55     57   
    56     58   /* Initialize and shutdown the page cache subsystem */
    57     59   int sqlite3PcacheInitialize(void);
    58     60   void sqlite3PcacheShutdown(void);
    59     61   
    60     62   /* Page cache buffer management:
    61     63   ** These routines implement SQLITE_CONFIG_PAGECACHE.

Changes to src/pragma.c.

   315    315     const char *zDb = 0;   /* The database name */
   316    316     Token *pId;            /* Pointer to <id> token */
   317    317     int iDb;               /* Database index for <database> */
   318    318     char *aFcntl[4];       /* Argument to SQLITE_FCNTL_PRAGMA */
   319    319     int rc;                      /* return value form SQLITE_FCNTL_PRAGMA */
   320    320     sqlite3 *db = pParse->db;    /* The database connection */
   321    321     Db *pDb;                     /* The specific database being pragmaed */
   322         -  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db);  /* Prepared statement */
          322  +  Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
   323    323   
   324    324     if( v==0 ) return;
   325    325     sqlite3VdbeRunOnlyOnce(v);
   326    326     pParse->nMem = 2;
   327    327   
   328    328     /* Interpret the [database.] part of the pragma statement. iDb is the
   329    329     ** index of the database this pragma is being applied to in db.aDb[]. */
................................................................................
   398    398     ** size.  But continue to take the absolute value of the default cache
   399    399     ** size of historical compatibility.
   400    400     */
   401    401     if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
   402    402       static const VdbeOpList getCacheSize[] = {
   403    403         { OP_Transaction, 0, 0,        0},                         /* 0 */
   404    404         { OP_ReadCookie,  0, 1,        BTREE_DEFAULT_CACHE_SIZE},  /* 1 */
   405         -      { OP_IfPos,       1, 7,        0},
          405  +      { OP_IfPos,       1, 8,        0},
   406    406         { OP_Integer,     0, 2,        0},
   407    407         { OP_Subtract,    1, 2,        1},
   408         -      { OP_IfPos,       1, 7,        0},
          408  +      { OP_IfPos,       1, 8,        0},
   409    409         { OP_Integer,     0, 1,        0},                         /* 6 */
          410  +      { OP_Noop,        0, 0,        0},
   410    411         { OP_ResultRow,   1, 1,        0},
   411    412       };
   412    413       int addr;
   413    414       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
   414    415       sqlite3VdbeUsesBtree(v, iDb);
   415    416       if( !zRight ){
   416    417         sqlite3VdbeSetNumCols(v, 1);
................................................................................
   740    741       }else{
   741    742         int size = sqlite3Atoi(zRight);
   742    743         pDb->pSchema->cache_size = size;
   743    744         sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
   744    745       }
   745    746     }else
   746    747   
          748  +  /*
          749  +  **  PRAGMA [database.]mmap_size(N)
          750  +  **
          751  +  ** Used to set mapping size limit. The mapping size limit is
          752  +  ** used to limit the aggregate size of all memory mapped regions of the
          753  +  ** database file. If this parameter is set to zero, then memory mapping
          754  +  ** is not used at all.  If N is negative, then the default memory map
          755  +  ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set.
          756  +  ** The parameter N is measured in bytes.
          757  +  **
          758  +  ** This value is advisory.  The underlying VFS is free to memory map
          759  +  ** as little or as much as it wants.  Except, if N is set to 0 then the
          760  +  ** upper layers will never invoke the xFetch interfaces to the VFS.
          761  +  */
          762  +  if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){
          763  +    sqlite3_int64 sz;
          764  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
          765  +    if( zRight ){
          766  +      int ii;
          767  +      sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8);
          768  +      if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
          769  +      if( pId2->n==0 ) db->szMmap = sz;
          770  +      for(ii=db->nDb-1; ii>=0; ii--){
          771  +        if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
          772  +          sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz);
          773  +        }
          774  +      }
          775  +    }
          776  +    sz = -1;
          777  +    if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_SIZE,&sz)==SQLITE_OK ){
          778  +#if SQLITE_MAX_MMAP_SIZE==0
          779  +      sz = 0;
          780  +#endif
          781  +      returnSingleInt(pParse, "mmap_size", sz);
          782  +    }
          783  +  }else
          784  +
   747    785     /*
   748    786     **   PRAGMA temp_store
   749    787     **   PRAGMA temp_store = "default"|"memory"|"file"
   750    788     **
   751    789     ** Return or set the local value of the temp_store flag.  Changing
   752    790     ** the local value does not make changes to the disk file and the default
   753    791     ** value will be restored the next time the database is opened.

Changes to src/prepare.c.

   650    650       for(i=iFirst; i<mx; i++){
   651    651         sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
   652    652                               azColName[i], SQLITE_STATIC);
   653    653       }
   654    654     }
   655    655   #endif
   656    656   
   657         -  assert( db->init.busy==0 || saveSqlFlag==0 );
   658    657     if( db->init.busy==0 ){
   659    658       Vdbe *pVdbe = pParse->pVdbe;
   660    659       sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
   661    660     }
   662    661     if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
   663    662       sqlite3VdbeFinalize(pParse->pVdbe);
   664    663       assert(!(*ppStmt));

Changes to src/resolve.c.

   384    384       **     SELECT a+b AS x FROM table WHERE x<10;
   385    385       **
   386    386       ** In cases like this, replace pExpr with a copy of the expression that
   387    387       ** forms the result set entry ("a+b" in the example) and return immediately.
   388    388       ** Note that the expression in the result set should have already been
   389    389       ** resolved by the time the WHERE clause is resolved.
   390    390       */
   391         -    if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
          391  +    if( (pEList = pNC->pEList)!=0
          392  +     && zTab==0
          393  +     && ((pNC->ncFlags & NC_AsMaybe)==0 || cnt==0)
          394  +    ){
   392    395         for(j=0; j<pEList->nExpr; j++){
   393    396           char *zAs = pEList->a[j].zName;
   394    397           if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
   395    398             Expr *pOrig;
   396    399             assert( pExpr->pLeft==0 && pExpr->pRight==0 );
   397    400             assert( pExpr->x.pList==0 );
   398    401             assert( pExpr->x.pSelect==0 );
................................................................................
   475    478     pExpr->pLeft = 0;
   476    479     sqlite3ExprDelete(db, pExpr->pRight);
   477    480     pExpr->pRight = 0;
   478    481     pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
   479    482   lookupname_end:
   480    483     if( cnt==1 ){
   481    484       assert( pNC!=0 );
   482         -    sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
          485  +    if( pExpr->op!=TK_AS ){
          486  +      sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
          487  +    }
   483    488       /* Increment the nRef value on all name contexts from TopNC up to
   484    489       ** the point where the name matched. */
   485    490       for(;;){
   486    491         assert( pTopNC!=0 );
   487    492         pTopNC->nRef++;
   488    493         if( pTopNC==pNC ) break;
   489    494         pTopNC = pTopNC->pNext;
................................................................................
  1150   1155       ** expressions in the WHERE clause (etc.) can refer to expressions by
  1151   1156       ** aliases in the result set.
  1152   1157       **
  1153   1158       ** Minor point: If this is the case, then the expression will be
  1154   1159       ** re-evaluated for each reference to it.
  1155   1160       */
  1156   1161       sNC.pEList = p->pEList;
  1157         -    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ||
  1158         -       sqlite3ResolveExprNames(&sNC, p->pHaving)
  1159         -    ){
  1160         -      return WRC_Abort;
  1161         -    }
         1162  +    if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
         1163  +    sNC.ncFlags |= NC_AsMaybe;
         1164  +    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
         1165  +    sNC.ncFlags &= ~NC_AsMaybe;
  1162   1166   
  1163   1167       /* The ORDER BY and GROUP BY clauses may not refer to terms in
  1164   1168       ** outer queries 
  1165   1169       */
  1166   1170       sNC.pNext = 0;
  1167   1171       sNC.ncFlags |= NC_AllowAgg;
  1168   1172   

Changes to src/shell.c.

  1547   1547     if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
  1548   1548       return 0;
  1549   1549     }
  1550   1550     fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
  1551   1551             zArg);
  1552   1552     return 0;
  1553   1553   }
         1554  +
         1555  +/*
         1556  +** Interpret zArg as an integer value, possibly with suffixes.
         1557  +*/
         1558  +static sqlite3_int64 integerValue(const char *zArg){
         1559  +  sqlite3_int64 v = 0;
         1560  +  static const struct { char *zSuffix; int iMult; } aMult[] = {
         1561  +    { "KiB", 1024 },
         1562  +    { "MiB", 1024*1024 },
         1563  +    { "GiB", 1024*1024*1024 },
         1564  +    { "KB",  1000 },
         1565  +    { "MB",  1000000 },
         1566  +    { "GB",  1000000000 },
         1567  +    { "K",   1000 },
         1568  +    { "M",   1000000 },
         1569  +    { "G",   1000000000 },
         1570  +  };
         1571  +  int i;
         1572  +  int isNeg = 0;
         1573  +  if( zArg[0]=='-' ){
         1574  +    isNeg = 1;
         1575  +    zArg++;
         1576  +  }else if( zArg[0]=='+' ){
         1577  +    zArg++;
         1578  +  }
         1579  +  while( isdigit(zArg[0]) ){
         1580  +    v = v*10 + zArg[0] - '0';
         1581  +    zArg++;
         1582  +  }
         1583  +  for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
         1584  +    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
         1585  +      v *= aMult[i].iMult;
         1586  +      break;
         1587  +    }
         1588  +  }
         1589  +  return isNeg? -v : v;
         1590  +}
  1554   1591   
  1555   1592   /*
  1556   1593   ** Close an output file, assuming it is not stderr or stdout
  1557   1594   */
  1558   1595   static void output_file_close(FILE *f){
  1559   1596     if( f && f!=stdout && f!=stderr ) fclose(f);
  1560   1597   }
................................................................................
  2465   2502               fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
  2466   2503             }
  2467   2504             break;
  2468   2505   
  2469   2506           /* sqlite3_test_control(int, uint) */
  2470   2507           case SQLITE_TESTCTRL_PENDING_BYTE:        
  2471   2508             if( nArg==3 ){
  2472         -            unsigned int opt = (unsigned int)atoi(azArg[2]);        
         2509  +            unsigned int opt = (unsigned int)integerValue(azArg[2]);        
  2473   2510               rc = sqlite3_test_control(testctrl, opt);
  2474   2511               printf("%d (0x%08x)\n", rc, rc);
  2475   2512             } else {
  2476   2513               fprintf(stderr,"Error: testctrl %s takes a single unsigned"
  2477   2514                              " int option\n", azArg[1]);
  2478   2515             }
  2479   2516             break;
................................................................................
  2557   2594         }
  2558   2595       }
  2559   2596     }else
  2560   2597   
  2561   2598   #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
  2562   2599     if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
  2563   2600       extern int sqlite3WhereTrace;
  2564         -    sqlite3WhereTrace = atoi(azArg[1]);
         2601  +    sqlite3WhereTrace = booleanValue(azArg[1]);
  2565   2602     }else
  2566   2603   #endif
  2567   2604   
  2568   2605     if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
  2569   2606       int j;
  2570   2607       assert( nArg<=ArraySize(azArg) );
  2571   2608       for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
................................................................................
  2743   2780             fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
  2744   2781           }
  2745   2782           errCnt++;
  2746   2783         }
  2747   2784         free(zSql);
  2748   2785         zSql = 0;
  2749   2786         nSql = 0;
         2787  +    }else if( zSql && _all_whitespace(zSql) ){
         2788  +      free(zSql);
         2789  +      zSql = 0;
         2790  +      nSql = 0;
  2750   2791       }
  2751   2792     }
  2752   2793     if( zSql ){
  2753   2794       if( !_all_whitespace(zSql) ){
  2754   2795         fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
  2755   2796       }
  2756   2797       free(zSql);
................................................................................
  2878   2919     "   -heap SIZE           Size of heap for memsys3 or memsys5\n"
  2879   2920   #endif
  2880   2921     "   -help                show this message\n"
  2881   2922     "   -html                set output mode to HTML\n"
  2882   2923     "   -interactive         force interactive I/O\n"
  2883   2924     "   -line                set output mode to 'line'\n"
  2884   2925     "   -list                set output mode to 'list'\n"
         2926  +  "   -mmap N              default mmap size set to N\n"
  2885   2927   #ifdef SQLITE_ENABLE_MULTIPLEX
  2886   2928     "   -multiplex           enable the multiplexor VFS\n"
  2887   2929   #endif
  2888   2930     "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
  2889   2931     "   -separator SEP       set output field separator. Default: '|'\n"
  2890   2932     "   -stats               print memory stats before each finalize\n"
  2891   2933     "   -version             show SQLite version\n"
................................................................................
  2997   3039       }else if( strcmp(z,"-heap")==0 ){
  2998   3040   #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  2999   3041         int j, c;
  3000   3042         const char *zSize;
  3001   3043         sqlite3_int64 szHeap;
  3002   3044   
  3003   3045         zSize = cmdline_option_value(argc, argv, ++i);
  3004         -      szHeap = atoi(zSize);
  3005         -      for(j=0; (c = zSize[j])!=0; j++){
  3006         -        if( c=='M' ){ szHeap *= 1000000; break; }
  3007         -        if( c=='K' ){ szHeap *= 1000; break; }
  3008         -        if( c=='G' ){ szHeap *= 1000000000; break; }
  3009         -      }
         3046  +      szHeap = integerValue(zSize);
  3010   3047         if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
  3011   3048         sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
  3012   3049   #endif
  3013   3050   #ifdef SQLITE_ENABLE_VFSTRACE
  3014   3051       }else if( strcmp(z,"-vfstrace")==0 ){
  3015   3052         extern int vfstrace_register(
  3016   3053            const char *zTraceName,
................................................................................
  3022   3059         vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
  3023   3060   #endif
  3024   3061   #ifdef SQLITE_ENABLE_MULTIPLEX
  3025   3062       }else if( strcmp(z,"-multiplex")==0 ){
  3026   3063         extern int sqlite3_multiple_initialize(const char*,int);
  3027   3064         sqlite3_multiplex_initialize(0, 1);
  3028   3065   #endif
         3066  +    }else if( strcmp(z,"-mmap")==0 ){
         3067  +      sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
         3068  +      sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
  3029   3069       }else if( strcmp(z,"-vfs")==0 ){
  3030   3070         sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
  3031   3071         if( pVfs ){
  3032   3072           sqlite3_vfs_register(pVfs, 1);
  3033   3073         }else{
  3034   3074           fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
  3035   3075           exit(1);
................................................................................
  3107   3147         return 0;
  3108   3148       }else if( strcmp(z,"-interactive")==0 ){
  3109   3149         stdin_is_interactive = 1;
  3110   3150       }else if( strcmp(z,"-batch")==0 ){
  3111   3151         stdin_is_interactive = 0;
  3112   3152       }else if( strcmp(z,"-heap")==0 ){
  3113   3153         i++;
         3154  +    }else if( strcmp(z,"-mmap")==0 ){
         3155  +      i++;
  3114   3156       }else if( strcmp(z,"-vfs")==0 ){
  3115   3157         i++;
  3116   3158   #ifdef SQLITE_ENABLE_VFSTRACE
  3117   3159       }else if( strcmp(z,"-vfstrace")==0 ){
  3118   3160         i++;
  3119   3161   #endif
  3120   3162   #ifdef SQLITE_ENABLE_MULTIPLEX
................................................................................
  3124   3166       }else if( strcmp(z,"-help")==0 ){
  3125   3167         usage(1);
  3126   3168       }else if( strcmp(z,"-cmd")==0 ){
  3127   3169         if( i==argc-1 ) break;
  3128   3170         z = cmdline_option_value(argc,argv,++i);
  3129   3171         if( z[0]=='.' ){
  3130   3172           rc = do_meta_command(z, &data);
  3131         -        if( rc && bail_on_error ) return rc;
         3173  +        if( rc && bail_on_error ) return rc==2 ? 0 : rc;
  3132   3174         }else{
  3133   3175           open_db(&data);
  3134   3176           rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
  3135   3177           if( zErrMsg!=0 ){
  3136   3178             fprintf(stderr,"Error: %s\n", zErrMsg);
  3137   3179             if( bail_on_error ) return rc!=0 ? rc : 1;
  3138   3180           }else if( rc!=0 ){
................................................................................
  3148   3190     }
  3149   3191   
  3150   3192     if( zFirstCmd ){
  3151   3193       /* Run just the command that follows the database name
  3152   3194       */
  3153   3195       if( zFirstCmd[0]=='.' ){
  3154   3196         rc = do_meta_command(zFirstCmd, &data);
         3197  +      if( rc==2 ) rc = 0;
  3155   3198       }else{
  3156   3199         open_db(&data);
  3157   3200         rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
  3158   3201         if( zErrMsg!=0 ){
  3159   3202           fprintf(stderr,"Error: %s\n", zErrMsg);
  3160   3203           return rc!=0 ? rc : 1;
  3161   3204         }else if( rc!=0 ){

Changes to src/sqlite.h.in.

   416    416   #define SQLITE_MISMATCH    20   /* Data type mismatch */
   417    417   #define SQLITE_MISUSE      21   /* Library used incorrectly */
   418    418   #define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
   419    419   #define SQLITE_AUTH        23   /* Authorization denied */
   420    420   #define SQLITE_FORMAT      24   /* Auxiliary database format error */
   421    421   #define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
   422    422   #define SQLITE_NOTADB      26   /* File opened that is not a database file */
          423  +#define SQLITE_NOTICE      27   /* Notifications from sqlite3_log() */
          424  +#define SQLITE_WARNING     28   /* Warnings from sqlite3_log() */
   423    425   #define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
   424    426   #define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
   425    427   /* end-of-error-codes */
   426    428   
   427    429   /*
   428    430   ** CAPI3REF: Extended Result Codes
   429    431   ** KEYWORDS: {extended error code} {extended error codes}
................................................................................
   466    468   #define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
   467    469   #define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
   468    470   #define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
   469    471   #define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
   470    472   #define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
   471    473   #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
   472    474   #define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
          475  +#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
   473    476   #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
   474    477   #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
   475    478   #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
   476    479   #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
   477    480   #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
   478    481   #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
   479    482   #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
................................................................................
   485    488   #define SQLITE_CONSTRAINT_FOREIGNKEY   (SQLITE_CONSTRAINT | (3<<8))
   486    489   #define SQLITE_CONSTRAINT_FUNCTION     (SQLITE_CONSTRAINT | (4<<8))
   487    490   #define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (5<<8))
   488    491   #define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (6<<8))
   489    492   #define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
   490    493   #define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
   491    494   #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
          495  +#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
          496  +#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
   492    497   
   493    498   /*
   494    499   ** CAPI3REF: Flags For File Open Operations
   495    500   **
   496    501   ** These bit values are intended for use in the
   497    502   ** 3rd parameter to the [sqlite3_open_v2()] interface and
   498    503   ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
................................................................................
   724    729     int (*xDeviceCharacteristics)(sqlite3_file*);
   725    730     /* Methods above are valid for version 1 */
   726    731     int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
   727    732     int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
   728    733     void (*xShmBarrier)(sqlite3_file*);
   729    734     int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
   730    735     /* Methods above are valid for version 2 */
          736  +  int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
          737  +  int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
          738  +  /* Methods above are valid for version 3 */
   731    739     /* Additional methods may be added in future releases */
   732    740   };
   733    741   
   734    742   /*
   735    743   ** CAPI3REF: Standard File Control Opcodes
   736    744   **
   737    745   ** These integer constants are opcodes for the xFileControl method
................................................................................
   860    868   ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
   861    869   ** that the VFS encountered an error while handling the [PRAGMA] and the
   862    870   ** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
   863    871   ** file control occurs at the beginning of pragma statement analysis and so
   864    872   ** it is able to override built-in [PRAGMA] statements.
   865    873   **
   866    874   ** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
   867         -** ^This file-control may be invoked by SQLite on the database file handle
          875  +** ^The [SQLITE_FCNTL_BUSYHANDLER]
          876  +** file-control may be invoked by SQLite on the database file handle
   868    877   ** shortly after it is opened in order to provide a custom VFS with access
   869    878   ** to the connections busy-handler callback. The argument is of type (void **)
   870    879   ** - an array of two (void *) values. The first (void *) actually points
   871    880   ** to a function of type (int (*)(void *)). In order to invoke the connections
   872    881   ** busy-handler, this function should be invoked with the second (void *) in
   873    882   ** the array as the only argument. If it returns non-zero, then the operation
   874    883   ** should be retried. If it returns zero, the custom VFS should abandon the
   875    884   ** current operation.
   876    885   **
   877    886   ** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
   878         -** ^Application can invoke this file-control to have SQLite generate a
          887  +** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
          888  +** to have SQLite generate a
   879    889   ** temporary filename using the same algorithm that is followed to generate
   880    890   ** temporary filenames for TEMP tables and other internal uses.  The
   881    891   ** argument should be a char** which will be filled with the filename
   882    892   ** written into memory obtained from [sqlite3_malloc()].  The caller should
   883    893   ** invoke [sqlite3_free()] on the result to avoid a memory leak.
   884    894   **
          895  +** <li>[[SQLITE_FCNTL_MMAP_SIZE]]
          896  +** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the
          897  +** maximum number of bytes that will be used for memory-mapped I/O.
          898  +** The argument is a pointer to a value of type sqlite3_int64 that
          899  +** is an advisory maximum number of bytes in the file to memory map.  The
          900  +** pointer is overwritten with the old value.  The limit is not changed if
          901  +** the value originally pointed to is negative, and so the current limit 
          902  +** can be queried by passing in a pointer to a negative number.  This
          903  +** file-control is used internally to implement [PRAGMA mmap_size].
          904  +**
   885    905   ** </ul>
   886    906   */
   887    907   #define SQLITE_FCNTL_LOCKSTATE               1
   888    908   #define SQLITE_GET_LOCKPROXYFILE             2
   889    909   #define SQLITE_SET_LOCKPROXYFILE             3
   890    910   #define SQLITE_LAST_ERRNO                    4
   891    911   #define SQLITE_FCNTL_SIZE_HINT               5
................................................................................
   896    916   #define SQLITE_FCNTL_PERSIST_WAL            10
   897    917   #define SQLITE_FCNTL_OVERWRITE              11
   898    918   #define SQLITE_FCNTL_VFSNAME                12
   899    919   #define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
   900    920   #define SQLITE_FCNTL_PRAGMA                 14
   901    921   #define SQLITE_FCNTL_BUSYHANDLER            15
   902    922   #define SQLITE_FCNTL_TEMPFILENAME           16
          923  +#define SQLITE_FCNTL_MMAP_SIZE              18
   903    924   
   904    925   /*
   905    926   ** CAPI3REF: Mutex Handle
   906    927   **
   907    928   ** The mutex module within SQLite defines [sqlite3_mutex] to be an
   908    929   ** abstract type for a mutex object.  The SQLite core never looks
   909    930   ** at the internal representation of an [sqlite3_mutex].  It only
................................................................................
  1608   1629   ** disable the optimization allows the older, buggy application code to work
  1609   1630   ** without change even with newer versions of SQLite.
  1610   1631   **
  1611   1632   ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
  1612   1633   ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
  1613   1634   ** <dd> These options are obsolete and should not be used by new code.
  1614   1635   ** They are retained for backwards compatibility but are now no-ops.
  1615         -** </dl>
         1636  +** </dd>
  1616   1637   **
  1617   1638   ** [[SQLITE_CONFIG_SQLLOG]]
  1618   1639   ** <dt>SQLITE_CONFIG_SQLLOG
  1619   1640   ** <dd>This option is only available if sqlite is compiled with the
  1620         -** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
         1641  +** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should
  1621   1642   ** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
  1622   1643   ** The second should be of type (void*). The callback is invoked by the library
  1623   1644   ** in three separate circumstances, identified by the value passed as the
  1624   1645   ** fourth parameter. If the fourth parameter is 0, then the database connection
  1625   1646   ** passed as the second argument has just been opened. The third argument
  1626   1647   ** points to a buffer containing the name of the main database file. If the
  1627   1648   ** fourth parameter is 1, then the SQL statement that the third parameter
  1628   1649   ** points to has just been executed. Or, if the fourth parameter is 2, then
  1629   1650   ** the connection being passed as the second parameter is being closed. The
  1630         -** third parameter is passed NULL In this case.
         1651  +** third parameter is passed NULL In this case.  An example of using this
         1652  +** configuration option can be seen in the "test_sqllog.c" source file in
         1653  +** the canonical SQLite source tree.</dd>
         1654  +**
         1655  +** [[SQLITE_CONFIG_MMAP_SIZE]]
         1656  +** <dt>SQLITE_CONFIG_MMAP_SIZE
         1657  +** <dd>SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
         1658  +** that are the default mmap size limit (the default setting for
         1659  +** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
         1660  +** The default setting can be overridden by each database connection using
         1661  +** either the [PRAGMA mmap_size] command, or by using the
         1662  +** [SQLITE_FCNTL_MMAP_SIZE] file control.  The maximum allowed mmap size
         1663  +** cannot be changed at run-time.  Nor may the maximum allowed mmap size
         1664  +** exceed the compile-time maximum mmap size set by the
         1665  +** [SQLITE_MAX_MMAP_SIZE] compile-time option.  
         1666  +** If either argument to this option is negative, then that argument is
         1667  +** changed to its compile-time default.
  1631   1668   ** </dl>
  1632   1669   */
  1633   1670   #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
  1634   1671   #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
  1635   1672   #define SQLITE_CONFIG_SERIALIZED    3  /* nil */
  1636   1673   #define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
  1637   1674   #define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
................................................................................
  1647   1684   #define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
  1648   1685   #define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
  1649   1686   #define SQLITE_CONFIG_URI          17  /* int */
  1650   1687   #define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
  1651   1688   #define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
  1652   1689   #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
  1653   1690   #define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
         1691  +#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
  1654   1692   
  1655   1693   /*
  1656   1694   ** CAPI3REF: Database Connection Configuration Options
  1657   1695   **
  1658   1696   ** These constants are the available integer configuration options that
  1659   1697   ** can be passed as the second argument to the [sqlite3_db_config()] interface.
  1660   1698   **
................................................................................
  4178   4216   ** argument is SQLITE_STATIC, it means that the content pointer is constant
  4179   4217   ** and will never change.  It does not need to be destroyed.  ^The
  4180   4218   ** SQLITE_TRANSIENT value means that the content will likely change in
  4181   4219   ** the near future and that SQLite should make its own private copy of
  4182   4220   ** the content before returning.
  4183   4221   **
  4184   4222   ** The typedef is necessary to work around problems in certain
  4185         -** C++ compilers.  See ticket #2191.
         4223  +** C++ compilers.
  4186   4224   */
  4187   4225   typedef void (*sqlite3_destructor_type)(void*);
  4188   4226   #define SQLITE_STATIC      ((sqlite3_destructor_type)0)
  4189   4227   #define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)
  4190   4228   
  4191   4229   /*
  4192   4230   ** CAPI3REF: Setting The Result Of An SQL Function
................................................................................
  4977   5015   
  4978   5016   /*
  4979   5017   ** CAPI3REF: Load An Extension
  4980   5018   **
  4981   5019   ** ^This interface loads an SQLite extension library from the named file.
  4982   5020   **
  4983   5021   ** ^The sqlite3_load_extension() interface attempts to load an
  4984         -** SQLite extension library contained in the file zFile.
         5022  +** [SQLite extension] library contained in the file zFile.  If
         5023  +** the file cannot be loaded directly, attempts are made to load
         5024  +** with various operating-system specific extensions added.
         5025  +** So for example, if "samplelib" cannot be loaded, then names like
         5026  +** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
         5027  +** be tried also.
  4985   5028   **
  4986   5029   ** ^The entry point is zProc.
  4987         -** ^zProc may be 0, in which case the name of the entry point
  4988         -** defaults to "sqlite3_extension_init".
         5030  +** ^(zProc may be 0, in which case SQLite will try to come up with an
         5031  +** entry point name on its own.  It first tries "sqlite3_extension_init".
         5032  +** If that does not work, it constructs a name "sqlite3_X_init" where the
         5033  +** X is consists of the lower-case equivalent of all ASCII alphabetic
         5034  +** characters in the filename from the last "/" to the first following
         5035  +** "." and omitting any initial "lib".)^
  4989   5036   ** ^The sqlite3_load_extension() interface returns
  4990   5037   ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
  4991   5038   ** ^If an error occurs and pzErrMsg is not 0, then the
  4992   5039   ** [sqlite3_load_extension()] interface shall attempt to
  4993   5040   ** fill *pzErrMsg with error message text stored in memory
  4994   5041   ** obtained from [sqlite3_malloc()]. The calling function
  4995   5042   ** should free this memory by calling [sqlite3_free()].
................................................................................
  5007   5054     char **pzErrMsg       /* Put error message here if not 0 */
  5008   5055   );
  5009   5056   
  5010   5057   /*
  5011   5058   ** CAPI3REF: Enable Or Disable Extension Loading
  5012   5059   **
  5013   5060   ** ^So as not to open security holes in older applications that are
  5014         -** unprepared to deal with extension loading, and as a means of disabling
  5015         -** extension loading while evaluating user-entered SQL, the following API
         5061  +** unprepared to deal with [extension loading], and as a means of disabling
         5062  +** [extension loading] while evaluating user-entered SQL, the following API
  5016   5063   ** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
  5017   5064   **
  5018         -** ^Extension loading is off by default. See ticket #1863.
         5065  +** ^Extension loading is off by default.
  5019   5066   ** ^Call the sqlite3_enable_load_extension() routine with onoff==1
  5020   5067   ** to turn extension loading on and call it with onoff==0 to turn
  5021   5068   ** it back off again.
  5022   5069   */
  5023   5070   int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
  5024   5071   
  5025   5072   /*
  5026   5073   ** CAPI3REF: Automatically Load Statically Linked Extensions
  5027   5074   **
  5028   5075   ** ^This interface causes the xEntryPoint() function to be invoked for
  5029   5076   ** each new [database connection] that is created.  The idea here is that
  5030         -** xEntryPoint() is the entry point for a statically linked SQLite extension
         5077  +** xEntryPoint() is the entry point for a statically linked [SQLite extension]
  5031   5078   ** that is to be automatically loaded into all new database connections.
  5032   5079   **
  5033   5080   ** ^(Even though the function prototype shows that xEntryPoint() takes
  5034   5081   ** no arguments and returns void, SQLite invokes xEntryPoint() with three
  5035   5082   ** arguments and expects and integer result as if the signature of the
  5036   5083   ** entry point where as follows:
  5037   5084   **
................................................................................
  6803   6850   ** and extensions to compare the contents of two buffers containing UTF-8
  6804   6851   ** strings in a case-independent fashion, using the same definition of "case
  6805   6852   ** independence" that SQLite uses internally when comparing identifiers.
  6806   6853   */
  6807   6854   int sqlite3_stricmp(const char *, const char *);
  6808   6855   int sqlite3_strnicmp(const char *, const char *, int);
  6809   6856   
         6857  +/*
         6858  +** CAPI3REF: String Globbing
         6859  +*
         6860  +** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
         6861  +** the glob pattern P, and it returns non-zero if string X does not match
         6862  +** the glob pattern P.  ^The definition of glob pattern matching used in
         6863  +** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
         6864  +** SQL dialect used by SQLite.  ^The sqlite3_strglob(P,X) function is case
         6865  +** sensitive.
         6866  +**
         6867  +** Note that this routine returns zero on a match and non-zero if the strings
         6868  +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
         6869  +*/
         6870  +int sqlite3_strglob(const char *zGlob, const char *zStr);
         6871  +
  6810   6872   /*
  6811   6873   ** CAPI3REF: Error Logging Interface
  6812   6874   **
  6813   6875   ** ^The [sqlite3_log()] interface writes a message into the error log
  6814   6876   ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
  6815   6877   ** ^If logging is enabled, the zFormat string and subsequent arguments are
  6816   6878   ** used with [sqlite3_snprintf()] to generate the final output string.

Changes to src/sqlite3ext.h.

   465    465   #define sqlite3_uri_boolean            sqlite3_api->uri_boolean
   466    466   #define sqlite3_uri_int64              sqlite3_api->uri_int64
   467    467   #define sqlite3_uri_parameter          sqlite3_api->uri_parameter
   468    468   #define sqlite3_uri_vsnprintf          sqlite3_api->vsnprintf
   469    469   #define sqlite3_wal_checkpoint_v2      sqlite3_api->wal_checkpoint_v2
   470    470   #endif /* SQLITE_CORE */
   471    471   
   472         -#define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api = 0;
   473         -#define SQLITE_EXTENSION_INIT2(v)  sqlite3_api = v;
          472  +#ifndef SQLITE_CORE
          473  +  /* This case when the file really is being compiled as a loadable 
          474  +  ** extension */
          475  +# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
          476  +# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;
          477  +#else
          478  +  /* This case when the file is being statically linked into the 
          479  +  ** application */
          480  +# define SQLITE_EXTENSION_INIT1     /*no-op*/
          481  +# define SQLITE_EXTENSION_INIT2(v)  (void)v; /* unused parameter */
          482  +#endif
   474    483   
   475    484   #endif /* _SQLITE3EXT_H_ */

Changes to src/sqliteInt.h.

   118    118   ** threads can use SQLite as long as no two threads try to use the same
   119    119   ** database connection at the same time.
   120    120   **
   121    121   ** Older versions of SQLite used an optional THREADSAFE macro.
   122    122   ** We support that for legacy.
   123    123   */
   124    124   #if !defined(SQLITE_THREADSAFE)
   125         -#if defined(THREADSAFE)
   126         -# define SQLITE_THREADSAFE THREADSAFE
   127         -#else
   128         -# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
   129         -#endif
          125  +# if defined(THREADSAFE)
          126  +#   define SQLITE_THREADSAFE THREADSAFE
          127  +# else
          128  +#   define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
          129  +# endif
   130    130   #endif
   131    131   
   132    132   /*
   133    133   ** Powersafe overwrite is on by default.  But can be turned off using
   134    134   ** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
   135    135   */
   136    136   #ifndef SQLITE_POWERSAFE_OVERWRITE
................................................................................
   388    388   
   389    389   /*
   390    390   ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
   391    391   ** on the command-line
   392    392   */
   393    393   #ifndef SQLITE_TEMP_STORE
   394    394   # define SQLITE_TEMP_STORE 1
          395  +# define SQLITE_TEMP_STORE_xc 1  /* Exclude from ctime.c */
   395    396   #endif
   396    397   
   397    398   /*
   398    399   ** GCC does not define the offsetof() macro so we'll have to do it
   399    400   ** ourselves.
   400    401   */
   401    402   #ifndef offsetof
................................................................................
   535    536   */
   536    537   #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
   537    538   # define EIGHT_BYTE_ALIGNMENT(X)   ((((char*)(X) - (char*)0)&3)==0)
   538    539   #else
   539    540   # define EIGHT_BYTE_ALIGNMENT(X)   ((((char*)(X) - (char*)0)&7)==0)
   540    541   #endif
   541    542   
          543  +/*
          544  +** Disable MMAP on platforms where it is known to not work
          545  +*/
          546  +#if defined(__OpenBSD__) || defined(__QNXNTO__)
          547  +# undef SQLITE_MAX_MMAP_SIZE
          548  +# define SQLITE_MAX_MMAP_SIZE 0
          549  +#endif
          550  +
          551  +/*
          552  +** Default maximum size of memory used by memory-mapped I/O in the VFS
          553  +*/
          554  +#ifdef __APPLE__
          555  +# include <TargetConditionals.h>
          556  +# if TARGET_OS_IPHONE
          557  +#   undef SQLITE_MAX_MMAP_SIZE
          558  +#   define SQLITE_MAX_MMAP_SIZE 0
          559  +# endif
          560  +#endif
          561  +#ifndef SQLITE_MAX_MMAP_SIZE
          562  +# if defined(__linux__) \
          563  +  || defined(_WIN32) \
          564  +  || (defined(__APPLE__) && defined(__MACH__)) \
          565  +  || defined(__sun)
          566  +#   define SQLITE_MAX_MMAP_SIZE 2147483648
          567  +# else
          568  +#   define SQLITE_MAX_MMAP_SIZE 0
          569  +# endif
          570  +# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */
          571  +#endif
          572  +
          573  +/*
          574  +** The default MMAP_SIZE is zero on all platforms.  Or, even if a larger
          575  +** default MMAP_SIZE is specified at compile-time, make sure that it does
          576  +** not exceed the maximum mmap size.
          577  +*/
          578  +#ifndef SQLITE_DEFAULT_MMAP_SIZE
          579  +# define SQLITE_DEFAULT_MMAP_SIZE 0
          580  +# define SQLITE_DEFAULT_MMAP_SIZE_xc 1  /* Exclude from ctime.c */
          581  +#endif
          582  +#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
          583  +# undef SQLITE_DEFAULT_MMAP_SIZE
          584  +# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
          585  +#endif
   542    586   
   543    587   /*
   544    588   ** An instance of the following structure is used to store the busy-handler
   545    589   ** callback for a given sqlite handle. 
   546    590   **
   547    591   ** The sqlite.busyHandler member of the sqlite struct contains the busy
   548    592   ** callback for the database handle. Each pager opened via the sqlite
................................................................................
   831    875     struct Vdbe *pVdbe;           /* List of active virtual machines */
   832    876     CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
   833    877     sqlite3_mutex *mutex;         /* Connection mutex */
   834    878     Db *aDb;                      /* All backends */
   835    879     int nDb;                      /* Number of backends currently in use */
   836    880     int flags;                    /* Miscellaneous flags. See below */
   837    881     i64 lastRowid;                /* ROWID of most recent insert (see above) */
          882  +  i64 szMmap;                   /* Default mmap_size setting */
   838    883     unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
   839    884     int errCode;                  /* Most recent error code (SQLITE_*) */
   840    885     int errMask;                  /* & result codes with this before returning */
   841    886     u16 dbOptFlags;               /* Flags to enable/disable optimizations */
   842    887     u8 autoCommit;                /* The auto-commit flag. */
   843    888     u8 temp_store;                /* 1: file 2: memory 0: default */
   844    889     u8 mallocFailed;              /* True if we have seen a malloc failure */
................................................................................
  2074   2119   /*
  2075   2120   ** Allowed values for the NameContext, ncFlags field.
  2076   2121   */
  2077   2122   #define NC_AllowAgg  0x01    /* Aggregate functions are allowed here */
  2078   2123   #define NC_HasAgg    0x02    /* One or more aggregate functions seen */
  2079   2124   #define NC_IsCheck   0x04    /* True if resolving names in a CHECK constraint */
  2080   2125   #define NC_InAggFunc 0x08    /* True if analyzing arguments to an agg func */
         2126  +#define NC_AsMaybe   0x10    /* Resolve to AS terms of the result set only
         2127  +                             ** if no other resolution is available */
  2081   2128   
  2082   2129   /*
  2083   2130   ** An instance of the following structure contains all information
  2084   2131   ** needed to generate code for a single SELECT statement.
  2085   2132   **
  2086   2133   ** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
  2087   2134   ** If there is a LIMIT clause, the parser sets nLimit to the value of the
................................................................................
  2513   2560     int nLookaside;                   /* Default lookaside buffer count */
  2514   2561     sqlite3_mem_methods m;            /* Low-level memory allocation interface */
  2515   2562     sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
  2516   2563     sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
  2517   2564     void *pHeap;                      /* Heap storage space */
  2518   2565     int nHeap;                        /* Size of pHeap[] */
  2519   2566     int mnReq, mxReq;                 /* Min and max heap requests sizes */
         2567  +  sqlite3_int64 szMmap;             /* mmap() space per open file */
         2568  +  sqlite3_int64 mxMmap;             /* Maximum value for szMmap */
  2520   2569     void *pScratch;                   /* Scratch memory */
  2521   2570     int szScratch;                    /* Size of each scratch buffer */
  2522   2571     int nScratch;                     /* Number of scratch buffers */
  2523   2572     void *pPage;                      /* Page cache memory */
  2524   2573     int szPage;                       /* Size of each page in pPage[] */
  2525   2574     int nPage;                        /* Number of pages in pPage[] */
  2526   2575     int mxParserStack;                /* maximum depth of the parser stack */

Changes to src/test1.c.

   112    112     }
   113    113     return TCL_OK;
   114    114   }
   115    115   
   116    116   
   117    117   const char *sqlite3TestErrorName(int rc){
   118    118     const char *zName = 0;
   119         -  switch( rc ){
   120         -    case SQLITE_OK:                  zName = "SQLITE_OK";                break;
   121         -    case SQLITE_ERROR:               zName = "SQLITE_ERROR";             break;
   122         -    case SQLITE_INTERNAL:            zName = "SQLITE_INTERNAL";          break;
   123         -    case SQLITE_PERM:                zName = "SQLITE_PERM";              break;
   124         -    case SQLITE_ABORT:               zName = "SQLITE_ABORT";             break;
   125         -    case SQLITE_BUSY:                zName = "SQLITE_BUSY";              break;
   126         -    case SQLITE_LOCKED:              zName = "SQLITE_LOCKED";            break;
   127         -    case SQLITE_LOCKED_SHAREDCACHE:  zName = "SQLITE_LOCKED_SHAREDCACHE";break;
   128         -    case SQLITE_NOMEM:               zName = "SQLITE_NOMEM";             break;
   129         -    case SQLITE_READONLY:            zName = "SQLITE_READONLY";          break;
   130         -    case SQLITE_INTERRUPT:           zName = "SQLITE_INTERRUPT";         break;
   131         -    case SQLITE_IOERR:               zName = "SQLITE_IOERR";             break;
   132         -    case SQLITE_CORRUPT:             zName = "SQLITE_CORRUPT";           break;
   133         -    case SQLITE_NOTFOUND:            zName = "SQLITE_NOTFOUND";          break;
   134         -    case SQLITE_FULL:                zName = "SQLITE_FULL";              break;
   135         -    case SQLITE_CANTOPEN:            zName = "SQLITE_CANTOPEN";          break;
   136         -    case SQLITE_PROTOCOL:            zName = "SQLITE_PROTOCOL";          break;
   137         -    case SQLITE_EMPTY:               zName = "SQLITE_EMPTY";             break;
   138         -    case SQLITE_SCHEMA:              zName = "SQLITE_SCHEMA";            break;
   139         -    case SQLITE_TOOBIG:              zName = "SQLITE_TOOBIG";            break;
   140         -    case SQLITE_CONSTRAINT:          zName = "SQLITE_CONSTRAINT";        break;
   141         -    case SQLITE_CONSTRAINT_UNIQUE:   zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
   142         -    case SQLITE_CONSTRAINT_TRIGGER:  zName = "SQLITE_CONSTRAINT_TRIGGER";break;
   143         -    case SQLITE_CONSTRAINT_FOREIGNKEY:
   144         -                                 zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
   145         -    case SQLITE_CONSTRAINT_CHECK:    zName = "SQLITE_CONSTRAINT_CHECK";  break;
   146         -    case SQLITE_CONSTRAINT_PRIMARYKEY:
   147         -                                 zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
   148         -    case SQLITE_CONSTRAINT_NOTNULL:  zName = "SQLITE_CONSTRAINT_NOTNULL";break;
   149         -    case SQLITE_CONSTRAINT_COMMITHOOK:
   150         -                                 zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
   151         -    case SQLITE_CONSTRAINT_VTAB:     zName = "SQLITE_CONSTRAINT_VTAB";   break;
   152         -    case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break;
   153         -    case SQLITE_MISMATCH:            zName = "SQLITE_MISMATCH";          break;
   154         -    case SQLITE_MISUSE:              zName = "SQLITE_MISUSE";            break;
   155         -    case SQLITE_NOLFS:               zName = "SQLITE_NOLFS";             break;
   156         -    case SQLITE_AUTH:                zName = "SQLITE_AUTH";              break;
   157         -    case SQLITE_FORMAT:              zName = "SQLITE_FORMAT";            break;
   158         -    case SQLITE_RANGE:               zName = "SQLITE_RANGE";             break;
   159         -    case SQLITE_NOTADB:              zName = "SQLITE_NOTADB";            break;
   160         -    case SQLITE_ROW:                 zName = "SQLITE_ROW";               break;
   161         -    case SQLITE_DONE:                zName = "SQLITE_DONE";              break;
   162         -    case SQLITE_IOERR_READ:          zName = "SQLITE_IOERR_READ";        break;
   163         -    case SQLITE_IOERR_SHORT_READ:    zName = "SQLITE_IOERR_SHORT_READ";  break;
   164         -    case SQLITE_IOERR_WRITE:         zName = "SQLITE_IOERR_WRITE";       break;
   165         -    case SQLITE_IOERR_FSYNC:         zName = "SQLITE_IOERR_FSYNC";       break;
   166         -    case SQLITE_IOERR_DIR_FSYNC:     zName = "SQLITE_IOERR_DIR_FSYNC";   break;
   167         -    case SQLITE_IOERR_TRUNCATE:      zName = "SQLITE_IOERR_TRUNCATE";    break;
   168         -    case SQLITE_IOERR_FSTAT:         zName = "SQLITE_IOERR_FSTAT";       break;
   169         -    case SQLITE_IOERR_UNLOCK:        zName = "SQLITE_IOERR_UNLOCK";      break;
   170         -    case SQLITE_IOERR_RDLOCK:        zName = "SQLITE_IOERR_RDLOCK";      break;
   171         -    case SQLITE_IOERR_DELETE:        zName = "SQLITE_IOERR_DELETE";      break;
   172         -    case SQLITE_IOERR_BLOCKED:       zName = "SQLITE_IOERR_BLOCKED";     break;
   173         -    case SQLITE_IOERR_NOMEM:         zName = "SQLITE_IOERR_NOMEM";       break;
   174         -    case SQLITE_IOERR_ACCESS:        zName = "SQLITE_IOERR_ACCESS";      break;
   175         -    case SQLITE_IOERR_CHECKRESERVEDLOCK:
   176         -                               zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
   177         -    case SQLITE_IOERR_LOCK:          zName = "SQLITE_IOERR_LOCK";        break;
   178         -    case SQLITE_CORRUPT_VTAB:        zName = "SQLITE_CORRUPT_VTAB";      break;
   179         -    case SQLITE_READONLY_RECOVERY:   zName = "SQLITE_READONLY_RECOVERY"; break;
   180         -    case SQLITE_READONLY_CANTLOCK:   zName = "SQLITE_READONLY_CANTLOCK"; break;
   181         -    case SQLITE_READONLY_ROLLBACK:   zName = "SQLITE_READONLY_ROLLBACK"; break;
   182         -    default:                         zName = "SQLITE_Unknown";           break;
   183         -  }
          119  +  int i;
          120  +  for(i=0; i<2 && zName==0; i++, rc &= 0xff){
          121  +    switch( rc ){
          122  +      case SQLITE_OK:                  zName = "SQLITE_OK";                break;
          123  +      case SQLITE_ERROR:               zName = "SQLITE_ERROR";             break;
          124  +      case SQLITE_INTERNAL:            zName = "SQLITE_INTERNAL";          break;
          125  +      case SQLITE_PERM:                zName = "SQLITE_PERM";              break;
          126  +      case SQLITE_ABORT:               zName = "SQLITE_ABORT";             break;
          127  +      case SQLITE_BUSY:                zName = "SQLITE_BUSY";              break;
          128  +      case SQLITE_LOCKED:              zName = "SQLITE_LOCKED";            break;
          129  +      case SQLITE_LOCKED_SHAREDCACHE:  zName = "SQLITE_LOCKED_SHAREDCACHE";break;
          130  +      case SQLITE_NOMEM:               zName = "SQLITE_NOMEM";             break;
          131  +      case SQLITE_READONLY:            zName = "SQLITE_READONLY";          break;
          132  +      case SQLITE_INTERRUPT:           zName = "SQLITE_INTERRUPT";         break;
          133  +      case SQLITE_IOERR:               zName = "SQLITE_IOERR";             break;
          134  +      case SQLITE_CORRUPT:             zName = "SQLITE_CORRUPT";           break;
          135  +      case SQLITE_NOTFOUND:            zName = "SQLITE_NOTFOUND";          break;
          136  +      case SQLITE_FULL:                zName = "SQLITE_FULL";              break;
          137  +      case SQLITE_CANTOPEN:            zName = "SQLITE_CANTOPEN";          break;
          138  +      case SQLITE_PROTOCOL:            zName = "SQLITE_PROTOCOL";          break;
          139  +      case SQLITE_EMPTY:               zName = "SQLITE_EMPTY";             break;
          140  +      case SQLITE_SCHEMA:              zName = "SQLITE_SCHEMA";            break;
          141  +      case SQLITE_TOOBIG:              zName = "SQLITE_TOOBIG";            break;
          142  +      case SQLITE_CONSTRAINT:          zName = "SQLITE_CONSTRAINT";        break;
          143  +      case SQLITE_CONSTRAINT_UNIQUE:   zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
          144  +      case SQLITE_CONSTRAINT_TRIGGER:  zName = "SQLITE_CONSTRAINT_TRIGGER";break;
          145  +      case SQLITE_CONSTRAINT_FOREIGNKEY:
          146  +                                   zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
          147  +      case SQLITE_CONSTRAINT_CHECK:    zName = "SQLITE_CONSTRAINT_CHECK";  break;
          148  +      case SQLITE_CONSTRAINT_PRIMARYKEY:
          149  +                                   zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
          150  +      case SQLITE_CONSTRAINT_NOTNULL:  zName = "SQLITE_CONSTRAINT_NOTNULL";break;
          151  +      case SQLITE_CONSTRAINT_COMMITHOOK:
          152  +                                   zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
          153  +      case SQLITE_CONSTRAINT_VTAB:     zName = "SQLITE_CONSTRAINT_VTAB";   break;
          154  +      case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break;
          155  +      case SQLITE_MISMATCH:            zName = "SQLITE_MISMATCH";          break;
          156  +      case SQLITE_MISUSE:              zName = "SQLITE_MISUSE";            break;
          157  +      case SQLITE_NOLFS:               zName = "SQLITE_NOLFS";             break;
          158  +      case SQLITE_AUTH:                zName = "SQLITE_AUTH";              break;
          159  +      case SQLITE_FORMAT:              zName = "SQLITE_FORMAT";            break;
          160  +      case SQLITE_RANGE:               zName = "SQLITE_RANGE";             break;
          161  +      case SQLITE_NOTADB:              zName = "SQLITE_NOTADB";            break;
          162  +      case SQLITE_ROW:                 zName = "SQLITE_ROW";               break;
          163  +      case SQLITE_NOTICE:              zName = "SQLITE_NOTICE";            break;
          164  +      case SQLITE_WARNING:             zName = "SQLITE_WARNING";           break;
          165  +      case SQLITE_DONE:                zName = "SQLITE_DONE";              break;
          166  +      case SQLITE_IOERR_READ:          zName = "SQLITE_IOERR_READ";        break;
          167  +      case SQLITE_IOERR_SHORT_READ:    zName = "SQLITE_IOERR_SHORT_READ";  break;
          168  +      case SQLITE_IOERR_WRITE:         zName = "SQLITE_IOERR_WRITE";       break;
          169  +      case SQLITE_IOERR_FSYNC:         zName = "SQLITE_IOERR_FSYNC";       break;
          170  +      case SQLITE_IOERR_DIR_FSYNC:     zName = "SQLITE_IOERR_DIR_FSYNC";   break;
          171  +      case SQLITE_IOERR_TRUNCATE:      zName = "SQLITE_IOERR_TRUNCATE";    break;
          172  +      case SQLITE_IOERR_FSTAT:         zName = "SQLITE_IOERR_FSTAT";       break;
          173  +      case SQLITE_IOERR_UNLOCK:        zName = "SQLITE_IOERR_UNLOCK";      break;
          174  +      case SQLITE_IOERR_RDLOCK:        zName = "SQLITE_IOERR_RDLOCK";      break;
          175  +      case SQLITE_IOERR_DELETE:        zName = "SQLITE_IOERR_DELETE";      break;
          176  +      case SQLITE_IOERR_BLOCKED:       zName = "SQLITE_IOERR_BLOCKED";     break;
          177  +      case SQLITE_IOERR_NOMEM:         zName = "SQLITE_IOERR_NOMEM";       break;
          178  +      case SQLITE_IOERR_ACCESS:        zName = "SQLITE_IOERR_ACCESS";      break;
          179  +      case SQLITE_IOERR_CHECKRESERVEDLOCK:
          180  +                                 zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
          181  +      case SQLITE_IOERR_LOCK:          zName = "SQLITE_IOERR_LOCK";        break;
          182  +      case SQLITE_CORRUPT_VTAB:        zName = "SQLITE_CORRUPT_VTAB";      break;
          183  +      case SQLITE_READONLY_RECOVERY:   zName = "SQLITE_READONLY_RECOVERY"; break;
          184  +      case SQLITE_READONLY_CANTLOCK:   zName = "SQLITE_READONLY_CANTLOCK"; break;
          185  +      case SQLITE_READONLY_ROLLBACK:   zName = "SQLITE_READONLY_ROLLBACK"; break;
          186  +    }
          187  +  }
          188  +  if( zName==0 ) zName = "SQLITE_Unknown";
   184    189     return zName;
   185    190   }
   186    191   #define t1ErrorName sqlite3TestErrorName
   187    192   
   188    193   /*
   189    194   ** Convert an sqlite3_stmt* into an sqlite3*.  This depends on the
   190    195   ** fact that the sqlite3* is the first field in the Vdbe structure.
................................................................................
  5839   5844         break;
  5840   5845       }
  5841   5846     }
  5842   5847   
  5843   5848     Tcl_ResetResult(interp);
  5844   5849     return TCL_OK;
  5845   5850   }
         5851  +
         5852  +#if SQLITE_OS_UNIX
         5853  +#include <sys/time.h>
         5854  +#include <sys/resource.h>
         5855  +
         5856  +static int test_getrusage(
         5857  +  void * clientData,
         5858  +  Tcl_Interp *interp,
         5859  +  int objc,
         5860  +  Tcl_Obj *CONST objv[]
         5861  +){
         5862  +  char buf[1024];
         5863  +  struct rusage r;
         5864  +  memset(&r, 0, sizeof(r));
         5865  +  getrusage(RUSAGE_SELF, &r);
         5866  +
         5867  +  sprintf(buf, "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d", 
         5868  +    (int)r.ru_utime.tv_sec, (int)r.ru_utime.tv_usec, 
         5869  +    (int)r.ru_stime.tv_sec, (int)r.ru_stime.tv_usec, 
         5870  +    (int)r.ru_minflt, (int)r.ru_majflt
         5871  +  );
         5872  +  Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
         5873  +  return TCL_OK;
         5874  +}
         5875  +#endif
  5846   5876   
  5847   5877   #if SQLITE_OS_WIN
  5848   5878   /*
  5849   5879   ** Information passed from the main thread into the windows file locker
  5850   5880   ** background thread.
  5851   5881   */
  5852   5882   struct win32FileLocker {
................................................................................
  6229   6259        { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
  6230   6260        { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },
  6231   6261        { "test_sqlite3_log",         test_sqlite3_log, 0  },
  6232   6262   #ifndef SQLITE_OMIT_EXPLAIN
  6233   6263        { "print_explain_query_plan", test_print_eqp, 0  },
  6234   6264   #endif
  6235   6265        { "sqlite3_test_control", test_test_control },
         6266  +#if SQLITE_OS_UNIX
         6267  +     { "getrusage", test_getrusage },
         6268  +#endif
  6236   6269     };
  6237   6270     static int bitmask_size = sizeof(Bitmask)*8;
  6238   6271     int i;
  6239   6272     extern int sqlite3_sync_count, sqlite3_fullsync_count;
  6240   6273     extern int sqlite3_opentemp_count;
  6241   6274     extern int sqlite3_like_count;
  6242   6275     extern int sqlite3_xferopt_count;

Changes to src/test2.c.

    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include "tcl.h"
    18     18   #include <stdlib.h>
    19     19   #include <string.h>
    20     20   #include <ctype.h>
    21     21   
    22         -/*
    23         -** Interpret an SQLite error number
    24         -*/
    25         -static char *errorName(int rc){
    26         -  char *zName;
    27         -  switch( rc ){
    28         -    case SQLITE_OK:         zName = "SQLITE_OK";          break;
    29         -    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
    30         -    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
    31         -    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
    32         -    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
    33         -    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
    34         -    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
    35         -    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
    36         -    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
    37         -    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
    38         -    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
    39         -    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
    40         -    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
    41         -    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
    42         -    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
    43         -    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
    44         -    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
    45         -    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
    46         -    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
    47         -    default:                zName = "SQLITE_Unknown";     break;
    48         -  }
    49         -  return zName;
    50         -}
           22  +extern const char *sqlite3TestErrorName(int rc);
    51     23   
    52     24   /*
    53     25   ** Page size and reserved size used for testing.
    54     26   */
    55     27   static int test_pagesize = 1024;
    56     28   
    57     29   /*
................................................................................
    83     55       return TCL_ERROR;
    84     56     }
    85     57     if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
    86     58     rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0,
    87     59         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB,
    88     60         pager_test_reiniter);
    89     61     if( rc!=SQLITE_OK ){
    90         -    Tcl_AppendResult(interp, errorName(rc), 0);
           62  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
    91     63       return TCL_ERROR;
    92     64     }
    93     65     sqlite3PagerSetCachesize(pPager, nPage);
    94     66     pageSize = test_pagesize;
    95     67     sqlite3PagerSetPagesize(pPager, &pageSize, -1);
    96     68     sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPager);
    97     69     Tcl_AppendResult(interp, zBuf, 0);
................................................................................
   115     87       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   116     88          " ID\"", 0);
   117     89       return TCL_ERROR;
   118     90     }
   119     91     pPager = sqlite3TestTextToPtr(argv[1]);
   120     92     rc = sqlite3PagerClose(pPager);
   121     93     if( rc!=SQLITE_OK ){
   122         -    Tcl_AppendResult(interp, errorName(rc), 0);
           94  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   123     95       return TCL_ERROR;
   124     96     }
   125     97     return TCL_OK;
   126     98   }
   127     99   
   128    100   /*
   129    101   ** Usage:   pager_rollback ID
................................................................................
   142    114       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   143    115          " ID\"", 0);
   144    116       return TCL_ERROR;
   145    117     }
   146    118     pPager = sqlite3TestTextToPtr(argv[1]);
   147    119     rc = sqlite3PagerRollback(pPager);
   148    120     if( rc!=SQLITE_OK ){
   149         -    Tcl_AppendResult(interp, errorName(rc), 0);
          121  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   150    122       return TCL_ERROR;
   151    123     }
   152    124     return TCL_OK;
   153    125   }
   154    126   
   155    127   /*
   156    128   ** Usage:   pager_commit ID
................................................................................
   169    141       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   170    142          " ID\"", 0);
   171    143       return TCL_ERROR;
   172    144     }
   173    145     pPager = sqlite3TestTextToPtr(argv[1]);
   174    146     rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0);
   175    147     if( rc!=SQLITE_OK ){
   176         -    Tcl_AppendResult(interp, errorName(rc), 0);
          148  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   177    149       return TCL_ERROR;
   178    150     }
   179    151     rc = sqlite3PagerCommitPhaseTwo(pPager);
   180    152     if( rc!=SQLITE_OK ){
   181         -    Tcl_AppendResult(interp, errorName(rc), 0);
          153  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   182    154       return TCL_ERROR;
   183    155     }
   184    156     return TCL_OK;
   185    157   }
   186    158   
   187    159   /*
   188    160   ** Usage:   pager_stmt_begin ID
................................................................................
   201    173       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   202    174          " ID\"", 0);
   203    175       return TCL_ERROR;
   204    176     }
   205    177     pPager = sqlite3TestTextToPtr(argv[1]);
   206    178     rc = sqlite3PagerOpenSavepoint(pPager, 1);
   207    179     if( rc!=SQLITE_OK ){
   208         -    Tcl_AppendResult(interp, errorName(rc), 0);
          180  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   209    181       return TCL_ERROR;
   210    182     }
   211    183     return TCL_OK;
   212    184   }
   213    185   
   214    186   /*
   215    187   ** Usage:   pager_stmt_rollback ID
................................................................................
   229    201          " ID\"", 0);
   230    202       return TCL_ERROR;
   231    203     }
   232    204     pPager = sqlite3TestTextToPtr(argv[1]);
   233    205     rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, 0);
   234    206     sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
   235    207     if( rc!=SQLITE_OK ){
   236         -    Tcl_AppendResult(interp, errorName(rc), 0);
          208  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   237    209       return TCL_ERROR;
   238    210     }
   239    211     return TCL_OK;
   240    212   }
   241    213   
   242    214   /*
   243    215   ** Usage:   pager_stmt_commit ID
................................................................................
   256    228       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   257    229          " ID\"", 0);
   258    230       return TCL_ERROR;
   259    231     }
   260    232     pPager = sqlite3TestTextToPtr(argv[1]);
   261    233     rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
   262    234     if( rc!=SQLITE_OK ){
   263         -    Tcl_AppendResult(interp, errorName(rc), 0);
          235  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   264    236       return TCL_ERROR;
   265    237     }
   266    238     return TCL_OK;
   267    239   }
   268    240   
   269    241   /*
   270    242   ** Usage:   pager_stats ID
................................................................................
   349    321     pPager = sqlite3TestTextToPtr(argv[1]);
   350    322     if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
   351    323     rc = sqlite3PagerSharedLock(pPager);
   352    324     if( rc==SQLITE_OK ){
   353    325       rc = sqlite3PagerGet(pPager, pgno, &pPage);
   354    326     }
   355    327     if( rc!=SQLITE_OK ){
   356         -    Tcl_AppendResult(interp, errorName(rc), 0);
          328  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   357    329       return TCL_ERROR;
   358    330     }
   359    331     sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
   360    332     Tcl_AppendResult(interp, zBuf, 0);
   361    333     return TCL_OK;
   362    334   }
   363    335   
................................................................................
   503    475       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   504    476          " PAGE DATA\"", 0);
   505    477       return TCL_ERROR;
   506    478     }
   507    479     pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
   508    480     rc = sqlite3PagerWrite(pPage);
   509    481     if( rc!=SQLITE_OK ){
   510         -    Tcl_AppendResult(interp, errorName(rc), 0);
          482  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   511    483       return TCL_ERROR;
   512    484     }
   513    485     pData = sqlite3PagerGetData(pPage);
   514    486     strncpy(pData, argv[2], test_pagesize-1);
   515    487     pData[test_pagesize-1] = 0;
   516    488     return TCL_OK;
   517    489   }
................................................................................
   552    524     if( zFile==0 ) return TCL_ERROR;
   553    525     memcpy(zFile, argv[2], nFile+1);
   554    526     zFile[nFile+1] = 0;
   555    527     rc = sqlite3OsOpenMalloc(pVfs, zFile, &fd, 
   556    528         (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0
   557    529     );
   558    530     if( rc ){
   559         -    Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
          531  +    Tcl_AppendResult(interp, "open failed: ", sqlite3TestErrorName(rc), 0);
   560    532       sqlite3_free(zFile);
   561    533       return TCL_ERROR;
   562    534     }
   563    535     offset = n;
   564    536     offset *= 1024*1024;
   565    537     rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
   566    538     sqlite3OsCloseFree(fd);
   567    539     sqlite3_free(zFile);
   568    540     if( rc ){
   569         -    Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
          541  +    Tcl_AppendResult(interp, "write failed: ", sqlite3TestErrorName(rc), 0);
   570    542       return TCL_ERROR;
   571    543     }
   572    544     return TCL_OK;
   573    545   }
   574    546   #endif
   575    547   
   576    548   

Changes to src/test3.c.

    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include "btreeInt.h"
    18     18   #include "tcl.h"
    19     19   #include <stdlib.h>
    20     20   #include <string.h>
    21     21   
    22         -/*
    23         -** Interpret an SQLite error number
    24         -*/
    25         -static char *errorName(int rc){
    26         -  char *zName;
    27         -  switch( rc ){
    28         -    case SQLITE_OK:         zName = "SQLITE_OK";          break;
    29         -    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
    30         -    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
    31         -    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
    32         -    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
    33         -    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
    34         -    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
    35         -    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
    36         -    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
    37         -    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
    38         -    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
    39         -    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
    40         -    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
    41         -    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
    42         -    case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;
    43         -    default:                zName = "SQLITE_Unknown";     break;
    44         -  }
    45         -  return zName;
    46         -}
           22  +extern const char *sqlite3TestErrorName(int rc);
    47     23   
    48     24   /*
    49     25   ** A bogus sqlite3 connection structure for use in the btree
    50     26   ** tests.
    51     27   */
    52     28   static sqlite3 sDb;
    53     29   static int nRefSqlite3 = 0;
................................................................................
    85     61     if( zFilename==0 ) return TCL_ERROR;
    86     62     memcpy(zFilename, argv[1], n+1);
    87     63     zFilename[n+1] = 0;
    88     64     rc = sqlite3BtreeOpen(sDb.pVfs, zFilename, &sDb, &pBt, 0, 
    89     65        SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
    90     66     sqlite3_free(zFilename);
    91     67     if( rc!=SQLITE_OK ){
    92         -    Tcl_AppendResult(interp, errorName(rc), 0);
           68  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
    93     69       return TCL_ERROR;
    94     70     }
    95     71     sqlite3BtreeSetCacheSize(pBt, nCache);
    96     72     sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pBt);
    97     73     Tcl_AppendResult(interp, zBuf, 0);
    98     74     return TCL_OK;
    99     75   }
................................................................................
   115     91       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   116     92          " ID\"", 0);
   117     93       return TCL_ERROR;
   118     94     }
   119     95     pBt = sqlite3TestTextToPtr(argv[1]);
   120     96     rc = sqlite3BtreeClose(pBt);
   121     97     if( rc!=SQLITE_OK ){
   122         -    Tcl_AppendResult(interp, errorName(rc), 0);
           98  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   123     99       return TCL_ERROR;
   124    100     }
   125    101     nRefSqlite3--;
   126    102     if( nRefSqlite3==0 ){
   127    103       sqlite3_mutex_leave(sDb.mutex);
   128    104       sqlite3_mutex_free(sDb.mutex);
   129    105       sDb.mutex = 0;
................................................................................
   152    128       return TCL_ERROR;
   153    129     }
   154    130     pBt = sqlite3TestTextToPtr(argv[1]);
   155    131     sqlite3BtreeEnter(pBt);
   156    132     rc = sqlite3BtreeBeginTrans(pBt, 1);
   157    133     sqlite3BtreeLeave(pBt);
   158    134     if( rc!=SQLITE_OK ){
   159         -    Tcl_AppendResult(interp, errorName(rc), 0);
          135  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   160    136       return TCL_ERROR;
   161    137     }
   162    138     return TCL_OK;
   163    139   }
   164    140   
   165    141   /*
   166    142   ** Usage:   btree_pager_stats ID
................................................................................
   246    222   #endif
   247    223     if( rc==SQLITE_OK ){
   248    224       rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur);
   249    225     }
   250    226     sqlite3BtreeLeave(pBt);
   251    227     if( rc ){
   252    228       ckfree((char *)pCur);
   253         -    Tcl_AppendResult(interp, errorName(rc), 0);
          229  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   254    230       return TCL_ERROR;
   255    231     }
   256    232     sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur);
   257    233     Tcl_AppendResult(interp, zBuf, 0);
   258    234     return SQLITE_OK;
   259    235   }
   260    236   
................................................................................
   281    257     pCur = sqlite3TestTextToPtr(argv[1]);
   282    258     pBt = pCur->pBtree;
   283    259     sqlite3BtreeEnter(pBt);
   284    260     rc = sqlite3BtreeCloseCursor(pCur);
   285    261     sqlite3BtreeLeave(pBt);
   286    262     ckfree((char *)pCur);
   287    263     if( rc ){
   288         -    Tcl_AppendResult(interp, errorName(rc), 0);
          264  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   289    265       return TCL_ERROR;
   290    266     }
   291    267     return SQLITE_OK;
   292    268   }
   293    269   
   294    270   /*
   295    271   ** Usage:   btree_next ID
................................................................................
   315    291       return TCL_ERROR;
   316    292     }
   317    293     pCur = sqlite3TestTextToPtr(argv[1]);
   318    294     sqlite3BtreeEnter(pCur->pBtree);
   319    295     rc = sqlite3BtreeNext(pCur, &res);
   320    296     sqlite3BtreeLeave(pCur->pBtree);
   321    297     if( rc ){
   322         -    Tcl_AppendResult(interp, errorName(rc), 0);
          298  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   323    299       return TCL_ERROR;
   324    300     }
   325    301     sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
   326    302     Tcl_AppendResult(interp, zBuf, 0);
   327    303     return SQLITE_OK;
   328    304   }
   329    305   
................................................................................
   350    326       return TCL_ERROR;
   351    327     }
   352    328     pCur = sqlite3TestTextToPtr(argv[1]);
   353    329     sqlite3BtreeEnter(pCur->pBtree);
   354    330     rc = sqlite3BtreeFirst(pCur, &res);
   355    331     sqlite3BtreeLeave(pCur->pBtree);
   356    332     if( rc ){
   357         -    Tcl_AppendResult(interp, errorName(rc), 0);
          333  +    Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
   358    334       return TCL_ERROR;
   359    335     }
   360    336     sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res);
   361    337     Tcl_AppendResult(interp, zBuf, 0);
   362    338     return SQLITE_OK;
   363    339   }
   364    340   

Changes to src/test4.c.

    16     16   #if SQLITE_OS_UNIX && SQLITE_THREADSAFE
    17     17   #include <stdlib.h>
    18     18   #include <string.h>
    19     19   #include <pthread.h>
    20     20   #include <sched.h>
    21     21   #include <ctype.h>
    22     22   
           23  +extern const char *sqlite3TestErrorName(int rc);
           24  +
    23     25   /*
    24     26   ** Each thread is controlled by an instance of the following
    25     27   ** structure.
    26     28   */
    27     29   typedef struct Thread Thread;
    28     30   struct Thread {
    29     31     /* The first group of fields are writable by the master and read-only
................................................................................
   368    370     i = parse_thread_id(interp, argv[1]);
   369    371     if( i<0 ) return TCL_ERROR;
   370    372     if( !threadset[i].busy ){
   371    373       Tcl_AppendResult(interp, "no such thread", 0);
   372    374       return TCL_ERROR;
   373    375     }
   374    376     thread_wait(&threadset[i]);
   375         -  switch( threadset[i].rc ){
   376         -    case SQLITE_OK:         zName = "SQLITE_OK";          break;
   377         -    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
   378         -    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
   379         -    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
   380         -    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
   381         -    case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;
   382         -    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
   383         -    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
   384         -    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
   385         -    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
   386         -    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
   387         -    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
   388         -    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
   389         -    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
   390         -    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
   391         -    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
   392         -    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
   393         -    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
   394         -    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
   395         -    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
   396         -    case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
   397         -    case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
   398         -    case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
   399         -    case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
   400         -    case SQLITE_DONE:       zName = "SQLITE_DONE";        break;
   401         -    default:                zName = "SQLITE_Unknown";     break;
   402         -  }
          377  +  zName = sqlite3TestErrorName(threadset[i].rc);
   403    378     Tcl_AppendResult(interp, zName, 0);
   404    379     return TCL_OK;
   405    380   }
   406    381   
   407    382   /*
   408    383   ** Usage: thread_error  ID
   409    384   **

Changes to src/test7.c.

   372    372       Tcl_AppendResult(interp, "column number out of range", 0);
   373    373       return TCL_ERROR;
   374    374     }
   375    375     Tcl_AppendResult(interp, threadset[i].colv[n], 0);
   376    376     return TCL_OK;
   377    377   }
   378    378   
          379  +extern const char *sqlite3TestErrorName(int rc);
          380  +
   379    381   /*
   380    382   ** Usage: client_result  ID
   381    383   **
   382    384   ** Wait on the most recent operation to complete, then return the
   383    385   ** result code from that operation.
   384    386   */
   385    387   static int tcl_client_result(
................................................................................
   399    401     i = parse_client_id(interp, argv[1]);
   400    402     if( i<0 ) return TCL_ERROR;
   401    403     if( !threadset[i].busy ){
   402    404       Tcl_AppendResult(interp, "no such thread", 0);
   403    405       return TCL_ERROR;
   404    406     }
   405    407     client_wait(&threadset[i]);
   406         -  switch( threadset[i].rc ){
   407         -    case SQLITE_OK:         zName = "SQLITE_OK";          break;
   408         -    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
   409         -    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
   410         -    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
   411         -    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
   412         -    case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;
   413         -    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
   414         -    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
   415         -    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
   416         -    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
   417         -    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
   418         -    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
   419         -    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
   420         -    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
   421         -    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
   422         -    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
   423         -    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
   424         -    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
   425         -    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
   426         -    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
   427         -    case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
   428         -    case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
   429         -    case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
   430         -    case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
   431         -    case SQLITE_DONE:       zName = "SQLITE_DONE";        break;
   432         -    default:                zName = "SQLITE_Unknown";     break;
   433         -  }
          408  +  zName = sqlite3TestErrorName(threadset[i].rc);
   434    409     Tcl_AppendResult(interp, zName, 0);
   435    410     return TCL_OK;
   436    411   }
   437    412   
   438    413   /*
   439    414   ** Usage: client_error  ID
   440    415   **

Changes to src/test_autoext.c.

    11     11   *************************************************************************
    12     12   ** Test extension for testing the sqlite3_auto_extension() function.
    13     13   */
    14     14   #include "tcl.h"
    15     15   #include "sqlite3ext.h"
    16     16   
    17     17   #ifndef SQLITE_OMIT_LOAD_EXTENSION
    18         -static SQLITE_EXTENSION_INIT1
           18  +SQLITE_EXTENSION_INIT1
    19     19   
    20     20   /*
    21     21   ** The sqr() SQL function returns the square of its input value.
    22     22   */
    23     23   static void sqrFunc(
    24     24     sqlite3_context *context,
    25     25     int argc,

Changes to src/test_config.c.

    53     53   
    54     54   #ifdef SQLITE_CASE_SENSITIVE_LIKE
    55     55     Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY);
    56     56   #else
    57     57     Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY);
    58     58   #endif
    59     59   
    60         -#ifdef SQLITE_CURDIR
           60  +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
    61     61     Tcl_SetVar2(interp, "sqlite_options", "curdir", "1", TCL_GLOBAL_ONLY);
    62     62   #else
    63     63     Tcl_SetVar2(interp, "sqlite_options", "curdir", "0", TCL_GLOBAL_ONLY);
    64     64   #endif
    65     65   
    66     66   #ifdef SQLITE_DEBUG
    67     67     Tcl_SetVar2(interp, "sqlite_options", "debug", "1", TCL_GLOBAL_ONLY);
................................................................................
    82     82   #endif
    83     83   
    84     84   #ifdef SQLITE_DISABLE_LFS
    85     85     Tcl_SetVar2(interp, "sqlite_options", "lfs", "0", TCL_GLOBAL_ONLY);
    86     86   #else
    87     87     Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY);
    88     88   #endif
           89  +
           90  +#if SQLITE_MAX_MMAP_SIZE>0
           91  +  Tcl_SetVar2(interp, "sqlite_options", "mmap", "1", TCL_GLOBAL_ONLY);
           92  +#else
           93  +  Tcl_SetVar2(interp, "sqlite_options", "mmap", "0", TCL_GLOBAL_ONLY);
           94  +#endif
    89     95   
    90     96   #if 1 /* def SQLITE_MEMDEBUG */
    91     97     Tcl_SetVar2(interp, "sqlite_options", "memdebug", "1", TCL_GLOBAL_ONLY);
    92     98   #else
    93     99     Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY);
    94    100   #endif
    95    101   

Changes to src/test_sqllog.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** OVERVIEW
    14     14   **
    15     15   **   This file contains experimental code used to record data from live
    16         -**   SQLite applications that may be useful for offline analysis. Specifically:
           16  +**   SQLite applications that may be useful for offline analysis. 
           17  +**   Specifically, this module can be used to capture the following
           18  +**   information:
    17     19   **
    18     20   **     1) The initial contents of all database files opened by the 
    19     21   **        application, and
    20     22   **
    21     23   **     2) All SQL statements executed by the application.
    22     24   **
           25  +**   The captured information can then be used to run (for example)
           26  +**   performance analysis looking for slow queries or to look for
           27  +**   optimization opportunities in either the application or in SQLite
           28  +**   itself.
           29  +**
    23     30   ** USAGE
    24     31   **
    25     32   **   To use this module, SQLite must be compiled with the SQLITE_ENABLE_SQLLOG
    26         -**   pre-processor symbol defined and this file linked into the application
    27         -**   somehow.
           33  +**   pre-processor symbol defined and this file linked into the application.
           34  +**   One way to link this file into the application is to append the content
           35  +**   of this file onto the end of the "sqlite3.c" amalgamation and then 
           36  +**   recompile the application as normal except with the addition  of the
           37  +**   -DSQLITE_ENABLE_SQLLOG option.
    28     38   **
    29     39   **   At runtime, logging is enabled by setting environment variable
    30     40   **   SQLITE_SQLLOG_DIR to the name of a directory in which to store logged 
    31         -**   data. The directory must already exist.
           41  +**   data. The logging directory must already exist.
    32     42   **
    33     43   **   Usually, if the application opens the same database file more than once
    34     44   **   (either by attaching it or by using more than one database handle), only
    35     45   **   a single copy is made. This behavior may be overridden (so that a 
    36     46   **   separate copy is taken each time the database file is opened or attached)
    37     47   **   by setting the environment variable SQLITE_SQLLOG_REUSE_FILES to 0.
    38     48   **
................................................................................
    53     63   **
    54     64   **   This module attempts to make a best effort to continue logging if an
    55     65   **   IO or other error is encountered. For example, if a log file cannot 
    56     66   **   be opened logs are not collected for that connection, but other
    57     67   **   logging proceeds as expected. Errors are logged by calling sqlite3_log().
    58     68   */
    59     69   
           70  +#ifndef _SQLITE3_H_
    60     71   #include "sqlite3.h"
    61         -#include "stdio.h"
    62         -#include "stdlib.h"
    63         -#include "string.h"
    64         -#include "assert.h"
           72  +#endif
           73  +#include <stdio.h>
           74  +#include <stdlib.h>
           75  +#include <string.h>
           76  +#include <assert.h>
    65     77   
    66         -#include "sys/types.h"
    67         -#include "unistd.h"
           78  +#include <sys/types.h>
           79  +#include <unistd.h>
    68     80   static int getProcessId(void){
    69     81   #if SQLITE_OS_WIN
    70     82     return (int)_getpid();
    71     83   #else
    72     84     return (int)getpid();
    73     85   #endif
    74     86   }
    75     87   
    76         -
           88  +/* Names of environment variables to be used */
    77     89   #define ENVIRONMENT_VARIABLE1_NAME "SQLITE_SQLLOG_DIR"
    78     90   #define ENVIRONMENT_VARIABLE2_NAME "SQLITE_SQLLOG_REUSE_FILES"
    79     91   
    80     92   /* Assume that all database and database file names are shorted than this. */
    81     93   #define SQLLOG_NAMESZ 512
    82     94   
    83     95   /* Maximum number of simultaneous database connections the process may
    84     96   ** open (if any more are opened an error is logged using sqlite3_log()
    85     97   ** and processing is halted).
    86     98   */
    87     99   #define MAX_CONNECTIONS 256
    88    100   
          101  +/* There is one instance of this object for each SQLite database connection
          102  +** that is being logged.
          103  +*/
    89    104   struct SLConn {
    90    105     int isErr;                      /* True if an error has occurred */
    91    106     sqlite3 *db;                    /* Connection handle */
    92    107     int iLog;                       /* First integer value used in file names */
    93    108     FILE *fd;                       /* File descriptor for log file */
    94    109   };
    95    110   
    96         -struct SLGlobal {
          111  +/* This object is a singleton that keeps track of all data loggers.
          112  +*/
          113  +static struct SLGlobal {
    97    114     /* Protected by MUTEX_STATIC_MASTER */
    98    115     sqlite3_mutex *mutex;           /* Recursive mutex */
    99    116     int nConn;                      /* Size of aConn[] array */
   100    117   
   101    118     /* Protected by SLGlobal.mutex */
   102    119     int bReuse;                     /* True to avoid extra copies of db files */
   103    120     char zPrefix[SQLLOG_NAMESZ];    /* Prefix for all created files */
................................................................................
   384    401       /* This is an ATTACH statement. Copy the database. */
   385    402       sqllogCopydb(p, 0, 1);
   386    403     }
   387    404   }
   388    405   
   389    406   /*
   390    407   ** The SQLITE_CONFIG_SQLLOG callback registered by sqlite3_init_sqllog().
          408  +**
          409  +** The eType parameter has the following values:
          410  +**
          411  +**    0:  Opening a new database connection.  zSql is the name of the
          412  +**        file being opened.  db is a pointer to the newly created database
          413  +**        connection.
          414  +**
          415  +**    1:  An SQL statement has run to completion.  zSql is the text of the
          416  +**        SQL statement with all parameters expanded to their actual values.
          417  +**
          418  +**    2:  Closing a database connection.  zSql is NULL.  The db pointer to
          419  +**        the database connection being closed has already been shut down
          420  +**        and cannot be used for any further SQL.
          421  +**
          422  +** The pCtx parameter is a copy of the pointer that was originally passed
          423  +** into the sqlite3_config(SQLITE_CONFIG_SQLLOG) statement.  In this
          424  +** particular implementation, pCtx is always a pointer to the 
          425  +** sqllogglobal global variable define above.
   391    426   */
   392    427   static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){
   393    428     struct SLConn *p = 0;
   394    429     sqlite3_mutex *master = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
   395    430   
   396    431     assert( eType==0 || eType==1 || eType==2 );
   397    432     assert( (eType==2)==(zSql==0) );

Changes to src/test_syscall.c.

    19     19   **   test_syscall install LIST
    20     20   **     Install wrapper functions for all system calls in argument LIST.
    21     21   **     LIST must be a list consisting of zero or more of the following
    22     22   **     literal values:
    23     23   **
    24     24   **         open        close      access   getcwd   stat      fstat    
    25     25   **         ftruncate   fcntl      read     pread    pread64   write
    26         -**         pwrite      pwrite64   fchmod   fallocate
           26  +**         pwrite      pwrite64   fchmod   fallocate mmap
    27     27   **
    28     28   **   test_syscall uninstall
    29     29   **     Uninstall all wrapper functions.
    30     30   **
    31     31   **   test_syscall fault ?COUNT PERSIST?
    32     32   **     If [test_syscall fault] is invoked without the two arguments, fault
    33     33   **     injection is disabled. Otherwise, fault injection is configured to
................................................................................
    77     77   
    78     78   #include "sqliteInt.h"
    79     79   #if SQLITE_OS_UNIX
    80     80   
    81     81   /* From test1.c */
    82     82   extern const char *sqlite3TestErrorName(int);
    83     83   
           84  +#include <sys/mman.h>
    84     85   #include <sys/types.h>
    85     86   #include <errno.h>
    86     87   
    87     88   static struct TestSyscallGlobal {
    88     89     int bPersist;                   /* 1 for persistent errors, 0 for transient */
    89     90     int nCount;                     /* Fail after this many more calls */
    90     91     int nFail;                      /* Number of failures that have occurred */
................................................................................
   102    103   static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off);
   103    104   static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off);
   104    105   static int ts_write(int fd, const void *aBuf, size_t nBuf);
   105    106   static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off);
   106    107   static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off);
   107    108   static int ts_fchmod(int fd, mode_t mode);
   108    109   static int ts_fallocate(int fd, off_t off, off_t len);
   109         -
          110  +static void *ts_mmap(void *, size_t, int, int, int, off_t);
          111  +static void *ts_mremap(void*, size_t, size_t, int, ...);
   110    112   
   111    113   struct TestSyscallArray {
   112    114     const char *zName;
   113    115     sqlite3_syscall_ptr xTest;
   114    116     sqlite3_syscall_ptr xOrig;
   115    117     int default_errno;              /* Default value for errno following errors */
   116    118     int custom_errno;               /* Current value for errno if error */
................................................................................
   127    129     /*  9 */ { "pread",     (sqlite3_syscall_ptr)ts_pread,     0, 0, 0 },
   128    130     /* 10 */ { "pread64",   (sqlite3_syscall_ptr)ts_pread64,   0, 0, 0 },
   129    131     /* 11 */ { "write",     (sqlite3_syscall_ptr)ts_write,     0, 0, 0 },
   130    132     /* 12 */ { "pwrite",    (sqlite3_syscall_ptr)ts_pwrite,    0, 0, 0 },
   131    133     /* 13 */ { "pwrite64",  (sqlite3_syscall_ptr)ts_pwrite64,  0, 0, 0 },
   132    134     /* 14 */ { "fchmod",    (sqlite3_syscall_ptr)ts_fchmod,    0, 0, 0 },
   133    135     /* 15 */ { "fallocate", (sqlite3_syscall_ptr)ts_fallocate, 0, 0, 0 },
          136  +  /* 16 */ { "mmap",      (sqlite3_syscall_ptr)ts_mmap,      0, 0, 0 },
          137  +  /* 17 */ { "mremap",    (sqlite3_syscall_ptr)ts_mremap,    0, 0, 0 },
   134    138              { 0, 0, 0, 0, 0 }
   135    139   };
   136    140   
   137    141   #define orig_open      ((int(*)(const char *, int, int))aSyscall[0].xOrig)
   138    142   #define orig_close     ((int(*)(int))aSyscall[1].xOrig)
   139    143   #define orig_access    ((int(*)(const char*,int))aSyscall[2].xOrig)
   140    144   #define orig_getcwd    ((char*(*)(char*,size_t))aSyscall[3].xOrig)
................................................................................
   148    152   #define orig_write     ((ssize_t(*)(int,const void*,size_t))aSyscall[11].xOrig)
   149    153   #define orig_pwrite    ((ssize_t(*)(int,const void*,size_t,off_t))\
   150    154                          aSyscall[12].xOrig)
   151    155   #define orig_pwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
   152    156                          aSyscall[13].xOrig)
   153    157   #define orig_fchmod    ((int(*)(int,mode_t))aSyscall[14].xOrig)
   154    158   #define orig_fallocate ((int(*)(int,off_t,off_t))aSyscall[15].xOrig)
          159  +#define orig_mmap      ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[16].xOrig)
          160  +#define orig_mremap    ((void*(*)(void*,size_t,size_t,int,...))aSyscall[17].xOrig)
   155    161   
   156    162   /*
   157    163   ** This function is called exactly once from within each invocation of a
   158    164   ** system call wrapper in this file. It returns 1 if the function should
   159    165   ** fail, or 0 if it should succeed.
   160    166   */
   161    167   static int tsIsFail(void){
................................................................................
   372    378   */
   373    379   static int ts_fallocate(int fd, off_t off, off_t len){
   374    380     if( tsIsFail() ){
   375    381       return tsErrno("fallocate");
   376    382     }
   377    383     return orig_fallocate(fd, off, len);
   378    384   }
          385  +
          386  +static void *ts_mmap(
          387  +  void *pAddr, 
          388  +  size_t nByte, 
          389  +  int prot, 
          390  +  int flags, 
          391  +  int fd, 
          392  +  off_t iOff
          393  +){
          394  +  if( tsIsFailErrno("mmap") ){
          395  +    return MAP_FAILED;
          396  +  }
          397  +  return orig_mmap(pAddr, nByte, prot, flags, fd, iOff);
          398  +}
          399  +
          400  +static void *ts_mremap(void *a, size_t b, size_t c, int d, ...){
          401  +  va_list ap;
          402  +  void *pArg;
          403  +  if( tsIsFailErrno("mremap") ){
          404  +    return MAP_FAILED;
          405  +  }
          406  +  va_start(ap, d);
          407  +  pArg = va_arg(ap, void *);
          408  +  return orig_mremap(a, b, c, d, pArg);
          409  +}
   379    410   
   380    411   static int test_syscall_install(
   381    412     void * clientData,
   382    413     Tcl_Interp *interp,
   383    414     int objc,
   384    415     Tcl_Obj *CONST objv[]
   385    416   ){

Changes to src/test_vfs.c.

   121    121   #define TESTVFS_DELETE_MASK       0x00000400
   122    122   #define TESTVFS_CLOSE_MASK        0x00000800
   123    123   #define TESTVFS_WRITE_MASK        0x00001000
   124    124   #define TESTVFS_TRUNCATE_MASK     0x00002000
   125    125   #define TESTVFS_ACCESS_MASK       0x00004000
   126    126   #define TESTVFS_FULLPATHNAME_MASK 0x00008000
   127    127   #define TESTVFS_READ_MASK         0x00010000
          128  +#define TESTVFS_UNLOCK_MASK       0x00020000
   128    129   
   129         -#define TESTVFS_ALL_MASK          0x0001FFFF
          130  +#define TESTVFS_ALL_MASK          0x0003FFFF
   130    131   
   131    132   
   132    133   #define TESTVFS_MAX_PAGES 1024
   133    134   
   134    135   /*
   135    136   ** A shared-memory buffer. There is one of these objects for each shared
   136    137   ** memory region opened by clients. If two clients open the same file,
................................................................................
   463    464     return sqlite3OsLock(p->pReal, eLock);
   464    465   }
   465    466   
   466    467   /*
   467    468   ** Unlock an tvfs-file.
   468    469   */
   469    470   static int tvfsUnlock(sqlite3_file *pFile, int eLock){
   470         -  TestvfsFd *p = tvfsGetFd(pFile);
   471         -  return sqlite3OsUnlock(p->pReal, eLock);
          471  +  TestvfsFd *pFd = tvfsGetFd(pFile);
          472  +  Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
          473  +  if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
          474  +    return SQLITE_IOERR_UNLOCK;
          475  +  }
          476  +  return sqlite3OsUnlock(pFd->pReal, eLock);
   472    477   }
   473    478   
   474    479   /*
   475    480   ** Check if another file-handle holds a RESERVED lock on an tvfs-file.
   476    481   */
   477    482   static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
   478    483     TestvfsFd *p = tvfsGetFd(pFile);
................................................................................
  1097   1102           { "xWrite",        TESTVFS_WRITE_MASK },
  1098   1103           { "xRead",         TESTVFS_READ_MASK },
  1099   1104           { "xTruncate",     TESTVFS_TRUNCATE_MASK },
  1100   1105           { "xOpen",         TESTVFS_OPEN_MASK },
  1101   1106           { "xClose",        TESTVFS_CLOSE_MASK },
  1102   1107           { "xAccess",       TESTVFS_ACCESS_MASK },
  1103   1108           { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
         1109  +        { "xUnlock",       TESTVFS_UNLOCK_MASK },
  1104   1110         };
  1105   1111         Tcl_Obj **apElem = 0;
  1106   1112         int nElem = 0;
  1107   1113         int i;
  1108   1114         int mask = 0;
  1109   1115         if( objc!=3 ){
  1110   1116           Tcl_WrongNumArgs(interp, 2, objv, "LIST");

Changes to src/vdbe.c.

  3521   3521         /* The next line of code computes as follows, only faster:
  3522   3522         **   if( oc==OP_SeekGt || oc==OP_SeekLe ){
  3523   3523         **     r.flags = UNPACKED_INCRKEY;
  3524   3524         **   }else{
  3525   3525         **     r.flags = 0;
  3526   3526         **   }
  3527   3527         */
  3528         -      r.flags = (u16)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)));
         3528  +      r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt)));
  3529   3529         assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY );
  3530   3530         assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY );
  3531   3531         assert( oc!=OP_SeekGe || r.flags==0 );
  3532   3532         assert( oc!=OP_SeekLt || r.flags==0 );
  3533   3533   
  3534   3534         r.aMem = &aMem[pOp->p3];
  3535   3535   #ifdef SQLITE_DEBUG

Changes to src/vdbeInt.h.

    14     14   ** source code file "vdbe.c".  When that file became too big (over
    15     15   ** 6000 lines long) it was split up into several smaller files and
    16     16   ** this header information was factored out.
    17     17   */
    18     18   #ifndef _VDBEINT_H_
    19     19   #define _VDBEINT_H_
    20     20   
           21  +/*
           22  +** The maximum number of times that a statement will try to reparse
           23  +** itself before giving up and returning SQLITE_SCHEMA.
           24  +*/
           25  +#ifndef SQLITE_MAX_SCHEMA_RETRY
           26  +# define SQLITE_MAX_SCHEMA_RETRY 50
           27  +#endif
           28  +
    21     29   /*
    22     30   ** SQL is translated into a sequence of instructions to be
    23     31   ** executed by a virtual machine.  Each instruction is an instance
    24     32   ** of the following structure.
    25     33   */
    26     34   typedef struct VdbeOp Op;
    27     35   

Changes to src/vdbeapi.c.

   449    449       ** caller. Set the error code in the database handle to the same value.
   450    450       */ 
   451    451       rc = sqlite3VdbeTransferError(p);
   452    452     }
   453    453     return (rc&db->errMask);
   454    454   }
   455    455   
   456         -/*
   457         -** The maximum number of times that a statement will try to reparse
   458         -** itself before giving up and returning SQLITE_SCHEMA.
   459         -*/
   460         -#ifndef SQLITE_MAX_SCHEMA_RETRY
   461         -# define SQLITE_MAX_SCHEMA_RETRY 5
   462         -#endif
   463         -
   464    456   /*
   465    457   ** This is the top-level implementation of sqlite3_step().  Call
   466    458   ** sqlite3Step() to do most of the work.  If a schema error occurs,
   467    459   ** call sqlite3Reprepare() and try again.
   468    460   */
   469    461   int sqlite3_step(sqlite3_stmt *pStmt){
   470    462     int rc = SQLITE_OK;      /* Result from sqlite3Step() */

Changes to src/vdbeblob.c.

   313    313       pBlob->db = db;
   314    314       sqlite3BtreeLeaveAll(db);
   315    315       if( db->mallocFailed ){
   316    316         goto blob_open_out;
   317    317       }
   318    318       sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
   319    319       rc = blobSeekToRow(pBlob, iRow, &zErr);
   320         -  } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA );
          320  +  } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
   321    321   
   322    322   blob_open_out:
   323    323     if( rc==SQLITE_OK && db->mallocFailed==0 ){
   324    324       *ppBlob = (sqlite3_blob *)pBlob;
   325    325     }else{
   326    326       if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
   327    327       sqlite3DbFree(db, pBlob);

Changes to src/vdbetrace.c.

    48     48   /*
    49     49   ** This function returns a pointer to a nul-terminated string in memory
    50     50   ** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
    51     51   ** string contains a copy of zRawSql but with host parameters expanded to 
    52     52   ** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1, 
    53     53   ** then the returned string holds a copy of zRawSql with "-- " prepended
    54     54   ** to each line of text.
           55  +**
           56  +** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then
           57  +** then long strings and blobs are truncated to that many bytes.  This
           58  +** can be used to prevent unreasonably large trace strings when dealing
           59  +** with large (multi-megabyte) strings and blobs.
    55     60   **
    56     61   ** The calling function is responsible for making sure the memory returned
    57     62   ** is eventually freed.
    58     63   **
    59     64   ** ALGORITHM:  Scan the input string looking for host parameters in any of
    60     65   ** these forms:  ?, ?N, $A, @A, :A.  Take care to avoid text within
    61     66   ** string literals, quoted identifier names, and comments.  For text forms,
................................................................................
   119    124         if( pVar->flags & MEM_Null ){
   120    125           sqlite3StrAccumAppend(&out, "NULL", 4);
   121    126         }else if( pVar->flags & MEM_Int ){
   122    127           sqlite3XPrintf(&out, "%lld", pVar->u.i);
   123    128         }else if( pVar->flags & MEM_Real ){
   124    129           sqlite3XPrintf(&out, "%!.15g", pVar->r);
   125    130         }else if( pVar->flags & MEM_Str ){
          131  +        int nOut;  /* Number of bytes of the string text to include in output */
   126    132   #ifndef SQLITE_OMIT_UTF16
   127    133           u8 enc = ENC(db);
          134  +        Mem utf8;
   128    135           if( enc!=SQLITE_UTF8 ){
   129         -          Mem utf8;
   130    136             memset(&utf8, 0, sizeof(utf8));
   131    137             utf8.db = db;
   132    138             sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
   133    139             sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
   134         -          sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
   135         -          sqlite3VdbeMemRelease(&utf8);
   136         -        }else
          140  +          pVar = &utf8;
          141  +        }
   137    142   #endif
   138         -        {
   139         -          sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
          143  +        nOut = pVar->n;
          144  +#ifdef SQLITE_TRACE_SIZE_LIMIT
          145  +        if( n>SQLITE_TRACE_SIZE_LIMIT ){
          146  +          nOut = SQLITE_TRACE_SIZE_LIMIT;
          147  +          while( nOut<pVar->n && (pVar->z[n]&0xc0)==0x80 ){ n++; }
   140    148           }
          149  +#endif    
          150  +        sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
          151  +#ifdef SQLITE_TRACE_SIZE_LIMIT
          152  +        if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n);
          153  +#endif
          154  +#ifndef SQLITE_OMIT_UTF16
          155  +        if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
          156  +#endif
   141    157         }else if( pVar->flags & MEM_Zero ){
   142    158           sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
   143    159         }else{
          160  +        int nOut;  /* Number of bytes of the blob to include in output */
   144    161           assert( pVar->flags & MEM_Blob );
   145    162           sqlite3StrAccumAppend(&out, "x'", 2);
   146         -        for(i=0; i<pVar->n; i++){
          163  +        nOut = pVar->n;
          164  +#ifdef SQLITE_TRACE_SIZE_LIMIT
          165  +        if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
          166  +#endif
          167  +        for(i=0; i<nOut; i++){
   147    168             sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
   148    169           }
   149    170           sqlite3StrAccumAppend(&out, "'", 1);
          171  +#ifdef SQLITE_TRACE_SIZE_LIMIT
          172  +        if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n);
          173  +#endif
   150    174         }
   151    175       }
   152    176     }
   153    177     return sqlite3StrAccumFinish(&out);
   154    178   }
   155    179   
   156    180   #endif /* #ifndef SQLITE_OMIT_TRACE */

Changes to src/wal.c.

  1203   1203   
  1204   1204       /* If more than one frame was recovered from the log file, report an
  1205   1205       ** event via sqlite3_log(). This is to help with identifying performance
  1206   1206       ** problems caused by applications routinely shutting down without
  1207   1207       ** checkpointing the log file.
  1208   1208       */
  1209   1209       if( pWal->hdr.nPage ){
  1210         -      sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s",
  1211         -          pWal->hdr.nPage, pWal->zWalName
         1210  +      sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
         1211  +          "recovered %d frames from WAL file %s",
         1212  +          pWal->hdr.mxFrame, pWal->zWalName
  1212   1213         );
  1213   1214       }
  1214   1215     }
  1215   1216   
  1216   1217   recovery_error:
  1217   1218     WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
  1218   1219     walUnlockExclusive(pWal, iLock, nLock);
................................................................................
  1718   1719       u32 nBackfill = pInfo->nBackfill;
  1719   1720   
  1720   1721       /* Sync the WAL to disk */
  1721   1722       if( sync_flags ){
  1722   1723         rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
  1723   1724       }
  1724   1725   
  1725         -    /* If the database file may grow as a result of this checkpoint, hint
  1726         -    ** about the eventual size of the db file to the VFS layer. 
         1726  +    /* If the database may grow as a result of this checkpoint, hint
         1727  +    ** about the eventual size of the db file to the VFS layer.
  1727   1728       */
  1728   1729       if( rc==SQLITE_OK ){
  1729   1730         i64 nReq = ((i64)mxPage * szPage);
  1730   1731         rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
  1731   1732         if( rc==SQLITE_OK && nSize<nReq ){
  1732   1733           sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
  1733   1734         }
  1734   1735       }
         1736  +
  1735   1737   
  1736   1738       /* Iterate through the contents of the WAL, copying data to the db file. */
  1737   1739       while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
  1738   1740         i64 iOffset;
  1739   1741         assert( walFramePgno(pWal, iFrame)==iDbpage );
  1740   1742         if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
  1741   1743         iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
................................................................................
  2283   2285     if( pWal->readLock>=0 ){
  2284   2286       walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
  2285   2287       pWal->readLock = -1;
  2286   2288     }
  2287   2289   }
  2288   2290   
  2289   2291   /*
  2290         -** Read a page from the WAL, if it is present in the WAL and if the 
  2291         -** current read transaction is configured to use the WAL.  
         2292  +** Search the wal file for page pgno. If found, set *piRead to the frame that
         2293  +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead
         2294  +** to zero.
  2292   2295   **
  2293         -** The *pInWal is set to 1 if the requested page is in the WAL and
  2294         -** has been loaded.  Or *pInWal is set to 0 if the page was not in 
  2295         -** the WAL and needs to be read out of the database.
         2296  +** Return SQLITE_OK if successful, or an error code if an error occurs. If an
         2297  +** error does occur, the final value of *piRead is undefined.
  2296   2298   */
  2297         -int sqlite3WalRead(
         2299  +int sqlite3WalFindFrame(
  2298   2300     Wal *pWal,                      /* WAL handle */
  2299   2301     Pgno pgno,                      /* Database page number to read data for */
  2300         -  int *pInWal,                    /* OUT: True if data is read from WAL */
  2301         -  int nOut,                       /* Size of buffer pOut in bytes */
  2302         -  u8 *pOut                        /* Buffer to write page data to */
         2302  +  u32 *piRead                     /* OUT: Frame number (or zero) */
  2303   2303   ){
  2304   2304     u32 iRead = 0;                  /* If !=0, WAL frame to return data from */
  2305   2305     u32 iLast = pWal->hdr.mxFrame;  /* Last page in WAL for this reader */
  2306   2306     int iHash;                      /* Used to loop through N hash tables */
  2307   2307   
  2308   2308     /* This routine is only be called from within a read transaction. */
  2309   2309     assert( pWal->readLock>=0 || pWal->lockError );
................................................................................
  2311   2311     /* If the "last page" field of the wal-index header snapshot is 0, then
  2312   2312     ** no data will be read from the wal under any circumstances. Return early
  2313   2313     ** in this case as an optimization.  Likewise, if pWal->readLock==0, 
  2314   2314     ** then the WAL is ignored by the reader so return early, as if the 
  2315   2315     ** WAL were empty.
  2316   2316     */
  2317   2317     if( iLast==0 || pWal->readLock==0 ){
  2318         -    *pInWal = 0;
         2318  +    *piRead = 0;
  2319   2319       return SQLITE_OK;
  2320   2320     }
  2321   2321   
  2322   2322     /* Search the hash table or tables for an entry matching page number
  2323   2323     ** pgno. Each iteration of the following for() loop searches one
  2324   2324     ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames).
  2325   2325     **
................................................................................
  2382   2382           break;
  2383   2383         }
  2384   2384       }
  2385   2385       assert( iRead==iRead2 );
  2386   2386     }
  2387   2387   #endif
  2388   2388   
  2389         -  /* If iRead is non-zero, then it is the log frame number that contains the
  2390         -  ** required page. Read and return data from the log file.
  2391         -  */
  2392         -  if( iRead ){
  2393         -    int sz;
  2394         -    i64 iOffset;
  2395         -    sz = pWal->hdr.szPage;
  2396         -    sz = (sz&0xfe00) + ((sz&0x0001)<<16);
  2397         -    testcase( sz<=32768 );
  2398         -    testcase( sz>=65536 );
  2399         -    iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
  2400         -    *pInWal = 1;
  2401         -    /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
  2402         -    return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
  2403         -  }
  2404         -
  2405         -  *pInWal = 0;
         2389  +  *piRead = iRead;
  2406   2390     return SQLITE_OK;
  2407   2391   }
  2408   2392   
         2393  +/*
         2394  +** Read the contents of frame iRead from the wal file into buffer pOut
         2395  +** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
         2396  +** error code otherwise.
         2397  +*/
         2398  +int sqlite3WalReadFrame(
         2399  +  Wal *pWal,                      /* WAL handle */
         2400  +  u32 iRead,                      /* Frame to read */
         2401  +  int nOut,                       /* Size of buffer pOut in bytes */
         2402  +  u8 *pOut                        /* Buffer to write page data to */
         2403  +){
         2404  +  int sz;
         2405  +  i64 iOffset;
         2406  +  sz = pWal->hdr.szPage;
         2407  +  sz = (sz&0xfe00) + ((sz&0x0001)<<16);
         2408  +  testcase( sz<=32768 );
         2409  +  testcase( sz>=65536 );
         2410  +  iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
         2411  +  /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
         2412  +  return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
         2413  +}
  2409   2414   
  2410   2415   /* 
  2411   2416   ** Return the size of the database in pages (or zero, if unknown).
  2412   2417   */
  2413   2418   Pgno sqlite3WalDbsize(Wal *pWal){
  2414   2419     if( pWal && ALWAYS(pWal->readLock>=0) ){
  2415   2420       return pWal->hdr.nPage;
................................................................................
  2948   2953         rc = SQLITE_OK;
  2949   2954       }
  2950   2955     }
  2951   2956   
  2952   2957     /* Read the wal-index header. */
  2953   2958     if( rc==SQLITE_OK ){
  2954   2959       rc = walIndexReadHdr(pWal, &isChanged);
         2960  +    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
         2961  +      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
         2962  +    }
  2955   2963     }
  2956   2964   
  2957   2965     /* Copy data from the log to the database file. */
  2958   2966     if( rc==SQLITE_OK ){
  2959   2967       if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
  2960   2968         rc = SQLITE_CORRUPT_BKPT;
  2961   2969       }else{

Changes to src/wal.h.

    27     27   
    28     28   #ifdef SQLITE_OMIT_WAL
    29     29   # define sqlite3WalOpen(x,y,z)                   0
    30     30   # define sqlite3WalLimit(x,y)
    31     31   # define sqlite3WalClose(w,x,y,z)                0
    32     32   # define sqlite3WalBeginReadTransaction(y,z)     0
    33     33   # define sqlite3WalEndReadTransaction(z)
    34         -# define sqlite3WalRead(v,w,x,y,z)               0
    35     34   # define sqlite3WalDbsize(y)                     0
    36     35   # define sqlite3WalBeginWriteTransaction(y)      0
    37     36   # define sqlite3WalEndWriteTransaction(x)        0
    38     37   # define sqlite3WalUndo(x,y,z)                   0
    39     38   # define sqlite3WalSavepoint(y,z)
    40     39   # define sqlite3WalSavepointUndo(y,z)            0
    41     40   # define sqlite3WalFrames(u,v,w,x,y,z)           0
................................................................................
    67     66   ** write to or checkpoint the WAL.  sqlite3WalCloseSnapshot() closes the
    68     67   ** transaction and releases the lock.
    69     68   */
    70     69   int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
    71     70   void sqlite3WalEndReadTransaction(Wal *pWal);
    72     71   
    73     72   /* Read a page from the write-ahead log, if it is present. */
    74         -int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
           73  +int sqlite3WalFindFrame(Wal *, Pgno, u32 *);
           74  +int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
    75     75   
    76     76   /* If the WAL is not empty, return the size of the database. */
    77     77   Pgno sqlite3WalDbsize(Wal *pWal);
    78     78   
    79     79   /* Obtain or release the WRITER lock. */
    80     80   int sqlite3WalBeginWriteTransaction(Wal *pWal);
    81     81   int sqlite3WalEndWriteTransaction(Wal *pWal);

Changes to src/where.c.

  2271   2271     WhereClause *pWC = p->pWC;      /* The WHERE clause */
  2272   2272     struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
  2273   2273     Table *pTab = pSrc->pTab;
  2274   2274     sqlite3_index_info *pIdxInfo;
  2275   2275     struct sqlite3_index_constraint *pIdxCons;
  2276   2276     struct sqlite3_index_constraint_usage *pUsage;
  2277   2277     WhereTerm *pTerm;
  2278         -  int i, j, k;
         2278  +  int i, j;
  2279   2279     int nOrderBy;
  2280         -  int sortOrder;                  /* Sort order for IN clauses */
  2281   2280     int bAllowIN;                   /* Allow IN optimizations */
  2282   2281     double rCost;
  2283   2282   
  2284   2283     /* Make sure wsFlags is initialized to some sane value. Otherwise, if the 
  2285   2284     ** malloc in allocateIndexInfo() fails and this function returns leaving
  2286   2285     ** wsFlags in an uninitialized state, the caller may behave unpredictably.
  2287   2286     */
................................................................................
  2372   2371         pIdxInfo->nOrderBy = 0;
  2373   2372       }
  2374   2373     
  2375   2374       if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
  2376   2375         return;
  2377   2376       }
  2378   2377     
  2379         -    sortOrder = SQLITE_SO_ASC;
  2380   2378       pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
  2381   2379       for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
  2382   2380         if( pUsage[i].argvIndex>0 ){
  2383   2381           j = pIdxCons->iTermOffset;
  2384   2382           pTerm = &pWC->a[j];
  2385   2383           p->cost.used |= pTerm->prereqRight;
  2386   2384           if( (pTerm->eOperator & WO_IN)!=0 ){
................................................................................
  2387   2385             if( pUsage[i].omit==0 ){
  2388   2386               /* Do not attempt to use an IN constraint if the virtual table
  2389   2387               ** says that the equivalent EQ constraint cannot be safely omitted.
  2390   2388               ** If we do attempt to use such a constraint, some rows might be
  2391   2389               ** repeated in the output. */
  2392   2390               break;
  2393   2391             }
  2394         -          for(k=0; k<pIdxInfo->nOrderBy; k++){
  2395         -            if( pIdxInfo->aOrderBy[k].iColumn==pIdxCons->iColumn ){
  2396         -              sortOrder = pIdxInfo->aOrderBy[k].desc;
  2397         -              break;
  2398         -            }
  2399         -          }
         2392  +          /* A virtual table that is constrained by an IN clause may not
         2393  +          ** consume the ORDER BY clause because (1) the order of IN terms
         2394  +          ** is not necessarily related to the order of output terms and
         2395  +          ** (2) Multiple outputs from a single IN value will not merge
         2396  +          ** together.  */
         2397  +          pIdxInfo->orderByConsumed = 0;
  2400   2398           }
  2401   2399         }
  2402   2400       }
  2403   2401       if( i>=pIdxInfo->nConstraint ) break;
  2404   2402     }
         2403  +
         2404  +  /* The orderByConsumed signal is only valid if all outer loops collectively
         2405  +  ** generate just a single row of output.
         2406  +  */
         2407  +  if( pIdxInfo->orderByConsumed ){
         2408  +    for(i=0; i<p->i; i++){
         2409  +      if( (p->aLevel[i].plan.wsFlags & WHERE_UNIQUE)==0 ){
         2410  +        pIdxInfo->orderByConsumed = 0;
         2411  +      }
         2412  +    }
         2413  +  }
  2405   2414     
  2406   2415     /* If there is an ORDER BY clause, and the selected virtual table index
  2407   2416     ** does not satisfy it, increase the cost of the scan accordingly. This
  2408   2417     ** matches the processing for non-virtual tables in bestBtreeIndex().
  2409   2418     */
  2410   2419     rCost = pIdxInfo->estimatedCost;
  2411   2420     if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){
................................................................................
  2422   2431     if( (SQLITE_BIG_DBL/((double)2))<rCost ){
  2423   2432       p->cost.rCost = (SQLITE_BIG_DBL/((double)2));
  2424   2433     }else{
  2425   2434       p->cost.rCost = rCost;
  2426   2435     }
  2427   2436     p->cost.plan.u.pVtabIdx = pIdxInfo;
  2428   2437     if( pIdxInfo->orderByConsumed ){
  2429         -    assert( sortOrder==0 || sortOrder==1 );
  2430         -    p->cost.plan.wsFlags |= WHERE_ORDERED + sortOrder*WHERE_REVERSE;
         2438  +    p->cost.plan.wsFlags |= WHERE_ORDERED;
  2431   2439       p->cost.plan.nOBSat = nOrderBy;
  2432   2440     }else{
  2433   2441       p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
  2434   2442     }
  2435   2443     p->cost.plan.nEq = 0;
  2436   2444     pIdxInfo->nOrderBy = nOrderBy;
  2437   2445   
................................................................................
  4160   4168     Parse *pParse;                  /* Parsing context */
  4161   4169     Vdbe *v;                        /* The prepared stmt under constructions */
  4162   4170     struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  4163   4171     int addrBrk;                    /* Jump here to break out of the loop */
  4164   4172     int addrCont;                   /* Jump here to continue with next cycle */
  4165   4173     int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  4166   4174     int iReleaseReg = 0;      /* Temp register to free before returning */
         4175  +  Bitmask newNotReady;      /* Return value */
  4167   4176   
  4168   4177     pParse = pWInfo->pParse;
  4169   4178     v = pParse->pVdbe;
  4170   4179     pWC = pWInfo->pWC;
  4171   4180     pLevel = &pWInfo->a[iLevel];
  4172   4181     pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  4173   4182     iCur = pTabItem->iCursor;
  4174   4183     bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
  4175   4184     omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 
  4176   4185              && (wctrlFlags & WHERE_FORCE_TABLE)==0;
         4186  +  VdbeNoopComment((v, "Begin Join Loop %d", iLevel));
  4177   4187   
  4178   4188     /* Create labels for the "break" and "continue" instructions
  4179   4189     ** for the current loop.  Jump to addrBrk to break out of a loop.
  4180   4190     ** Jump to cont to go immediately to the next iteration of the
  4181   4191     ** loop.
  4182   4192     **
  4183   4193     ** When there is an IN operator, we also have a "addrNxt" label that
................................................................................
  4820   4830       assert( bRev==0 || bRev==1 );
  4821   4831       assert( omitTable==0 );
  4822   4832       pLevel->op = aStep[bRev];
  4823   4833       pLevel->p1 = iCur;
  4824   4834       pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
  4825   4835       pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
  4826   4836     }
  4827         -  notReady &= ~getMask(pWC->pMaskSet, iCur);
         4837  +  newNotReady = notReady & ~getMask(pWC->pMaskSet, iCur);
  4828   4838   
  4829   4839     /* Insert code to test every subexpression that can be completely
  4830   4840     ** computed using the current set of tables.
  4831   4841     **
  4832   4842     ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
  4833   4843     ** the use of indices become tests that are evaluated against each row of
  4834   4844     ** the relevant input tables.
  4835   4845     */
  4836   4846     for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
  4837   4847       Expr *pE;
  4838   4848       testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
  4839   4849       testcase( pTerm->wtFlags & TERM_CODED );
  4840   4850       if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
  4841         -    if( (pTerm->prereqAll & notReady)!=0 ){
         4851  +    if( (pTerm->prereqAll & newNotReady)!=0 ){
  4842   4852         testcase( pWInfo->untestedTerms==0
  4843   4853                  && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
  4844   4854         pWInfo->untestedTerms = 1;
  4845   4855         continue;
  4846   4856       }
  4847   4857       pE = pTerm->pExpr;
  4848   4858       assert( pE!=0 );
  4849   4859       if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
  4850   4860         continue;
  4851   4861       }
  4852   4862       sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
  4853   4863       pTerm->wtFlags |= TERM_CODED;
  4854   4864     }
         4865  +
         4866  +  /* Insert code to test for implied constraints based on transitivity
         4867  +  ** of the "==" operator.
         4868  +  **
         4869  +  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
         4870  +  ** and we are coding the t1 loop and the t2 loop has not yet coded,
         4871  +  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
         4872  +  ** the implied "t1.a=123" constraint.
         4873  +  */
         4874  +  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
         4875  +    Expr *pE;
         4876  +    WhereTerm *pAlt;
         4877  +    Expr sEq;
         4878  +    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
         4879  +    if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
         4880  +    if( pTerm->leftCursor!=iCur ) continue;
         4881  +    pE = pTerm->pExpr;
         4882  +    assert( !ExprHasProperty(pE, EP_FromJoin) );
         4883  +    assert( (pTerm->prereqRight & newNotReady)!=0 );
         4884  +    pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
         4885  +    if( pAlt==0 ) continue;
         4886  +    VdbeNoopComment((v, "begin transitive constraint"));
         4887  +    sEq = *pAlt->pExpr;
         4888  +    sEq.pLeft = pE->pLeft;
         4889  +    sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
         4890  +  }
  4855   4891   
  4856   4892     /* For a LEFT OUTER JOIN, generate code that will record the fact that
  4857   4893     ** at least one row of the right table has matched the left table.  
  4858   4894     */
  4859   4895     if( pLevel->iLeftJoin ){
  4860   4896       pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
  4861   4897       sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
  4862   4898       VdbeComment((v, "record LEFT JOIN hit"));
  4863   4899       sqlite3ExprCacheClear(pParse);
  4864   4900       for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
  4865   4901         testcase( pTerm->wtFlags & TERM_VIRTUAL );  /* IMP: R-30575-11662 */
  4866   4902         testcase( pTerm->wtFlags & TERM_CODED );
  4867   4903         if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
  4868         -      if( (pTerm->prereqAll & notReady)!=0 ){
         4904  +      if( (pTerm->prereqAll & newNotReady)!=0 ){
  4869   4905           assert( pWInfo->untestedTerms );
  4870   4906           continue;
  4871   4907         }
  4872   4908         assert( pTerm->pExpr );
  4873   4909         sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
  4874   4910         pTerm->wtFlags |= TERM_CODED;
  4875   4911       }
  4876   4912     }
  4877   4913     sqlite3ReleaseTempReg(pParse, iReleaseReg);
  4878   4914   
  4879         -  return notReady;
         4915  +  return newNotReady;
  4880   4916   }
  4881   4917   
  4882   4918   #if defined(SQLITE_TEST)
  4883   4919   /*
  4884   4920   ** The following variable holds a text description of query plan generated
  4885   4921   ** by the most recent call to sqlite3WhereBegin().  Each call to WhereBegin
  4886   4922   ** overwrites the previous.  This information is used for testing and

Added test/btreefault.test.

            1  +# 2013 April 02
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file contains fault injection tests designed to test the btree.c 
           13  +# module.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/malloc_common.tcl
           19  +set testprefix btreefault
           20  +
           21  +do_test 1-pre1 {
           22  +  execsql {
           23  +    PRAGMA auto_vacuum = incremental;
           24  +    PRAGMA journal_mode = DELETE;
           25  +    CREATE TABLE t1(a PRIMARY KEY, b);
           26  +    INSERT INTO t1 VALUES(randomblob(1000), randomblob(100));
           27  +    INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           28  +    INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           29  +    INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           30  +    INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           31  +    DELETE FROM t1 WHERE rowid%2;
           32  +  }
           33  +  faultsim_save_and_close
           34  +} {}
           35  +
           36  +do_faultsim_test 1 -prep {
           37  +  faultsim_restore_and_reopen
           38  +  set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY a" -1 DUMMY]
           39  +  sqlite3_step $::STMT
           40  +  sqlite3_step $::STMT
           41  +} -body {
           42  +  execsql { PRAGMA incremental_vacuum = 10 }
           43  +} -test {
           44  +  sqlite3_finalize $::STMT
           45  +  faultsim_test_result {0 {}} 
           46  +  faultsim_integrity_check
           47  +}
           48  +
           49  +finish_test
           50  +

Changes to test/dbstatus2.test.

    36     36   proc db_write {db {reset 0}} {
    37     37     sqlite3_db_status $db CACHE_WRITE $reset
    38     38   }
    39     39   
    40     40   do_test 1.1 {
    41     41     db close
    42     42     sqlite3 db test.db
           43  +  execsql { PRAGMA mmap_size = 0 }
    43     44     expr {[file size test.db] / 1024}
    44     45   } 6
    45     46   
    46     47   do_test 1.2 {
    47     48     execsql { SELECT b FROM t1 WHERE a=2 }
    48     49     db_hit_miss db
    49     50   } {{0 2 0} {0 4 0}}

Changes to test/exclusive2.test.

    20     20   #
    21     21   do_not_use_codec
    22     22   
    23     23   ifcapable {!pager_pragmas} {
    24     24     finish_test
    25     25     return
    26     26   }
           27  +
           28  +# Tests in this file verify that locking_mode=exclusive causes SQLite to
           29  +# use cached pages even if the database is changed on disk. This doesn't
           30  +# work with mmap.
           31  +if {[permutation]=="mmap"} {
           32  +  finish_test
           33  +  return
           34  +}
    27     35   
    28     36   # This module does not work right if the cache spills at unexpected
    29     37   # moments.  So disable the soft-heap-limit.
    30     38   #
    31     39   sqlite3_soft_heap_limit 0
    32     40   
    33     41   proc pagerChangeCounter {filename new {fd ""}} {

Changes to test/fts3aux1.test.

   350    350   
   351    351   do_execsql_test 3.1.1 {
   352    352     CREATE VIRTUAL TABLE t2 USING fts4;
   353    353   }
   354    354   
   355    355   do_catchsql_test 3.1.2 {
   356    356     CREATE VIRTUAL TABLE terms2 USING fts4aux;
   357         -} {1 {wrong number of arguments to fts4aux constructor}}
          357  +} {1 {invalid arguments to fts4aux constructor}}
   358    358   do_catchsql_test 3.1.3 {
   359    359     CREATE VIRTUAL TABLE terms2 USING fts4aux(t2, t2);
   360         -} {1 {wrong number of arguments to fts4aux constructor}}
          360  +} {1 {invalid arguments to fts4aux constructor}}
   361    361   
   362    362   do_execsql_test 3.2.1 {
   363    363     CREATE VIRTUAL TABLE terms3 USING fts4aux(does_not_exist)
   364    364   }
   365    365   do_catchsql_test 3.2.2 {
   366    366     SELECT * FROM terms3
   367    367   } {1 {SQL logic error or missing database}}
................................................................................
   440    440   }
   441    441   
   442    442   #-------------------------------------------------------------------------
   443    443   # The following tests check that fts4aux can handle an fts table with an
   444    444   # odd name (one that requires quoting for use in SQL statements). And that
   445    445   # the argument to the fts4aux constructor is properly dequoted before use.
   446    446   #
   447         -#
   448    447   do_execsql_test 5.1 {
   449    448     CREATE VIRTUAL TABLE "abc '!' def" USING fts4(x, y);
   450    449     INSERT INTO "abc '!' def" VALUES('XX', 'YY');
   451    450   
   452    451     CREATE VIRTUAL TABLE terms3 USING fts4aux("abc '!' def");
   453    452     SELECT * FROM terms3;
   454    453   } {xx * 1 1 xx 0 1 1 yy * 1 1 yy 1 1 1}
   455    454   
   456    455   do_execsql_test 5.2 {
   457    456     CREATE VIRTUAL TABLE "%%^^%%" USING fts4aux('abc ''!'' def');
   458    457     SELECT * FROM "%%^^%%";
   459    458   } {xx * 1 1 xx 0 1 1 yy * 1 1 yy 1 1 1}
   460    459   
          460  +#-------------------------------------------------------------------------
          461  +# Test that we can create an fts4aux table in the temp database.
          462  +#
          463  +forcedelete test.db2
          464  +do_execsql_test 6.1 {
          465  +  CREATE VIRTUAL TABLE ft1 USING fts4(x, y);
          466  +  INSERT INTO ft1 VALUES('a b', 'c d');
          467  +  INSERT INTO ft1 VALUES('e e', 'c d');
          468  +  INSERT INTO ft1 VALUES('a a', 'b b');
          469  +  CREATE VIRTUAL TABLE temp.aux1 USING fts4aux(main, ft1);
          470  +  SELECT * FROM aux1;
          471  +} {
          472  +    a * 2 3 a 0 2 3 
          473  +    b * 2 3 b 0 1 1 b 1 1 2 
          474  +    c * 2 2 c 1 2 2 
          475  +    d * 2 2 d 1 2 2 
          476  +    e * 1 2 e 0 1 2
          477  +}
          478  +
          479  +do_execsql_test 6.2 {
          480  +  ATTACH 'test.db2' AS att;
          481  +  CREATE VIRTUAL TABLE att.ft1 USING fts4(x, y);
          482  +  INSERT INTO att.ft1 VALUES('v w', 'x y');
          483  +  INSERT INTO att.ft1 VALUES('z z', 'x y');
          484  +  INSERT INTO att.ft1 VALUES('v v', 'w w');
          485  +  CREATE VIRTUAL TABLE temp.aux2 USING fts4aux(att, ft1);
          486  +  SELECT * FROM aux2;
          487  +} {
          488  +    v * 2 3 v 0 2 3 
          489  +    w * 2 3 w 0 1 1 w 1 1 2 
          490  +    x * 2 2 x 1 2 2 
          491  +    y * 2 2 y 1 2 2 
          492  +    z * 1 2 z 0 1 2
          493  +}
          494  +
          495  +foreach {tn q res1 res2} {
          496  +  1  { SELECT * FROM %%% WHERE term = 'a' } {a * 2 3 a 0 2 3} {}
          497  +  2  { SELECT * FROM %%% WHERE term = 'x' } {} {x * 2 2 x 1 2 2} 
          498  +
          499  +  3  { SELECT * FROM %%% WHERE term >= 'y' } 
          500  +     {} {y * 2 2 y 1 2 2 z * 1 2 z 0 1 2}
          501  +
          502  +  4  { SELECT * FROM %%% WHERE term <= 'c' } 
          503  +     {a * 2 3 a 0 2 3 b * 2 3 b 0 1 1 b 1 1 2 c * 2 2 c 1 2 2} {}
          504  +} {
          505  +  set sql1 [string map {%%% aux1} $q]
          506  +  set sql2 [string map {%%% aux2} $q]
          507  +
          508  +  do_execsql_test 7.$tn.1 $sql1 $res1
          509  +  do_execsql_test 7.$tn.2 $sql2 $res2
          510  +}
          511  +
          512  +do_test 8.1 {
          513  +  catchsql { CREATE VIRTUAL TABLE att.aux3 USING fts4aux(main, ft1) }
          514  +} {1 {invalid arguments to fts4aux constructor}}
          515  +
          516  +do_test 8.2 {
          517  +  execsql {DETACH att}
          518  +  catchsql { SELECT * FROM aux2 }
          519  +} {1 {SQL logic error or missing database}}
   461    520   
   462    521   finish_test
          522  +

Added test/fts3tok1.test.

            1  +# 2013 April 22
            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 "fts3tokenize" virtual table
           13  +# that is part of the FTS3 module.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +ifcapable !fts3 { finish_test ; return }
           19  +set ::testprefix fts3tok1
           20  +
           21  +#-------------------------------------------------------------------------
           22  +# Simple test cases. Using the default (simple) tokenizer.
           23  +#
           24  +do_execsql_test 1.0 {
           25  +  CREATE VIRTUAL TABLE t1 USING fts3tokenize(simple);
           26  +  CREATE VIRTUAL TABLE t2 USING fts3tokenize();
           27  +  CREATE VIRTUAL TABLE t3 USING fts3tokenize(simple, '', 'xyz ');
           28  +}
           29  +
           30  +foreach {tn tbl} {1 t1 2 t2 3 t3} {
           31  +  do_execsql_test 1.$tn.1 "SELECT * FROM $tbl WHERE input = 'one two three'" {
           32  +    {one two three} one   0  3 0 
           33  +    {one two three} two   4  7 1 
           34  +    {one two three} three 8 13 2
           35  +  }
           36  +
           37  +  do_execsql_test 1.$tn.2 "
           38  +    SELECT token FROM $tbl WHERE input = 'OnE tWo tHrEe'
           39  +  " {
           40  +    one two three
           41  +  }
           42  +}
           43  +
           44  +do_execsql_test 1.4 {
           45  +  SELECT token FROM t3 WHERE input = '1x2x3x'
           46  +} {1 2 3}
           47  +
           48  +do_execsql_test 1.5 {
           49  +  SELECT token FROM t1 WHERE input = '1x2x3x'
           50  +} {1x2x3x}
           51  +
           52  +do_execsql_test 1.6 {
           53  +  SELECT token FROM t3 WHERE input = '1''2x3x'
           54  +} {1'2 3}
           55  +
           56  +do_execsql_test 1.7 {
           57  +  SELECT token FROM t3 WHERE input = ''
           58  +} {}
           59  +
           60  +do_execsql_test 1.8 {
           61  +  SELECT token FROM t3 WHERE input = NULL
           62  +} {}
           63  +
           64  +do_execsql_test 1.9 {
           65  +  SELECT * FROM t3 WHERE input = 123
           66  +} {123 123 0 3 0}
           67  +
           68  +do_execsql_test 1.10 {
           69  +  SELECT * FROM t1 WHERE input = 'a b c' AND token = 'b';
           70  +} {
           71  +  {a b c} b 2 3 1
           72  +}
           73  +
           74  +do_execsql_test 1.11 {
           75  +  SELECT * FROM t1 WHERE token = 'b' AND input = 'a b c';
           76  +} {
           77  +  {a b c} b 2 3 1
           78  +}
           79  +
           80  +do_execsql_test 1.12 {
           81  +  SELECT * FROM t1 WHERE input < 'b' AND input = 'a b c';
           82  +} {
           83  +  {a b c} a 0 1 0 
           84  +  {a b c} b 2 3 1 
           85  +  {a b c} c 4 5 2
           86  +}
           87  +
           88  +do_execsql_test 1.13.1 {
           89  +  CREATE TABLE c1(x);
           90  +  INSERT INTO c1(x) VALUES('a b c');
           91  +  INSERT INTO c1(x) VALUES('d e f');
           92  +}
           93  +breakpoint
           94  +do_execsql_test 1.13.2 {
           95  +  SELECT * FROM c1, t1 WHERE input = x AND c1.rowid=t1.rowid;
           96  +} {
           97  +  {a b c} {a b c} a 0 1 0 
           98  +  {d e f} {d e f} e 2 3 1 
           99  +}
          100  +
          101  +
          102  +#-------------------------------------------------------------------------
          103  +# Error cases.
          104  +#
          105  +do_catchsql_test 2.0 {
          106  +  CREATE VIRTUAL TABLE tX USING fts3tokenize(nosuchtokenizer);
          107  +} {1 {unknown tokenizer: nosuchtokenizer}}
          108  +
          109  +proc fts3_tokenizer {args} { return 1 }
          110  +db function fts3_tokenizer -argcount 1 fts3_tokenizer
          111  +do_catchsql_test 2.1 {
          112  +  CREATE VIRTUAL TABLE tX USING fts3tokenize(simple);
          113  +} {1 {vtable constructor failed: tX}}
          114  +
          115  +db close
          116  +sqlite3 db test.db
          117  +do_catchsql_test 2.2 {
          118  +  CREATE VIRTUAL TABLE t4 USING fts3tokenize;
          119  +  SELECT * FROM t4;
          120  +} {1 {SQL logic error or missing database}}
          121  +
          122  +
          123  +finish_test
          124  +
          125  +

Added test/fts3tok_err.test.

            1  +# 2013 April 22
            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 "fts3tokenize" virtual table
           13  +# that is part of the FTS3 module.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/malloc_common.tcl
           19  +ifcapable !fts3 { finish_test ; return }
           20  +set ::testprefix fts3tok_err
           21  +
           22  +
           23  +faultsim_save_and_close
           24  +do_faultsim_test fts3tok_err-1 -faults oom* -prep {
           25  +  faultsim_restore_and_reopen
           26  +} -body {
           27  +  execsql { CREATE VIRTUAL TABLE t1 USING fts3tokenize("simple"); }
           28  +} -test {
           29  +  faultsim_test_result {0 {}} 
           30  +}
           31  +
           32  +do_test fts3tok_err-2.prep {
           33  +  faultsim_delete_and_reopen 
           34  +  execsql { CREATE VIRTUAL TABLE t1 USING fts3tokenize("simple"); }
           35  +  faultsim_save_and_close
           36  +} {}
           37  +
           38  +do_faultsim_test fts3tok_err-2 -faults oom* -prep {
           39  +  faultsim_restore_and_reopen
           40  +} -body {
           41  +  execsql { SELECT token FROM t1 WHERE input = 'A galaxy far, far away' } 
           42  +} -test {
           43  +  faultsim_test_result {0 {a galaxy far far away}} 
           44  +}
           45  +
           46  +
           47  +finish_test
           48  +
           49  +

Changes to test/func.test.

  1269   1269   } {1}
  1270   1270   do_test func-29.3 {
  1271   1271     db close
  1272   1272     sqlite3 db test.db
  1273   1273     sqlite3_db_status db CACHE_MISS 1
  1274   1274     db eval {SELECT typeof(+x) FROM t29 ORDER BY id}
  1275   1275   } {integer null real blob text}
  1276         -do_test func-29.4 {
  1277         -  set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
  1278         -  if {$x>100} {set x many}
  1279         -  set x
  1280         -} {many}
         1276  +if {[permutation] != "mmap"} {
         1277  +  do_test func-29.4 {
         1278  +    set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
         1279  +    if {$x>100} {set x many}
         1280  +    set x
         1281  +  } {many}
         1282  +}
  1281   1283   do_test func-29.5 {
  1282   1284     db close
  1283   1285     sqlite3 db test.db
  1284   1286     sqlite3_db_status db CACHE_MISS 1
  1285   1287     db eval {SELECT sum(length(x)) FROM t29}
  1286   1288   } {1000009}
  1287   1289   do_test func-29.6 {

Changes to test/incrblob.test.

   119    119       }
   120    120     }
   121    121   
   122    122     db close
   123    123     forcedelete test.db test.db-journal
   124    124   
   125    125     sqlite3 db test.db
          126  +  execsql "PRAGMA mmap_size = 0"
   126    127     execsql "PRAGMA auto_vacuum = $AutoVacuumMode"
   127    128   
   128    129     do_test incrblob-2.$AutoVacuumMode.1 {
   129    130       set ::str [string repeat abcdefghij 2900]
   130    131       execsql {
   131    132         BEGIN;
   132    133         CREATE TABLE blobs(k PRIMARY KEY, v BLOB, i INTEGER);
................................................................................
   145    146       } $AutoVacuumMode
   146    147     }
   147    148   
   148    149     do_test incrblob-2.$AutoVacuumMode.3 {
   149    150       # Open and close the db to make sure the page cache is empty.
   150    151       db close
   151    152       sqlite3 db test.db
          153  +    execsql "PRAGMA mmap_size = 0"
   152    154     
   153    155       # Read the last 20 bytes of the blob via a blob handle.
   154    156       set ::blob [db incrblob blobs v 1]
   155    157       seek $::blob -20 end
   156    158       set ::fragment [read $::blob]
   157    159       close $::blob
   158    160     
................................................................................
   167    169       string range [db one {SELECT v FROM blobs}] end-19 end
   168    170     } $::fragment
   169    171   
   170    172     do_test incrblob-2.$AutoVacuumMode.5 {
   171    173       # Open and close the db to make sure the page cache is empty.
   172    174       db close
   173    175       sqlite3 db test.db
          176  +    execsql "PRAGMA mmap_size = 0"
   174    177     
   175    178       # Write the second-to-last 20 bytes of the blob via a blob handle.
   176    179       #
   177    180       set ::blob [db incrblob blobs v 1]
   178    181       seek $::blob -40 end
   179    182       puts -nonewline $::blob "1234567890abcdefghij"
   180    183       flush $::blob
................................................................................
   196    199       string range [db one {SELECT v FROM blobs}] end-39 end-20
   197    200     } "1234567890abcdefghij"
   198    201   
   199    202     do_test incrblob-2.$AutoVacuumMode.8 {
   200    203       # Open and close the db to make sure the page cache is empty.
   201    204       db close
   202    205       sqlite3 db test.db
          206  +    execsql { PRAGMA mmap_size = 0 }
   203    207   
   204    208       execsql { SELECT i FROM blobs } 
   205    209     } {45}
   206    210   
   207    211     do_test incrblob-2.$AutoVacuumMode.9 {
   208    212       nRead db
   209    213     } [expr $AutoVacuumMode ? 4 : 30]

Changes to test/loadext.test.

   135    135   #
   136    136   do_test loadext-2.1 {
   137    137     forcedelete ${testextension}xx
   138    138     set rc [catch {
   139    139       sqlite3_load_extension db "${testextension}xx"
   140    140     } msg]
   141    141     list $rc $msg
   142         -} [list 1 [format $dlerror_nosuchfile ${testextension}xx]]
          142  +} /[list 1 [format $dlerror_nosuchfile ${testextension}xx.*]]/
   143    143   
   144    144   # Try to load an extension for which the file is not a shared object
   145    145   #
   146    146   do_test loadext-2.2 {
   147         -  set fd [open "${testextension}xx" w]
          147  +  set fd [open "./notasharedlib.so" w]
          148  +  puts $fd blah
          149  +  close $fd
          150  +  set fd [open "./notasharedlib.dll" w]
   148    151     puts $fd blah
   149    152     close $fd
   150    153     set rc [catch {
   151         -    sqlite3_load_extension db "${testextension}xx"
          154  +    sqlite3_load_extension db "./notasharedlib"
   152    155     } msg]
   153         -  set expected_error_pattern [format $dlerror_notadll ${testextension}xx]
   154         -  list $rc [string match $expected_error_pattern $msg]
   155         -} [list 1 1]
          156  +  list $rc $msg
          157  +} /[list 1 [format $dlerror_notadll ./notasharedlib.*]]/
   156    158   
   157    159   # Try to load an extension for which the file is present but the
   158    160   # entry point is not.
   159    161   #
   160    162   do_test loadext-2.3 {
   161    163     set rc [catch {
   162    164       sqlite3_load_extension db $testextension icecream
................................................................................
   192    194     set res [catchsql {
   193    195       SELECT load_extension($::testextension)
   194    196     }]
   195    197     if {$::tcl_platform(os) eq "Darwin"} {
   196    198       regsub {0x[1234567890abcdefABCDEF]*} $res XXX res
   197    199     }
   198    200     set res
   199         -} [list 1 [format $dlerror_nosymbol $testextension sqlite3_extension_init]]
          201  +} /[list 1 [format $dlerror_nosymbol $testextension sqlite3_.*_init]]/
   200    202   do_test loadext-3.3 {
   201    203     catchsql {
   202    204       SELECT load_extension($::testextension,'testloadext_init')
   203    205     }
   204    206   } {0 {{}}}
   205    207   do_test loadext-3.4 {
   206    208     catchsql {

Changes to test/malloc_common.tcl.

   260    260   # by -test scripts.
   261    261   #
   262    262   proc faultsim_test_result_int {args} {
   263    263     upvar testrc testrc testresult testresult testnfail testnfail
   264    264     set t [list $testrc $testresult]
   265    265     set r $args
   266    266     if { ($testnfail==0 && $t != [lindex $r 0]) || [lsearch $r $t]<0 } {
   267         -    error "nfail=$testnfail rc=$testrc result=$testresult"
          267  +    error "nfail=$testnfail rc=$testrc result=$testresult list=$r"
   268    268     }
   269    269   }
   270    270   
   271    271   #--------------------------------------------------------------------------
   272    272   # Usage do_one_faultsim_test NAME ?OPTIONS...? 
   273    273   #
   274    274   # The first argument, <test number>, is used as a prefix of the test names

Added test/mmap1.test.

            1  +# 2013 March 20
            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  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +ifcapable !mmap {
           16  +  finish_test
           17  +  return
           18  +}
           19  +source $testdir/lock_common.tcl
           20  +set testprefix mmap1
           21  +
           22  +proc nRead {db} {
           23  +  set bt [btree_from_db $db]
           24  +  db_enter $db
           25  +  array set stats [btree_pager_stats $bt]
           26  +  db_leave $db
           27  +  # puts [array get stats]
           28  +  return $stats(read)
           29  +}
           30  +
           31  +proc register_rblob_code {dbname seed} {
           32  +  return [subst -nocommands {
           33  +    set ::rcnt $seed
           34  +    proc rblob {n} {
           35  +      set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF]
           36  +      set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]] 
           37  +      string range [string repeat [set str] [expr [set n]/4]] 1 [set n]
           38  +    }
           39  +    $dbname func rblob rblob
           40  +  }]
           41  +}
           42  +
           43  +foreach {t mmap_size nRead c2init} {
           44  +  1.1 { PRAGMA mmap_size = 67108864 }   4 {PRAGMA mmap_size = 0}
           45  +  1.2 { PRAGMA mmap_size =    53248 } 150 {PRAGMA mmap_size = 0}
           46  +  1.3 { PRAGMA mmap_size =        0 } 344 {PRAGMA mmap_size = 0}
           47  +  1.4 { PRAGMA mmap_size = 67108864 }   4 {PRAGMA mmap_size = 67108864 }
           48  +  1.5 { PRAGMA mmap_size =    53248 } 150 {PRAGMA mmap_size = 67108864 }
           49  +  1.6 { PRAGMA mmap_size =        0 } 344 {PRAGMA mmap_size = 67108864 }
           50  +} {
           51  +  do_multiclient_test tn {
           52  +    sql1 {PRAGMA page_size=1024}
           53  +    sql1 $mmap_size
           54  +    sql2 $c2init
           55  +
           56  +    code2 [register_rblob_code db2 0]
           57  +
           58  +    sql2 {
           59  +      PRAGMA page_size=1024;
           60  +      PRAGMA auto_vacuum = 1;
           61  +      CREATE TABLE t1(a, b, UNIQUE(a, b));
           62  +      INSERT INTO t1 VALUES(rblob(500), rblob(500));
           63  +      INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    2
           64  +      INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    4
           65  +      INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    8
           66  +      INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   16
           67  +      INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   32
           68  +    }
           69  +    do_test $t.$tn.1 {
           70  +      sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count"
           71  +    } {32 ok 77}
           72  +
           73  +    # Have connection 2 shrink the file. Check connection 1 can still read it.
           74  +    sql2 { DELETE FROM t1 WHERE rowid%2; }
           75  +    do_test $t.$tn.2 {
           76  +      sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count"
           77  +    } {16 ok 42}
           78  +
           79  +    # Have connection 2 grow the file. Check connection 1 can still read it.
           80  +    sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 }
           81  +    do_test $t.$tn.3 {
           82  +      sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count"
           83  +    } {32 ok 79}
           84  +
           85  +    # Have connection 2 grow the file again. Check connection 1 is still ok.
           86  +    sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 }
           87  +    do_test $t.$tn.4 {
           88  +      sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count"
           89  +    } {64 ok 149}
           90  +
           91  +    # Check that the number of pages read by connection 1 indicates that the
           92  +    # "PRAGMA mmap_size" command worked.
           93  +    do_test $t.$tn.5 { nRead db } $nRead
           94  +  }
           95  +}
           96  +
           97  +set ::rcnt 0
           98  +proc rblob {n} {
           99  +  set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF]
          100  +  set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] 
          101  +  string range [string repeat $str [expr $n/4]] 1 $n
          102  +}
          103  +
          104  +reset_db
          105  +db func rblob rblob
          106  +
          107  +do_execsql_test 2.1 {
          108  +  PRAGMA auto_vacuum = 1;
          109  +  PRAGMA mmap_size = 67108864;
          110  +  PRAGMA journal_mode = wal;
          111  +  CREATE TABLE t1(a, b, UNIQUE(a, b));
          112  +  INSERT INTO t1 VALUES(rblob(500), rblob(500));
          113  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    2
          114  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    4
          115  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    8
          116  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   16
          117  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   32
          118  +  PRAGMA wal_checkpoint;
          119  +} {67108864 wal 0 103 103}
          120  +
          121  +do_execsql_test 2.2 {
          122  +  PRAGMA auto_vacuum;
          123  +  SELECT count(*) FROM t1;
          124  +} {1 32}
          125  +
          126  +do_test 2.3 {
          127  +  sqlite3 db2 test.db
          128  +  db2 func rblob rblob
          129  +  db2 eval { 
          130  +    DELETE FROM t1 WHERE (rowid%4);
          131  +    PRAGMA wal_checkpoint;
          132  +  }
          133  +  db2 eval { 
          134  +    INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    16
          135  +    SELECT count(*) FROM t1;
          136  +  }
          137  +} {16}
          138  +
          139  +do_execsql_test 2.4 {
          140  +  PRAGMA wal_checkpoint;
          141  +} {0 24 24}
          142  +
          143  +db2 close
          144  +reset_db
          145  +db func rblob rblob
          146  +do_execsql_test 3.1 {
          147  +  PRAGMA auto_vacuum = 1;
          148  +
          149  +  CREATE TABLE t1(a, b, UNIQUE(a, b));
          150  +  INSERT INTO t1 VALUES(rblob(500), rblob(500));
          151  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    2
          152  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    4
          153  +  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    8
          154  +
          155  +  CREATE TABLE t2(a, b, UNIQUE(a, b));
          156  +  INSERT INTO t2 SELECT * FROM t1;
          157  +} {}
          158  +
          159  +do_test 3.2 {
          160  +  set nRow 0
          161  +  db eval {SELECT * FROM t2 ORDER BY a, b} {
          162  +    if {$nRow==4} { db eval { DELETE FROM t1 } }
          163  +    incr nRow
          164  +  }
          165  +  set nRow
          166  +} {8}
          167  +
          168  +#-------------------------------------------------------------------------
          169  +# Ensure that existing cursors using xFetch() pages see changes made
          170  +# to rows using the incrblob API.
          171  +#
          172  +reset_db
          173  +set aaa [string repeat a 400]
          174  +set bbb [string repeat b 400]
          175  +set ccc [string repeat c 400]
          176  +set ddd [string repeat d 400]
          177  +set eee [string repeat e 400]
          178  +
          179  +do_execsql_test 4.1 {
          180  +  PRAGMA page_size = 1024;
          181  +  CREATE TABLE t1(x);
          182  +  INSERT INTO t1 VALUES($aaa);
          183  +  INSERT INTO t1 VALUES($bbb);
          184  +  INSERT INTO t1 VALUES($ccc);
          185  +  INSERT INTO t1 VALUES($ddd);
          186  +  SELECT * FROM t1;
          187  +  BEGIN;
          188  +} [list $aaa $bbb $ccc $ddd]
          189  +
          190  +do_test 4.2 {
          191  +  set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY rowid" -1 dummy]
          192  +  sqlite3_step $::STMT
          193  +  sqlite3_column_text $::STMT 0
          194  +} $aaa
          195  +
          196  +do_test 4.3 {
          197  +  foreach r {2 3 4} {
          198  +    set fd [db incrblob t1 x $r]
          199  +    puts -nonewline $fd $eee
          200  +    close $fd
          201  +  }
          202  +
          203  +  set res [list]
          204  +  while {"SQLITE_ROW" == [sqlite3_step $::STMT]} {
          205  +    lappend res [sqlite3_column_text $::STMT 0]
          206  +  }
          207  +  set res
          208  +} [list $eee $eee $eee]
          209  +
          210  +do_test 4.4 {
          211  +  sqlite3_finalize $::STMT
          212  +} SQLITE_OK
          213  +
          214  +do_execsql_test 4.5 { COMMIT }
          215  +
          216  +#-------------------------------------------------------------------------
          217  +# Ensure that existing cursors holding xFetch() references are not 
          218  +# confused if those pages are moved to make way for the root page of a
          219  +# new table or index.
          220  +#
          221  +reset_db
          222  +do_execsql_test 5.1 {
          223  +  PRAGMA auto_vacuum = 2;
          224  +  PRAGMA page_size = 1024;
          225  +  CREATE TABLE t1(x);
          226  +  INSERT INTO t1 VALUES($aaa);
          227  +  INSERT INTO t1 VALUES($bbb);
          228  +  INSERT INTO t1 VALUES($ccc);
          229  +  INSERT INTO t1 VALUES($ddd);
          230  +
          231  +  PRAGMA auto_vacuum;
          232  +  SELECT * FROM t1;
          233  +} [list 2 $aaa $bbb $ccc $ddd]
          234  +
          235  +do_test 5.2 {
          236  +  set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY rowid" -1 dummy]
          237  +  sqlite3_step $::STMT
          238  +  sqlite3_column_text $::STMT 0
          239  +} $aaa
          240  +
          241  +do_execsql_test 5.3 {
          242  +  CREATE TABLE t2(x);
          243  +  INSERT INTO t2 VALUES('tricked you!');
          244  +  INSERT INTO t2 VALUES('tricked you!');
          245  +}
          246  +
          247  +do_test 5.4 {
          248  +  sqlite3_step $::STMT
          249  +  sqlite3_column_text $::STMT 0
          250  +} $bbb
          251  +
          252  +do_test 5.5 {
          253  +  sqlite3_finalize $::STMT
          254  +} SQLITE_OK
          255  +
          256  +#-------------------------------------------------------------------------
          257  +# Test various mmap_size settings.
          258  +#
          259  +foreach {tn1 mmap1 mmap2} {
          260  +     1 6144       167773
          261  +     2 18432      140399
          262  +     3 43008      401302
          263  +     4 92160      253899
          264  +     5 190464          2
          265  +     6 387072     752431
          266  +     7 780288     291143
          267  +     8 1566720    594306
          268  +     9 3139584    829137
          269  +     10 6285312   793963
          270  +     11 12576768 1015590
          271  +} {
          272  +  do_multiclient_test tn {
          273  +    sql1 {
          274  +      CREATE TABLE t1(a PRIMARY KEY);
          275  +      CREATE TABLE t2(x);
          276  +      INSERT INTO t2 VALUES('');
          277  +    }
          278  +
          279  +    code1 [register_rblob_code db  0]
          280  +    code2 [register_rblob_code db2 444]
          281  +
          282  +    sql1 "PRAGMA mmap_size = $mmap1"
          283  +    sql2 "PRAGMA mmap_size = $mmap2"
          284  +
          285  +    do_test $tn1.$tn { 
          286  +      for {set i 1} {$i <= 100} {incr i} {
          287  +        if {$i % 2} {
          288  +          set c1 sql1
          289  +            set c2 sql2
          290  +        } else {
          291  +          set c1 sql2
          292  +            set c2 sql1
          293  +        }
          294  +
          295  +        $c1 {
          296  +          INSERT INTO t1 VALUES( rblob(5000) );
          297  +          UPDATE t2 SET x = (SELECT md5sum(a) FROM t1);
          298  +        }
          299  +
          300  +        set res [$c2 { 
          301  +            SELECT count(*) FROM t1;
          302  +            SELECT x == (SELECT md5sum(a) FROM t1) FROM t2;
          303  +            PRAGMA integrity_check;
          304  +        }]
          305  +        if {$res != [list $i 1 ok]} {
          306  +          do_test $tn1.$tn.$i {
          307  +            set ::res
          308  +          } [list $i 1 ok]
          309  +        }
          310  +      }
          311  +      set res 1
          312  +    } {1}
          313  +  }
          314  +}
          315  +
          316  +
          317  +finish_test

Added test/mmap2.test.

            1  +# 2013 March 20
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file tests the effect of the mmap() or mremap() system calls 
           13  +# returning an error on the library. 
           14  +#
           15  +# If either mmap() or mremap() fails, SQLite should log an error 
           16  +# message, then continue accessing the database using read() and 
           17  +# write() exclusively.
           18  +#
           19  +
           20  +set testdir [file dirname $argv0]
           21  +source $testdir/tester.tcl
           22  +set testprefix mmap2
           23  +
           24  +if {$::tcl_platform(platform)!="unix" || [test_syscall defaultvfs] != "unix"} {
           25  +  finish_test
           26  +  return
           27  +}
           28  +ifcapable !mmap {
           29  +  finish_test
           30  +  return
           31  +}
           32  +
           33  +db close
           34  +sqlite3_shutdown
           35  +test_sqlite3_log xLog
           36  +proc xLog {error_code msg} {
           37  +  if {[string match os_unix.c* $msg]} {
           38  +    lappend ::log $msg 
           39  +  }
           40  +}
           41  +
           42  +foreach syscall {mmap mremap} {
           43  +  test_syscall uninstall 
           44  +  if {[catch {test_syscall install $syscall}]} continue
           45  +
           46  +  for {set i 1} {$i < 20} {incr i} {
           47  +    reset_db
           48  +
           49  +    test_syscall fault $i 1
           50  +    test_syscall errno $syscall ENOMEM
           51  +    set ::log ""
           52  +
           53  +    do_execsql_test 1.$syscall.$i.1 {
           54  +      CREATE TABLE t1(a, b, UNIQUE(a, b));
           55  +      INSERT INTO t1 VALUES(randomblob(1000), randomblob(1000));
           56  +      INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           57  +      INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           58  +      INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           59  +      INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           60  +      INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           61  +      INSERT INTO t1 SELECT randomblob(1000), randomblob(1000) FROM t1;
           62  +    }
           63  +
           64  +    set nFail [test_syscall fault 0 0]
           65  +
           66  +    do_execsql_test 1.$syscall.$i.2 {
           67  +      SELECT count(*) FROM t1;
           68  +      PRAGMA integrity_check;
           69  +    } {64 ok}
           70  +
           71  +    do_test 1.$syscall.$i.3 {
           72  +      expr {$nFail==0 || $nFail==1}
           73  +    } {1}
           74  +
           75  +    do_test 1.$syscall.$i.4.nFail=$nFail {
           76  +      regexp ".*${syscall}.*" $::log
           77  +    } [expr $nFail>0]
           78  +  }
           79  +}
           80  +
           81  +db close
           82  +test_syscall uninstall 
           83  +sqlite3_shutdown
           84  +test_sqlite3_log 
           85  +sqlite3_initialize
           86  +finish_test

Changes to test/pager1.test.

    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   source $testdir/lock_common.tcl
    16     16   source $testdir/malloc_common.tcl
    17     17   source $testdir/wal_common.tcl
           18  +set testprefix pager1
    18     19   
    19     20   # Do not use a codec for tests in this file, as the database file is
    20     21   # manipulated directly using tcl scripts (using the [hexio_write] command).
    21     22   #
    22     23   do_not_use_codec
    23     24   
    24     25   #
................................................................................
  1378   1379   
  1379   1380   #-------------------------------------------------------------------------
  1380   1381   # Test that regardless of the value returned by xSectorSize(), the
  1381   1382   # minimum effective sector-size is 512 and the maximum 65536 bytes.
  1382   1383   #
  1383   1384   testvfs tv -default 1
  1384   1385   foreach sectorsize {
         1386  +    16
  1385   1387       32   64   128   256   512   1024   2048 
  1386   1388       4096 8192 16384 32768 65536 131072 262144
  1387   1389   } {
  1388   1390     tv sectorsize $sectorsize
  1389   1391     tv devchar {}
  1390   1392     set eff $sectorsize
  1391   1393     if {$sectorsize < 512}   { set eff 512 }
................................................................................
  1400   1402         BEGIN;
  1401   1403           CREATE TABLE t1(a, b);
  1402   1404           CREATE TABLE t2(a, b);
  1403   1405           CREATE TABLE t3(a, b);
  1404   1406         COMMIT;
  1405   1407       }
  1406   1408       file size test.db-journal
  1407         -  } [expr $sectorsize > 65536 ? 65536 : $sectorsize]
         1409  +  } [expr $sectorsize > 65536 ? 65536 : ($sectorsize<32 ? 512 : $sectorsize)]
  1408   1410   
  1409   1411     do_test pager1-10.$sectorsize.2 {
  1410   1412       execsql { 
  1411   1413         INSERT INTO t3 VALUES(a_string(300), a_string(300));
  1412   1414         INSERT INTO t3 SELECT * FROM t3;        /*  2 */
  1413   1415         INSERT INTO t3 SELECT * FROM t3;        /*  4 */
  1414   1416         INSERT INTO t3 SELECT * FROM t3;        /*  8 */
................................................................................
  2239   2241         SAVEPOINT abc;
  2240   2242           CREATE TABLE t1(a, b);
  2241   2243         ROLLBACK TO abc;
  2242   2244       COMMIT;
  2243   2245     }
  2244   2246     db close
  2245   2247   } {}
  2246         -breakpoint
  2247   2248   do_test pager1-25-2 {
  2248   2249     faultsim_delete_and_reopen
  2249   2250     execsql {
  2250   2251       SAVEPOINT abc;
  2251   2252         CREATE TABLE t1(a, b);
  2252   2253       ROLLBACK TO abc;
  2253   2254       COMMIT;
................................................................................
  2518   2519     } {1 {disk I/O error}}
  2519   2520   
  2520   2521     do_test pager1-33.2 {
  2521   2522       file rename bak-journal test.db-journal
  2522   2523       execsql { SELECT * FROM t1 }
  2523   2524     } {one two}
  2524   2525   }
         2526  +
         2527  +#-------------------------------------------------------------------------
         2528  +# Test that appending pages to the database file then moving those pages
         2529  +# to the free-list before the transaction is committed does not cause
         2530  +# an error.
         2531  +#
         2532  +foreach {tn pragma strsize} {
         2533  +  1 { PRAGMA mmap_size = 0 } 2400
         2534  +  2 { }                       2400
         2535  +  3 { PRAGMA mmap_size = 0 } 4400
         2536  +  4 { }                       4400
         2537  +} {
         2538  +  reset_db
         2539  +  db func a_string a_string
         2540  +  db eval $pragma
         2541  +  do_execsql_test 34.$tn.1 {
         2542  +    CREATE TABLE t1(a, b);
         2543  +    INSERT INTO t1 VALUES(1, 2);
         2544  +  }
         2545  +  do_execsql_test 34.$tn.2 {
         2546  +    BEGIN;
         2547  +    INSERT INTO t1 VALUES(2, a_string($strsize));
         2548  +    DELETE FROM t1 WHERE oid=2;
         2549  +    COMMIT;
         2550  +    PRAGMA integrity_check;
         2551  +  } {ok}
         2552  +}
         2553  +
         2554  +#-------------------------------------------------------------------------
         2555  +#
         2556  +reset_db
         2557  +do_test 35 {
         2558  +  sqlite3 db test.db
         2559  +
         2560  +  execsql {
         2561  +    CREATE TABLE t1(x, y);
         2562  +    PRAGMA journal_mode = WAL;
         2563  +    INSERT INTO t1 VALUES(1, 2);
         2564  +  }
         2565  +
         2566  +  execsql {
         2567  +    BEGIN;
         2568  +      CREATE TABLE t2(a, b);
         2569  +  }
         2570  +
         2571  +  hexio_write test.db-shm [expr 16*1024] [string repeat 0055 8192]
         2572  +  catchsql ROLLBACK
         2573  +} {0 {}}
         2574  +
         2575  +do_multiclient_test tn {
         2576  +  sql1 {
         2577  +    PRAGMA auto_vacuum = 0;
         2578  +    CREATE TABLE t1(x, y);
         2579  +    INSERT INTO t1 VALUES(1, 2);
         2580  +  }
         2581  +
         2582  +  do_test 36.$tn.1 { 
         2583  +    sql2 { PRAGMA max_page_count = 2 }
         2584  +    list [catch { sql2 { CREATE TABLE t2(x) } } msg] $msg
         2585  +  } {1 {database or disk is full}}
         2586  +
         2587  +  sql1 { PRAGMA checkpoint_fullfsync = 1 }
         2588  +  sql1 { CREATE TABLE t2(x) }
         2589  +
         2590  +  do_test 36.$tn.2 { 
         2591  +    sql2 { INSERT INTO t2 VALUES('xyz') }
         2592  +    list [catch { sql2 { CREATE TABLE t3(x) } } msg] $msg
         2593  +  } {1 {database or disk is full}}
         2594  +}
         2595  +
         2596  +forcedelete test1 test2
         2597  +foreach {tn uri} {
         2598  +  1   {file:?mode=memory&cache=shared}
         2599  +  2   {file:one?mode=memory&cache=shared}
         2600  +  3   {file:test1?cache=shared}
         2601  +  4   {file:test2?another=parameter&yet=anotherone}
         2602  +} {
         2603  +  do_test 37.$tn {
         2604  +    catch { db close }
         2605  +    sqlite3_shutdown
         2606  +    sqlite3_config_uri 1
         2607  +    sqlite3 db $uri
         2608  +
         2609  +    db eval {
         2610  +      CREATE TABLE t1(x);
         2611  +      INSERT INTO t1 VALUES(1);
         2612  +      SELECT * FROM t1;
         2613  +    }
         2614  +  } {1}
         2615  +
         2616  +  do_execsql_test 37.$tn.2 {
         2617  +    VACUUM;
         2618  +    SELECT * FROM t1;
         2619  +  } {1}
         2620  +
         2621  +  db close
         2622  +  sqlite3_shutdown
         2623  +  sqlite3_config_uri 0
         2624  +}
         2625  +
         2626  +do_test 38.1 {
         2627  +  catch { db close }
         2628  +  forcedelete test.db
         2629  +  set fd [open test.db w]
         2630  +  puts $fd "hello world"
         2631  +  close $fd
         2632  +  sqlite3 db test.db
         2633  +  catchsql { CREATE TABLE t1(x) }
         2634  +} {1 {file is encrypted or is not a database}}
         2635  +do_test 38.2 {
         2636  +  catch { db close }
         2637  +  forcedelete test.db
         2638  +} {}
         2639  +
         2640  +do_test 39.1 {
         2641  +  sqlite3 db test.db
         2642  +  execsql {
         2643  +    PRAGMA auto_vacuum = 1;
         2644  +    CREATE TABLE t1(x);
         2645  +    INSERT INTO t1 VALUES('xxx');
         2646  +    INSERT INTO t1 VALUES('two');
         2647  +    INSERT INTO t1 VALUES(randomblob(400));
         2648  +    INSERT INTO t1 VALUES(randomblob(400));
         2649  +    INSERT INTO t1 VALUES(randomblob(400));
         2650  +    INSERT INTO t1 VALUES(randomblob(400));
         2651  +    BEGIN;
         2652  +    UPDATE t1 SET x = 'one' WHERE rowid=1;
         2653  +  }
         2654  +  set ::stmt [sqlite3_prepare db "SELECT * FROM t1 ORDER BY rowid" -1 dummy]
         2655  +  sqlite3_step $::stmt
         2656  +  sqlite3_column_text $::stmt 0
         2657  +} {one}
         2658  +do_test 39.2 {
         2659  +  execsql { CREATE TABLE t2(x) }
         2660  +  sqlite3_step $::stmt
         2661  +  sqlite3_column_text $::stmt 0
         2662  +} {two}
         2663  +do_test 39.3 {
         2664  +  sqlite3_finalize $::stmt
         2665  +  execsql COMMIT
         2666  +} {}
         2667  +
         2668  +do_execsql_test 39.4 {
         2669  +  PRAGMA auto_vacuum = 2;
         2670  +  CREATE TABLE t3(x);
         2671  +  CREATE TABLE t4(x);
         2672  +
         2673  +  DROP TABLE t2;
         2674  +  DROP TABLE t3;
         2675  +  DROP TABLE t4;
         2676  +}
         2677  +do_test 39.5 {
         2678  +  db close
         2679  +  sqlite3 db test.db
         2680  +  execsql {
         2681  +    PRAGMA cache_size = 1;
         2682  +    PRAGMA incremental_vacuum;
         2683  +    PRAGMA integrity_check;
         2684  +  }
         2685  +} {ok}
         2686  +
         2687  +do_test 40.1 {
         2688  +  reset_db
         2689  +  execsql {
         2690  +    PRAGMA auto_vacuum = 1;
         2691  +    CREATE TABLE t1(x PRIMARY KEY);
         2692  +    INSERT INTO t1 VALUES(randomblob(1200));
         2693  +    PRAGMA page_count;
         2694  +  }
         2695  +} {6}
         2696  +do_test 40.2 {
         2697  +  execsql {
         2698  +    INSERT INTO t1 VALUES(randomblob(1200));
         2699  +    INSERT INTO t1 VALUES(randomblob(1200));
         2700  +    INSERT INTO t1 VALUES(randomblob(1200));
         2701  +  }
         2702  +} {}
         2703  +do_test 40.3 {
         2704  +  db close
         2705  +  sqlite3 db test.db
         2706  +  execsql {
         2707  +    PRAGMA cache_size = 1;
         2708  +    CREATE TABLE t2(x);
         2709  +    PRAGMA integrity_check;
         2710  +  }
         2711  +} {ok}
         2712  +
         2713  +do_test 41.1 {
         2714  +  reset_db
         2715  +  execsql {
         2716  +    CREATE TABLE t1(x PRIMARY KEY);
         2717  +    INSERT INTO t1 VALUES(randomblob(200));
         2718  +    INSERT INTO t1 SELECT randomblob(200) FROM t1;
         2719  +    INSERT INTO t1 SELECT randomblob(200) FROM t1;
         2720  +    INSERT INTO t1 SELECT randomblob(200) FROM t1;
         2721  +    INSERT INTO t1 SELECT randomblob(200) FROM t1;
         2722  +    INSERT INTO t1 SELECT randomblob(200) FROM t1;
         2723  +    INSERT INTO t1 SELECT randomblob(200) FROM t1;
         2724  +  }
         2725  +} {}
         2726  +do_test 41.2 {
         2727  +  testvfs tv -default 1
         2728  +  tv sectorsize 16384;
         2729  +  tv devchar [list]
         2730  +  db close
         2731  +  sqlite3 db test.db
         2732  +  execsql {
         2733  +    PRAGMA cache_size = 1;
         2734  +    DELETE FROM t1 WHERE rowid%4;
         2735  +    PRAGMA integrity_check;
         2736  +  }
         2737  +} {ok}
         2738  +db close
         2739  +tv delete
         2740  +
         2741  +set pending_prev [sqlite3_test_control_pending_byte 0x1000000]
         2742  +do_test 42.1 {
         2743  +  reset_db
         2744  +  execsql {
         2745  +    CREATE TABLE t1(x, y);
         2746  +    INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
         2747  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2748  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2749  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2750  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2751  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2752  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2753  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2754  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2755  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2756  +  }
         2757  +  db close
         2758  +  sqlite3_test_control_pending_byte 0x0010000
         2759  +  sqlite3 db test.db
         2760  +  db eval { PRAGMA mmap_size = 0 }
         2761  +  catchsql { SELECT sum(length(y)) FROM t1 }
         2762  +} {1 {database disk image is malformed}}
         2763  +do_test 42.2 {
         2764  +  reset_db
         2765  +  execsql {
         2766  +    CREATE TABLE t1(x, y);
         2767  +    INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
         2768  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2769  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2770  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2771  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2772  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2773  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2774  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2775  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         2776  +  }
         2777  +  db close
         2778  +
         2779  +  testvfs tv -default 1
         2780  +  tv sectorsize 16384;
         2781  +  tv devchar [list]
         2782  +  sqlite3 db test.db -vfs tv
         2783  +  execsql { UPDATE t1 SET x = randomblob(200) }
         2784  +} {}
         2785  +db close
         2786  +tv delete
         2787  +sqlite3_test_control_pending_byte $pending_prev
         2788  +
         2789  +do_test 43.1 {
         2790  +  reset_db
         2791  +  execsql {
         2792  +    CREATE TABLE t1(x, y);
         2793  +    INSERT INTO t1 VALUES(1, 2);
         2794  +    CREATE TABLE t2(x, y);
         2795  +    INSERT INTO t2 VALUES(1, 2);
         2796  +    CREATE TABLE t3(x, y);
         2797  +    INSERT INTO t3 VALUES(1, 2);
         2798  +  }
         2799  +  db close
         2800  +  sqlite3 db test.db
         2801  +
         2802  +  db eval { PRAGMA mmap_size = 0 }
         2803  +  db eval { SELECT * FROM t1 }
         2804  +  sqlite3_db_status db CACHE_MISS 0
         2805  +} {0 2 0}
         2806  +
         2807  +do_test 43.2 {
         2808  +  db eval { SELECT * FROM t2 }
         2809  +  sqlite3_db_status db CACHE_MISS 1
         2810  +} {0 3 0}
         2811  +
         2812  +do_test 43.3 {
         2813  +  db eval { SELECT * FROM t3 }
         2814  +  sqlite3_db_status db CACHE_MISS 0
         2815  +} {0 1 0}
  2525   2816   
  2526   2817   finish_test
         2818  +

Changes to test/pager2.test.

   114    114     }
   115    115   }
   116    116   db close
   117    117   tv delete
   118    118   
   119    119   
   120    120   #-------------------------------------------------------------------------
   121         -#
   122    121   # pager2-2.1: Test a ROLLBACK with journal_mode=off.
   123    122   # pager2-2.2: Test shrinking the database (auto-vacuum) with 
   124    123   #             journal_mode=off
   125    124   #
   126    125   do_test pager2-2.1 {
   127    126     faultsim_delete_and_reopen
   128    127     execsql {
................................................................................
   143    142       CREATE TABLE t1(a, b);
   144    143       INSERT INTO t1 VALUES(zeroblob(5000), zeroblob(5000));
   145    144       DELETE FROM t1;
   146    145       PRAGMA incremental_vacuum;
   147    146     }
   148    147     file size test.db
   149    148   } {3072}
          149  +
          150  +#-------------------------------------------------------------------------
          151  +# Test that shared in-memory databases seem to work.
          152  +#
          153  +db close
          154  +do_test pager2-3.1 {
          155  +  forcedelete test.db
          156  +  sqlite3_shutdown
          157  +  sqlite3_config_uri 1
          158  +
          159  +  sqlite3 db1 {file:test.db?mode=memory&cache=shared}
          160  +  sqlite3 db2 {file:test.db?mode=memory&cache=shared}
          161  +  sqlite3 db3 test.db
          162  +
          163  +  db1 eval { CREATE TABLE t1(a, b) }
          164  +  db2 eval { INSERT INTO t1 VALUES(1, 2) }
          165  +  list [catch { db3 eval { INSERT INTO t1 VALUES(3, 4) } } msg] $msg
          166  +} {1 {no such table: t1}}
   150    167   
   151    168   finish_test

Changes to test/pagerfault.test.

  1242   1242   } -test {
  1243   1243     catchsql { UPDATE t2 SET a = a_string(800), b = a_string(800) }
  1244   1244     catch { close $::channel }
  1245   1245     catchsql { ROLLBACK }
  1246   1246     faultsim_integrity_check
  1247   1247   }
  1248   1248   
         1249  +
         1250  +#-------------------------------------------------------------------------
         1251  +#
         1252  +do_test pagerfault-28-pre {
         1253  +  faultsim_delete_and_reopen
         1254  +  db func a_string a_string
         1255  +  execsql {
         1256  +    PRAGMA page_size = 512;
         1257  +
         1258  +    PRAGMA journal_mode = wal;
         1259  +    PRAGMA wal_autocheckpoint = 0;
         1260  +    PRAGMA cache_size = 100000;
         1261  +
         1262  +    BEGIN;
         1263  +      CREATE TABLE t2(a UNIQUE, b UNIQUE);
         1264  +      INSERT INTO t2 VALUES( a_string(800), a_string(800) );
         1265  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1266  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1267  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1268  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1269  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1270  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1271  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1272  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1273  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1274  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1275  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1276  +    COMMIT;
         1277  +    CREATE TABLE t1(a PRIMARY KEY, b);
         1278  +  }
         1279  +  expr {[file size test.db-shm] >= 96*1024}
         1280  +} {1}
         1281  +faultsim_save_and_close
         1282  +
         1283  +do_faultsim_test pagerfault-28a -faults oom* -prep {
         1284  +  faultsim_restore_and_reopen
         1285  +  execsql { PRAGMA mmap_size=0 }
         1286  +
         1287  +  sqlite3 db2 test.db
         1288  +  db2 eval { SELECT count(*) FROM t2 }
         1289  +
         1290  +  db func a_string a_string
         1291  +  execsql { 
         1292  +    BEGIN;
         1293  +      INSERT INTO t1 VALUES(a_string(2000), a_string(2000));
         1294  +      INSERT INTO t1 VALUES(a_string(2000), a_string(2000));
         1295  +  }
         1296  +  set ::STMT [sqlite3_prepare db "SELECT * FROM t1 ORDER BY a" -1 DUMMY]
         1297  +  sqlite3_step $::STMT
         1298  +} -body {
         1299  +  execsql { ROLLBACK }
         1300  +} -test {
         1301  +  db2 close
         1302  +  sqlite3_finalize $::STMT
         1303  +  catchsql { ROLLBACK }
         1304  +  faultsim_integrity_check
         1305  +}
         1306  +
         1307  +faultsim_restore_and_reopen
         1308  +sqlite3 db2 test.db
         1309  +db2 eval {SELECT count(*) FROM t2}
         1310  +db close
         1311  +
         1312  +do_faultsim_test pagerfault-28b -faults oom* -prep {
         1313  +  sqlite3 db test.db
         1314  +} -body {
         1315  +  execsql { SELECT count(*) FROM t2 }
         1316  +} -test {
         1317  +  faultsim_test_result {0 2048}
         1318  +  db close
         1319  +}
         1320  +
         1321  +db2 close
         1322  +
         1323  +#-------------------------------------------------------------------------
         1324  +# Try this:
         1325  +#
         1326  +#    1) Put the pager in ERROR state (error during rollback)
         1327  +#
         1328  +#    2) Next time the connection is used inject errors into all xWrite() and
         1329  +#       xUnlock() calls. This causes the hot-journal rollback to fail and
         1330  +#       the pager to declare its locking state UNKNOWN.
         1331  +#
         1332  +#    3) Same again.
         1333  +#
         1334  +#    4a) Stop injecting errors. Allow the rollback to succeed. Check that
         1335  +#        the database is Ok. Or, 
         1336  +#
         1337  +#    4b) Close and reopen the db. Check that the db is Ok.
         1338  +#
         1339  +proc custom_injectinstall {} {
         1340  +  testvfs custom -default true
         1341  +  custom filter {xWrite xUnlock}
         1342  +}
         1343  +proc custom_injectuninstall {} {
         1344  +  catch {db  close}
         1345  +  catch {db2 close}
         1346  +  custom delete
         1347  +}
         1348  +proc custom_injectstart {iFail} {
         1349  +  custom ioerr $iFail 1
         1350  +}
         1351  +proc custom_injectstop {} {
         1352  +  custom ioerr
         1353  +}
         1354  +set ::FAULTSIM(custom)          [list      \
         1355  +  -injectinstall   custom_injectinstall    \
         1356  +  -injectstart     custom_injectstart      \
         1357  +  -injectstop      custom_injectstop       \
         1358  +  -injecterrlist   {{1 {disk I/O error}}}  \
         1359  +  -injectuninstall custom_injectuninstall  \
         1360  +]
         1361  +
         1362  +do_test pagerfault-29-pre {
         1363  +  faultsim_delete_and_reopen
         1364  +  db func a_string a_string
         1365  +  execsql {
         1366  +    PRAGMA page_size = 1024;
         1367  +    PRAGMA cache_size = 5;
         1368  +
         1369  +    BEGIN;
         1370  +      CREATE TABLE t2(a UNIQUE, b UNIQUE);
         1371  +      INSERT INTO t2 VALUES( a_string(800), a_string(800) );
         1372  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1373  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1374  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1375  +      INSERT INTO t2 SELECT a_string(800), a_string(800) FROM t2;
         1376  +    COMMIT;
         1377  +  }
         1378  +  expr {[file size test.db] >= 50*1024}
         1379  +} {1}
         1380  +faultsim_save_and_close
         1381  +foreach {tn tt} {
         1382  +  29 { catchsql ROLLBACK }
         1383  +  30 { db close ; sqlite3 db test.db }
         1384  +} {
         1385  +  do_faultsim_test pagerfault-$tn -faults custom -prep {
         1386  +    faultsim_restore_and_reopen
         1387  +      db func a_string a_string
         1388  +      execsql {
         1389  +        PRAGMA cache_size = 5;
         1390  +        BEGIN;
         1391  +        UPDATE t2 SET a = a_string(799);
         1392  +      }
         1393  +  } -body {
         1394  +    catchsql ROLLBACK
         1395  +    catchsql ROLLBACK
         1396  +    catchsql ROLLBACK
         1397  +  } -test {
         1398  +    eval $::tt
         1399  +    if {"ok" != [db one {PRAGMA integrity_check}]} {
         1400  +      error "integrity check failed"
         1401  +    }
         1402  +  }
         1403  +}
         1404  +
         1405  +do_test pagerfault-31-pre {
         1406  +  sqlite3_shutdown
         1407  +  sqlite3_config_uri 1
         1408  +} {SQLITE_OK}
         1409  +do_faultsim_test pagerfault-31 -faults oom* -body {
         1410  +  sqlite3 db {file:one?mode=memory&cache=shared}
         1411  +  db eval {
         1412  +    CREATE TABLE t1(x);
         1413  +    INSERT INTO t1 VALUES(1);
         1414  +    SELECT * FROM t1;
         1415  +  }
         1416  +} -test {
         1417  +  faultsim_test_result {0 1} {1 {}}
         1418  +  catch { db close }
         1419  +}
         1420  +sqlite3_shutdown
         1421  +sqlite3_config_uri 0
         1422  +
         1423  +do_test pagerfault-32-pre {
         1424  +  reset_db
         1425  +  execsql {
         1426  +    CREATE TABLE t1(x);
         1427  +    INSERT INTO t1 VALUES('one');
         1428  +  }
         1429  +} {}
         1430  +faultsim_save_and_close
         1431  +
         1432  +do_faultsim_test pagerfault-32 -prep {
         1433  +  faultsim_restore_and_reopen
         1434  +  db eval { SELECT * FROM t1; }
         1435  +} -body {
         1436  +  execsql { SELECT * FROM t1; }
         1437  +} -test {
         1438  +  faultsim_test_result {0 one}
         1439  +}
         1440  +sqlite3_shutdown
         1441  +sqlite3_config_uri 0
         1442  +
         1443  +do_faultsim_test pagerfault-33a -prep {
         1444  +  sqlite3 db :memory:
         1445  +  execsql {
         1446  +    CREATE TABLE t1(a, b);
         1447  +    INSERT INTO t1 VALUES(1, 2);
         1448  +  }
         1449  +} -body {
         1450  +  execsql { VACUUM }
         1451  +} -test {
         1452  +  faultsim_test_result {0 {}}
         1453  +} 
         1454  +do_faultsim_test pagerfault-33b -prep {
         1455  +  sqlite3 db ""
         1456  +  execsql {
         1457  +    CREATE TABLE t1(a, b);
         1458  +    INSERT INTO t1 VALUES(1, 2);
         1459  +  }
         1460  +} -body {
         1461  +  execsql { VACUUM }
         1462  +} -test {
         1463  +  faultsim_test_result {0 {}}
         1464  +} 
         1465  +
         1466  +do_test pagerfault-34-pre {
         1467  +  reset_db
         1468  +  execsql {
         1469  +    CREATE TABLE t1(x PRIMARY KEY);
         1470  +  }
         1471  +} {}
         1472  +faultsim_save_and_close
         1473  +do_faultsim_test pagerfault-34 -prep {
         1474  +  faultsim_restore_and_reopen
         1475  +  execsql {
         1476  +    BEGIN;
         1477  +      INSERT INTO t1 VALUES( randomblob(4000) );
         1478  +      DELETE FROM t1;
         1479  +  }
         1480  +} -body {
         1481  +  execsql COMMIT
         1482  +} -test {
         1483  +  faultsim_test_result {0 {}}
         1484  +} 
         1485  +
         1486  +do_test pagerfault-35-pre {
         1487  +  faultsim_delete_and_reopen
         1488  +  execsql {
         1489  +    CREATE TABLE t1(x PRIMARY KEY, y);
         1490  +    INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
         1491  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         1492  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         1493  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         1494  +  }
         1495  +  faultsim_save_and_close
         1496  +} {}
         1497  +testvfs tv -default 1
         1498  +tv sectorsize 8192;
         1499  +tv devchar [list]
         1500  +do_faultsim_test pagerfault-35 -prep {
         1501  +  faultsim_restore_and_reopen
         1502  +} -body {
         1503  +  execsql { UPDATE t1 SET x=randomblob(200) }
         1504  +} -test {
         1505  +  faultsim_test_result {0 {}}
         1506  +}
         1507  +catch {db close}
         1508  +tv delete
         1509  +
         1510  +sqlite3_shutdown
         1511  +sqlite3_config_uri 1
         1512  +do_test pagerfault-36-pre {
         1513  +  faultsim_delete_and_reopen
         1514  +  execsql {
         1515  +    CREATE TABLE t1(x PRIMARY KEY, y);
         1516  +    INSERT INTO t1 VALUES(randomblob(200), randomblob(200));
         1517  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         1518  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         1519  +    INSERT INTO t1 SELECT randomblob(200), randomblob(200) FROM t1;
         1520  +  }
         1521  +  faultsim_save_and_close
         1522  +} {}
         1523  +do_faultsim_test pagerfault-36 -prep {
         1524  +  faultsim_restore
         1525  +  sqlite3 db file:test.db?cache=shared
         1526  +  sqlite3 db2 file:test.db?cache=shared
         1527  +  db2 eval {
         1528  +    BEGIN;
         1529  +    SELECT count(*) FROM sqlite_master;
         1530  +  }
         1531  +  db eval {
         1532  +    PRAGMA cache_size = 1;
         1533  +    BEGIN;
         1534  +      UPDATE t1 SET x = randomblob(200);
         1535  +  }
         1536  +} -body {
         1537  +  execsql ROLLBACK db
         1538  +} -test {
         1539  +  catch { db eval {UPDATE t1 SET x = randomblob(200)} }
         1540  +  faultsim_test_result {0 {}}
         1541  +  catch { db close }
         1542  +  catch { db2 close }
         1543  +}
         1544  +
         1545  +sqlite3_shutdown
         1546  +sqlite3_config_uri 0
         1547  +
  1249   1548   finish_test
  1250   1549   

Changes to test/pageropt.test.

    83     83       SELECT hex(x) FROM t1
    84     84     }
    85     85   } [list 0 0 0 $blobcontent]
    86     86   
    87     87   # But if the other thread modifies the database, then the cache
    88     88   # must refill.
    89     89   #
           90  +ifcapable mmap {
           91  +  set x [expr {[permutation]=="mmap" ? 1 : 6}]
           92  +} else {
           93  +  set x 6
           94  +}
    90     95   do_test pageropt-1.5 {
    91     96     db2 eval {CREATE TABLE t2(y)}
    92     97     pagercount_sql {
    93     98       SELECT hex(x) FROM t1
    94     99     }
    95         -} [list 6 0 0 $blobcontent]
          100  +} [list $x 0 0 $blobcontent]
    96    101   do_test pageropt-1.6 {
    97    102     pagercount_sql {
    98    103       SELECT hex(x) FROM t1
    99    104     }
   100    105   } [list 0 0 0 $blobcontent]
   101    106   
   102    107   # Verify that the last page of an overflow chain is not read from

Changes to test/permutations.test.

   136    136   test_suite "veryquick" -prefix "" -description {
   137    137     "Very" quick test suite. Runs in less than 5 minutes on a workstation. 
   138    138     This test suite is the same as the "quick" tests, except that some files
   139    139     that test malloc and IO errors are omitted.
   140    140   } -files [
   141    141     test_set $allquicktests -exclude *malloc* *ioerr* *fault*
   142    142   ]
          143  +
          144  +test_suite "mmap" -prefix "mm-" -description {
          145  +  Similar to veryquick. Except with memory mapping disabled.
          146  +} -presql {
          147  +  pragma mmap_size = 268435456;
          148  +} -files [
          149  +  test_set $allquicktests -exclude *malloc* *ioerr* *fault* -include malloc.test
          150  +]
   143    151   
   144    152   test_suite "valgrind" -prefix "" -description {
   145    153     Run the "veryquick" test suite with a couple of multi-process tests (that
   146    154     fail under valgrind) omitted.
   147    155   } -files [
   148    156     test_set $allquicktests -exclude *malloc* *ioerr* *fault* wal.test atof1.test
   149    157   ] -initialize {

Added test/resolver01.test.

            1  +# 2013-04-13
            2  +#
            3  +# The author disclaims copyright to this source code. In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file tests features of the name resolver (the component that
           13  +# figures out what identifiers in the SQL statement refer to) that
           14  +# were fixed by ticket [2500cdb9be]
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +
           20  +do_test resolver01-1.1 {
           21  +  catchsql {
           22  +    CREATE TABLE t1(x, y); INSERT INTO t1 VALUES(11,22);
           23  +    CREATE TABLE t2(y, z); INSERT INTO t2 VALUES(33,44);
           24  +    SELECT 1 AS y FROM t1, t2 ORDER BY y;
           25  +  }
           26  +} {0 1}
           27  +do_test resolver01-1.2 {
           28  +  catchsql {
           29  +    SELECT 2 AS y FROM t1, t2 ORDER BY y COLLATE nocase;
           30  +  }
           31  +} {0 2}
           32  +do_test resolver01-1.3 {
           33  +  catchsql {
           34  +    SELECT 3 AS y FROM t1, t2 ORDER BY +y;
           35  +  }
           36  +} {0 3}
           37  +
           38  +
           39  +finish_test

Changes to test/speed1p.test.

    20     20   #sqlite3_config_scratch 29000 1
    21     21   set old_lookaside [sqlite3_config_lookaside 2048 300]
    22     22   #sqlite3_config_pagecache 1024 11000
    23     23   set testdir [file dirname $argv0]
    24     24   source $testdir/tester.tcl
    25     25   speed_trial_init speed1
    26     26   
           27  +sqlite3_memdebug_vfs_oom_test 0
           28  +
    27     29   # Set a uniform random seed
    28     30   expr srand(0)
    29     31   
    30     32   # The number_name procedure below converts its argment (an integer)
    31     33   # into a string which is the English-language name for that number.
    32     34   #
    33     35   # Example:
................................................................................
    73     75       CREATE INDEX i2a ON t2(a);
    74     76       CREATE INDEX i2b ON t2(b);
    75     77     }
    76     78     execsql {
    77     79       SELECT name FROM sqlite_master ORDER BY 1;
    78     80     }
    79     81   } {i2a i2b t1 t2}
    80         -
    81     82   
    82     83   # 50000 INSERTs on an unindexed table
    83     84   #
    84     85   set list {}
    85     86   for {set i 1} {$i<=50000} {incr i} {
    86     87     set r [expr {int(rand()*500000)}]
    87     88     set x [number_name $r]

Changes to test/syscall.test.

    56     56   #-------------------------------------------------------------------------
    57     57   # Tests for the xNextSystemCall method.
    58     58   #
    59     59   foreach s {
    60     60       open close access getcwd stat fstat ftruncate
    61     61       fcntl read pread write pwrite fchmod fallocate
    62     62       pread64 pwrite64 unlink openDirectory mkdir rmdir 
    63         -    statvfs fchown umask
           63  +    statvfs fchown umask mmap munmap mremap
    64     64   } {
    65     65     if {[test_syscall exists $s]} {lappend syscall_list $s}
    66     66   }
    67     67   do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list]
    68     68   
    69     69   #-------------------------------------------------------------------------
    70     70   # This test verifies that if a call to open() fails and errno is set to

Changes to test/sysfault.test.

   239    239       SELECT length(a) + length(b) FROM t1;
   240    240       COMMIT;
   241    241     }
   242    242   } -test {
   243    243     faultsim_test_result {0 20000}
   244    244   }
   245    245   
   246         -finish_test
          246  +#-------------------------------------------------------------------------
          247  +# Test errors in mmap().
          248  +#
          249  +proc vfsfault_install {} { 
          250  +  test_syscall reset
          251  +  test_syscall install {mmap}
          252  +}
          253  +
          254  +faultsim_delete_and_reopen
          255  +execsql {
          256  +  CREATE TABLE t1(a, b);
          257  +  INSERT INTO t1 VALUES(1, 2);
          258  +}
          259  +faultsim_save_and_close
          260  +
          261  +do_faultsim_test 4 -faults vfsfault-* -prep {
          262  +  faultsim_restore_and_reopen
          263  +  file_control_chunksize_test db main 8192
          264  +  execsql { 
          265  +    PRAGMA mmap_size = 1000000;
          266  +  }
          267  +} -body {
          268  +  test_syscall errno mmap     EACCES
          269  +
          270  +  execsql {
          271  +    SELECT * FROM t1;
          272  +  }
          273  +} -test {
          274  +  faultsim_test_result {0 {1 2}} {1 {disk I/O error}}
          275  +}
   247    276   
          277  +finish_test

Changes to test/tester.tcl.

   458    458   # counters in the parent interpreter.
   459    459   #
   460    460   if {0==[info exists ::SLAVE]} {
   461    461     set TC(errors)    0
   462    462     set TC(count)     0
   463    463     set TC(fail_list) [list]
   464    464     set TC(omit_list) [list]
          465  +  set TC(warn_list) [list]
   465    466   
   466    467     proc set_test_counter {counter args} {
   467    468       if {[llength $args]} {
   468    469         set ::TC($counter) [lindex $args 0]
   469    470       }
   470    471       set ::TC($counter)
   471    472     }
................................................................................
   491    492   
   492    493     set nFail [set_test_counter errors]
   493    494     if {$nFail>=$::cmdlinearg(maxerror)} {
   494    495       puts "*** Giving up..."
   495    496       finalize_testing
   496    497     }
   497    498   }
          499  +
          500  +# Remember a warning message to be displayed at the conclusion of all testing
          501  +#
          502  +proc warning {msg {append 1}} {
          503  +  puts "Warning: $msg"
          504  +  set warnList [set_test_counter warn_list]
          505  +  if {$append} {
          506  +    lappend warnList $msg
          507  +  }
          508  +  set_test_counter warn_list $warnList
          509  +}
          510  +
   498    511   
   499    512   # Increment the number of tests run
   500    513   #
   501    514   proc incr_ntest {} {
   502    515     set_test_counter count [expr [set_test_counter count] + 1]
   503    516   }
   504    517   
................................................................................
   785    798     sqlite3_soft_heap_limit 0
   786    799     set nTest [incr_ntest]
   787    800     set nErr [set_test_counter errors]
   788    801   
   789    802     puts "$nErr errors out of $nTest tests"
   790    803     if {$nErr>0} {
   791    804       puts "Failures on these tests: [set_test_counter fail_list]"
          805  +  }
          806  +  foreach warning [set_test_counter warn_list] {
          807  +    puts "Warning: $warning"
   792    808     }
   793    809     run_thread_tests 1
   794    810     if {[llength $omitList]>0} {
   795    811       puts "Omitted test cases:"
   796    812       set prec {}
   797    813       foreach {rec} [lsort $omitList] {
   798    814         if {$rec==$prec} continue

Changes to test/tkt2822.test.

   204    204     execsql {
   205    205       SELECT a AS "b" FROM t3 ORDER BY [B];
   206    206     }
   207    207   } {1 9}
   208    208   
   209    209   # In "ORDER BY +b" the term is now an expression rather than
   210    210   # a label.  It therefore matches by rule (3) instead of rule (2).
          211  +#
          212  +# 2013-04-13:  This is busted.  Changed to conform to PostgreSQL and
          213  +# MySQL and Oracle behavior.
   211    214   # 
   212    215   do_test tkt2822-5.5 {
   213    216     execsql {
   214    217       SELECT a AS b FROM t3 ORDER BY +b;
   215    218     }
   216         -} {9 1}
          219  +} {1 9}
   217    220   
   218    221   # Tests for rule 2 in compound queries
   219    222   #
   220    223   do_test tkt2822-6.1 {
   221    224     execsql {
   222    225       CREATE TABLE t6a(p,q);
   223    226       INSERT INTO t6a VALUES(1,8);

Changes to test/wal.test.

   723    723     list [expr [file size test.db]/1024] [file size test.db-wal]
   724    724   } [list 37 [wal_file_size 41 1024]]
   725    725   do_test wal-11.9 {
   726    726     db close
   727    727     list [expr [file size test.db]/1024] [log_deleted test.db-wal]
   728    728   } {37 1}
   729    729   sqlite3_wal db test.db
          730  +set nWal 39
          731  +if {[permutation]!="mmap"} {set nWal 37}
          732  +ifcapable !mmap {set nWal 37}
   730    733   do_test wal-11.10 {
   731    734     execsql {
   732    735       PRAGMA cache_size = 10;
   733    736       BEGIN;
   734    737         INSERT INTO t1 SELECT blob(900) FROM t1;   -- 32
   735    738         SELECT count(*) FROM t1;
   736    739     }
   737    740     list [expr [file size test.db]/1024] [file size test.db-wal]
   738         -} [list 37 [wal_file_size 37 1024]]
          741  +} [list 37 [wal_file_size $nWal 1024]]
   739    742   do_test wal-11.11 {
   740    743     execsql {
   741    744         SELECT count(*) FROM t1;
   742    745       ROLLBACK;
   743    746       SELECT count(*) FROM t1;
   744    747     }
   745    748   } {32 16}
   746    749   do_test wal-11.12 {
   747    750     list [expr [file size test.db]/1024] [file size test.db-wal]
   748         -} [list 37 [wal_file_size 37 1024]]
          751  +} [list 37 [wal_file_size $nWal 1024]]
   749    752   do_test wal-11.13 {
   750    753     execsql {
   751    754       INSERT INTO t1 VALUES( blob(900) );
   752    755       SELECT count(*) FROM t1;
   753    756       PRAGMA integrity_check;
   754    757     }
   755    758   } {17 ok}
   756    759   do_test wal-11.14 {
   757    760     list [expr [file size test.db]/1024] [file size test.db-wal]
   758         -} [list 37 [wal_file_size 37 1024]]
          761  +} [list 37 [wal_file_size $nWal 1024]]
   759    762   
   760    763   
   761    764   #-------------------------------------------------------------------------
   762    765   # This block of tests, wal-12.*, tests the fix for a problem that 
   763    766   # could occur if a log that is a prefix of an older log is written 
   764    767   # into a reused log file.
   765    768   #
................................................................................
  1508   1511     set ::log [list]
  1509   1512     faultsim_restore_and_reopen
  1510   1513     execsql { SELECT * FROM t1 }
  1511   1514   } {1 2 3 4}
  1512   1515   set nPage [expr 2+$AUTOVACUUM]
  1513   1516   do_test wal-23.4 { 
  1514   1517     set ::log 
  1515         -} [list SQLITE_OK "Recovered $nPage frames from WAL file $walfile"]
         1518  +} [list SQLITE_NOTICE "recovered $nPage frames from WAL file $walfile"]
  1516   1519   
  1517   1520   
  1518   1521   ifcapable autovacuum {
  1519   1522     # This block tests that if the size of a database is reduced by a 
  1520   1523     # transaction (because of an incremental or auto-vacuum), that no
  1521   1524     # data is written to the WAL file for the truncated pages as part
  1522   1525     # of the commit. e.g. if a transaction reduces the size of a database

Changes to test/wal5.test.

   231    231       } {}
   232    232       do_test 2.3.$tn.2 { file_page_counts } {1 3 1 3}
   233    233       do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2}
   234    234       do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {}
   235    235       do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {}
   236    236       do_test 2.3.$tn.6 { file_page_counts } {1 4 1 4}
   237    237       do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 4 3}
   238         -    do_test 2.3.$tn.8 { file_page_counts } {1 4 2 4}
          238  +
          239  +    # The checkpoint above only writes page 1 of the db file. The other
          240  +    # page (page 2) is locked by the read-transaction opened by the
          241  +    # [sql2] commmand above. So normally, the db is 1 page in size here.
          242  +    # However, in mmap() mode, the db is pre-allocated to 2 pages at the
          243  +    # start of the checkpoint, even though page 2 cannot be written.
          244  +    set nDb 2
          245  +    if {[permutation]!="mmap"} {set nDb 1}
          246  +    ifcapable !mmap {set nDb 1}
          247  +    do_test 2.3.$tn.8 { file_page_counts } [list $nDb 4 2 4]
   239    248     }
   240    249   
   241    250     # Check that checkpoints block on the correct locks. And respond correctly
   242    251     # if they cannot obtain those locks. There are three locks that a checkpoint
   243    252     # may block on (in the following order):
   244    253     #
   245    254     #   1. The writer lock: FULL and RESTART checkpoints block until any writer
................................................................................
   339    348   
   340    349       do_test 3.$tn.6 { code3 { do_wal_checkpoint db3 } } {0 0 0}
   341    350     }
   342    351   }
   343    352   
   344    353   
   345    354   finish_test
   346         -

Changes to test/walfault.test.

   544    544     }
   545    545   } -test {
   546    546     faultsim_test_result {0 {0 9 9}}
   547    547     faultsim_integrity_check
   548    548     set nRow [db eval {SELECT count(*) FROM abc}]
   549    549     if {!(($nRow==2 && $testrc) || $nRow==3)} { error "Bad db content" }
   550    550   }
   551         -finish_test
          551  +
          552  +#-------------------------------------------------------------------------
          553  +# Test fault-handling when switching out of exclusive-locking mode.
          554  +#
          555  +do_test walfault-14-pre {
          556  +  faultsim_delete_and_reopen
          557  +  execsql {
          558  +    PRAGMA auto_vacuum = 0;
          559  +    PRAGMA journal_mode = WAL;
          560  +    BEGIN;
          561  +      CREATE TABLE abc(a PRIMARY KEY);
          562  +      INSERT INTO abc VALUES(randomblob(1500));
          563  +      INSERT INTO abc VALUES(randomblob(1500));
          564  +    COMMIT;
          565  +  }
          566  +  faultsim_save_and_close
          567  +} {}
          568  +do_faultsim_test walfault-14 -prep {
          569  +  faultsim_restore_and_reopen
          570  +  breakpoint
          571  +  execsql {
          572  +    SELECT count(*) FROM abc;
          573  +    PRAGMA locking_mode = exclusive;
          574  +    BEGIN;
          575  +      INSERT INTO abc VALUES(randomblob(1500));
          576  +    COMMIT;
          577  +  }
          578  +} -body {
          579  +  db eval { 
          580  +    PRAGMA locking_mode = normal;
          581  +    BEGIN;
          582  +      INSERT INTO abc VALUES(randomblob(1500));
          583  +    COMMIT;
          584  +  }
          585  +} -test {
          586  +  faultsim_integrity_check
          587  +  set nRow [db eval {SELECT count(*) FROM abc}]
          588  +  if {$nRow!=3 && $nRow!=4} { error "Bad db content" }
          589  +}
   552    590   
   553    591   finish_test

Changes to test/win32lock.test.

    23     23   db close
    24     24   sqlite3_shutdown
    25     25   test_sqlite3_log xLog
    26     26   proc xLog {error_code msg} {
    27     27     lappend ::log $msg 
    28     28   }
    29     29   sqlite3 db test.db
           30  +db eval {PRAGMA mmap_size=0}
    30     31   
    31     32   do_test win32lock-1.1 {
    32     33     db eval {
    33     34       PRAGMA cache_size=10;
    34     35       CREATE TABLE t1(x,y);
    35     36       INSERT INTO t1 VALUES(1,randomblob(100000));
    36     37       INSERT INTO t1 VALUES(2,randomblob(50000));

Changes to tool/mksqlite3c.tcl.

   309    309      fts3.c
   310    310      fts3_aux.c
   311    311      fts3_expr.c
   312    312      fts3_hash.c
   313    313      fts3_porter.c
   314    314      fts3_tokenizer.c
   315    315      fts3_tokenizer1.c
          316  +   fts3_tokenize_vtab.c
   316    317      fts3_write.c
   317    318      fts3_snippet.c
   318    319      fts3_unicode.c
   319    320      fts3_unicode2.c
   320    321   
   321    322      rtree.c
   322    323      icu.c