/ Check-in [e65db42c]
Login

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

Overview
Comment:Merge updates from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | configReadOnly
Files: files | file ages | folders
SHA1:e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0
User & Date: mistachkin 2012-12-08 06:46:05
Context
2013-01-07
17:31
Merge updates from trunk. check-in: bf90f1fb user: mistachkin tags: configReadOnly
2012-12-08
06:46
Merge updates from trunk. check-in: e65db42c user: mistachkin tags: configReadOnly
2012-12-07
19:28
Ensure the VerifyCookie sub-routine has been run before the database is accessed in an obscure case. Fix for ticket [d6b36be38]. check-in: 2d5f37c9 user: dan tags: trunk
2012-10-16
23:08
Merge updates from trunk. check-in: f021559d user: mistachkin tags: configReadOnly
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

    41     41   
    42     42   # Compiler options needed for programs that use the TCL library.
    43     43   #
    44     44   TCC += @TCL_INCLUDE_SPEC@
    45     45   
    46     46   # The library that programs using TCL must link against.
    47     47   #
    48         -LIBTCL = @TCL_LIB_SPEC@ @TCL_LIBS@
           48  +LIBTCL = @TCL_LIB_SPEC@
    49     49   
    50     50   # Compiler options needed for programs that use the readline() library.
    51     51   #
    52     52   READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@
    53     53   
    54     54   # The library that programs using readline() must link against.
    55     55   #
................................................................................
   931    931   
   932    932   clean:	
   933    933   	rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
   934    934   	rm -f sqlite3.h opcodes.*
   935    935   	rm -rf .libs .deps
   936    936   	rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
   937    937   	rm -f mkkeywordhash$(BEXE) keywordhash.h
   938         -	rm -f $(PUBLISH)
   939    938   	rm -f *.da *.bb *.bbg gmon.out
   940    939   	rm -rf quota2a quota2b quota2c
   941    940   	rm -rf tsrc .target_source
   942    941   	rm -f tclsqlite3$(TEXE)
   943    942   	rm -f testfixture$(TEXE) test.db
   944    943   	rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
   945    944   	rm -f sqlite3.c
   946    945   	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
   947         -	rm -f sqlite-output.vsix
          946  +	rm -f sqlite-*-output.vsix
   948    947   
   949    948   distclean:	clean
   950    949   	rm -f config.log config.status libtool Makefile sqlite3.pc
   951    950   
   952    951   #
   953    952   # Windows section
   954    953   #

Changes to Makefile.msc.

   825    825   	$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl < tsrc\vdbe.c > vdbe.new
   826    826   	move vdbe.new tsrc\vdbe.c
   827    827   	echo > .target_source
   828    828   
   829    829   sqlite3.c:	.target_source $(TOP)\tool\mksqlite3c.tcl
   830    830   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl
   831    831   
   832         -sqlite3-all.c:	sqlite3.c $(TOP)/tool/split-sqlite3c.tcl
   833         -	$(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl
          832  +sqlite3-all.c:	sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
          833  +	$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
   834    834   
   835    835   # Rule to build the amalgamation
   836    836   #
   837    837   sqlite3.lo:	sqlite3.c
   838    838   	$(LTCOMPILE) -c sqlite3.c
   839    839   
   840    840   # Rules to build the LEMON compiler generator
................................................................................
  1243   1243   	del /Q .target_source
  1244   1244   	del /Q tclsqlite3.exe tclsqlite3.exp
  1245   1245   	del /Q testfixture.exe testfixture.exp test.db
  1246   1246   	del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
  1247   1247   	del /Q sqlite3.c
  1248   1248   	del /Q sqlite3rc.h
  1249   1249   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
  1250         -	del /Q sqlite-output.vsix
         1250  +	del /Q sqlite-*-output.vsix
  1251   1251   
  1252   1252   # Dynamic link library section.
  1253   1253   #
  1254   1254   dll: sqlite3.dll
  1255   1255   
  1256   1256   sqlite3.def: libsqlite3.lib
  1257   1257   	echo EXPORTS > sqlite3.def
  1258   1258   	dumpbin /all libsqlite3.lib \
  1259   1259   		| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
  1260   1260   		| sort >> sqlite3.def
  1261   1261   
  1262   1262   sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) sqlite3.def
  1263   1263   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)

Changes to configure.

   875    875   SQLITE_OS_UNIX
   876    876   SQLITE_OS_WIN
   877    877   SQLITE_OS_OS2
   878    878   TARGET_EXEEXT
   879    879   TCL_VERSION
   880    880   TCL_BIN_DIR
   881    881   TCL_SRC_DIR
   882         -TCL_LIBS
   883    882   TCL_INCLUDE_SPEC
   884    883   TCL_LIB_FILE
   885    884   TCL_LIB_FLAG
   886    885   TCL_LIB_SPEC
   887    886   TCL_STUB_LIB_FILE
   888    887   TCL_STUB_LIB_FLAG
   889    888   TCL_STUB_LIB_SPEC

Changes to configure.ac.

   497    497       eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
   498    498       eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
   499    499       eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
   500    500       
   501    501       AC_SUBST(TCL_VERSION)
   502    502       AC_SUBST(TCL_BIN_DIR)
   503    503       AC_SUBST(TCL_SRC_DIR)
   504         -    AC_SUBST(TCL_LIBS)
   505    504       AC_SUBST(TCL_INCLUDE_SPEC)
   506    505       
   507    506       AC_SUBST(TCL_LIB_FILE)
   508    507       AC_SUBST(TCL_LIB_FLAG)
   509    508       AC_SUBST(TCL_LIB_SPEC)
   510    509       
   511    510       AC_SUBST(TCL_STUB_LIB_FILE)

Changes to ext/async/README.txt.

            1  +NOTE (2012-11-29):
            2  +
            3  +The functionality implemented by this extension has been superseded
            4  +by WAL-mode.  This module is no longer supported or maintained.  The
            5  +code is retained for historical reference only.
            6  +
            7  +------------------------------------------------------------------------------
     1      8   
     2      9   Normally, when SQLite writes to a database file, it waits until the write
     3     10   operation is finished before returning control to the calling application.
     4     11   Since writing to the file-system is usually very slow compared with CPU
     5     12   bound operations, this can be a performance bottleneck. This directory
     6     13   contains an extension that causes SQLite to perform all write requests
     7     14   using a separate thread running in the background. Although this does not
................................................................................
   157    164       static void async_mutex_leave(int eMutex);
   158    165       static void async_cond_wait(int eCond, int eMutex);
   159    166       static void async_cond_signal(int eCond);
   160    167       static void async_sched_yield(void);
   161    168   
   162    169     The functionality required of each of the above functions is described
   163    170     in comments in sqlite3async.c.
   164         -

Changes to ext/async/sqlite3async.c.

  1506   1506           }
  1507   1507           break;
  1508   1508         }
  1509   1509   
  1510   1510         case ASYNC_DELETE:
  1511   1511           ASYNC_TRACE(("DELETE %s\n", p->zBuf));
  1512   1512           rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset);
         1513  +        if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
  1513   1514           break;
  1514   1515   
  1515   1516         case ASYNC_OPENEXCLUSIVE: {
  1516   1517           int flags = (int)p->iOffset;
  1517   1518           AsyncFileData *pData = p->pFileData;
  1518   1519           ASYNC_TRACE(("OPEN %s flags=%d\n", p->zBuf, (int)p->iOffset));
  1519   1520           assert(pData->pBaseRead->pMethods==0 && pData->pBaseWrite->pMethods==0);

Changes to ext/async/sqlite3async.h.

    71     71   /*
    72     72   ** This function unregisters the asynchronous IO VFS using 
    73     73   ** sqlite3_vfs_unregister().
    74     74   **
    75     75   ** On win32 platforms, this function also releases the small number of 
    76     76   ** critical section and event objects created by sqlite3async_initialize().
    77     77   */ 
    78         -void sqlite3async_shutdown();
           78  +void sqlite3async_shutdown(void);
    79     79   
    80     80   /*
    81     81   ** This function may only be called when the asynchronous IO VFS is 
    82     82   ** installed (after a call to sqlite3async_initialize()). It processes
    83     83   ** zero or more queued write operations before returning. It is expected
    84     84   ** (but not required) that this function will be called by a different 
    85     85   ** thread than those threads that use SQLite. The "background thread"
................................................................................
    90     90   ** verb to sqlite3async_control() (see below for details). By default
    91     91   ** this function never returns - it processes all pending operations and 
    92     92   ** then blocks waiting for new ones.
    93     93   **
    94     94   ** If multiple simultaneous calls are made to sqlite3async_run() from two
    95     95   ** or more threads, then the calls are serialized internally.
    96     96   */
    97         -void sqlite3async_run();
           97  +void sqlite3async_run(void);
    98     98   
    99     99   /*
   100    100   ** This function may only be called when the asynchronous IO VFS is 
   101    101   ** installed (after a call to sqlite3async_initialize()). It is used 
   102    102   ** to query or configure various parameters that affect the operation 
   103    103   ** of the asynchronous IO VFS. At present there are three parameters 
   104    104   ** supported:

Changes to ext/fts2/fts2_icu.c.

   114    114   
   115    115     if( nInput<0 ){
   116    116       nInput = strlen(zInput);
   117    117     }
   118    118     nChar = nInput+1;
   119    119     pCsr = (IcuCursor *)sqlite3_malloc(
   120    120         sizeof(IcuCursor) +                /* IcuCursor */
   121         -      nChar * sizeof(UChar) +            /* IcuCursor.aChar[] */
          121  +      ((nChar+3)&~3) * sizeof(UChar) +   /* IcuCursor.aChar[] */
   122    122         (nChar+1) * sizeof(int)            /* IcuCursor.aOffset[] */
   123    123     );
   124    124     if( !pCsr ){
   125    125       return SQLITE_NOMEM;
   126    126     }
   127    127     memset(pCsr, 0, sizeof(IcuCursor));
   128    128     pCsr->aChar = (UChar *)&pCsr[1];
   129         -  pCsr->aOffset = (int *)&pCsr->aChar[nChar];
          129  +  pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3];
   130    130   
   131    131     pCsr->aOffset[iOut] = iInput;
   132    132     U8_NEXT(zInput, iInput, nInput, c); 
   133    133     while( c>0 ){
   134    134       int isError = 0;
   135    135       c = u_foldCase(c, opt);
   136    136       U16_APPEND(pCsr->aChar, iOut, nChar, c, isError);

Changes to ext/fts3/fts3.c.

  4739   4739       char *aTmp;                   /* Temp space for PoslistNearMerge() */
  4740   4740   
  4741   4741       /* Allocate temporary working space. */
  4742   4742       for(p=pExpr; p->pLeft; p=p->pLeft){
  4743   4743         nTmp += p->pRight->pPhrase->doclist.nList;
  4744   4744       }
  4745   4745       nTmp += p->pPhrase->doclist.nList;
  4746         -    aTmp = sqlite3_malloc(nTmp*2);
  4747         -    if( !aTmp ){
  4748         -      *pRc = SQLITE_NOMEM;
         4746  +    if( nTmp==0 ){
  4749   4747         res = 0;
  4750   4748       }else{
  4751         -      char *aPoslist = p->pPhrase->doclist.pList;
  4752         -      int nToken = p->pPhrase->nToken;
  4753         -
  4754         -      for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
  4755         -        Fts3Phrase *pPhrase = p->pRight->pPhrase;
  4756         -        int nNear = p->nNear;
  4757         -        res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
  4758         -      }
  4759         -  
  4760         -      aPoslist = pExpr->pRight->pPhrase->doclist.pList;
  4761         -      nToken = pExpr->pRight->pPhrase->nToken;
  4762         -      for(p=pExpr->pLeft; p && res; p=p->pLeft){
  4763         -        int nNear;
  4764         -        Fts3Phrase *pPhrase;
  4765         -        assert( p->pParent && p->pParent->pLeft==p );
  4766         -        nNear = p->pParent->nNear;
  4767         -        pPhrase = (
  4768         -            p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
  4769         -        );
  4770         -        res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
         4749  +      aTmp = sqlite3_malloc(nTmp*2);
         4750  +      if( !aTmp ){
         4751  +        *pRc = SQLITE_NOMEM;
         4752  +        res = 0;
         4753  +      }else{
         4754  +        char *aPoslist = p->pPhrase->doclist.pList;
         4755  +        int nToken = p->pPhrase->nToken;
         4756  +
         4757  +        for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
         4758  +          Fts3Phrase *pPhrase = p->pRight->pPhrase;
         4759  +          int nNear = p->nNear;
         4760  +          res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
         4761  +        }
         4762  +
         4763  +        aPoslist = pExpr->pRight->pPhrase->doclist.pList;
         4764  +        nToken = pExpr->pRight->pPhrase->nToken;
         4765  +        for(p=pExpr->pLeft; p && res; p=p->pLeft){
         4766  +          int nNear;
         4767  +          Fts3Phrase *pPhrase;
         4768  +          assert( p->pParent && p->pParent->pLeft==p );
         4769  +          nNear = p->pParent->nNear;
         4770  +          pPhrase = (
         4771  +              p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
         4772  +              );
         4773  +          res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
         4774  +        }
  4771   4775         }
         4776  +
         4777  +      sqlite3_free(aTmp);
  4772   4778       }
  4773         -
  4774         -    sqlite3_free(aTmp);
  4775   4779     }
  4776   4780   
  4777   4781     return res;
  4778   4782   }
  4779   4783   
  4780   4784   /*
  4781   4785   ** This function is a helper function for fts3EvalTestDeferredAndNear().

Changes to ext/fts3/fts3_expr.c.

   181    181     sqlite3_tokenizer_cursor *pCursor;
   182    182     Fts3Expr *pRet = 0;
   183    183     int nConsumed = 0;
   184    184   
   185    185     rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
   186    186     if( rc==SQLITE_OK ){
   187    187       const char *zToken;
   188         -    int nToken, iStart, iEnd, iPosition;
          188  +    int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
   189    189       int nByte;                               /* total space to allocate */
   190    190   
   191    191       rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
   192    192       if( rc==SQLITE_OK ){
   193    193         nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
   194    194         pRet = (Fts3Expr *)fts3MallocZero(nByte);
   195    195         if( !pRet ){
................................................................................
   296    296     */
   297    297     rc = sqlite3Fts3OpenTokenizer(
   298    298         pTokenizer, pParse->iLangid, zInput, nInput, &pCursor);
   299    299     if( rc==SQLITE_OK ){
   300    300       int ii;
   301    301       for(ii=0; rc==SQLITE_OK; ii++){
   302    302         const char *zByte;
   303         -      int nByte, iBegin, iEnd, iPos;
          303  +      int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0;
   304    304         rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
   305    305         if( rc==SQLITE_OK ){
   306    306           Fts3PhraseToken *pToken;
   307    307   
   308    308           p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken));
   309    309           if( !p ) goto no_mem;
   310    310   

Changes to ext/fts3/fts3_icu.c.

   115    115       zInput = "";
   116    116     }else if( nInput<0 ){
   117    117       nInput = strlen(zInput);
   118    118     }
   119    119     nChar = nInput+1;
   120    120     pCsr = (IcuCursor *)sqlite3_malloc(
   121    121         sizeof(IcuCursor) +                /* IcuCursor */
   122         -      nChar * sizeof(UChar) +            /* IcuCursor.aChar[] */
          122  +      ((nChar+3)&~3) * sizeof(UChar) +   /* IcuCursor.aChar[] */
   123    123         (nChar+1) * sizeof(int)            /* IcuCursor.aOffset[] */
   124    124     );
   125    125     if( !pCsr ){
   126    126       return SQLITE_NOMEM;
   127    127     }
   128    128     memset(pCsr, 0, sizeof(IcuCursor));
   129    129     pCsr->aChar = (UChar *)&pCsr[1];
   130         -  pCsr->aOffset = (int *)&pCsr->aChar[nChar];
          130  +  pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3];
   131    131   
   132    132     pCsr->aOffset[iOut] = iInput;
   133    133     U8_NEXT(zInput, iInput, nInput, c); 
   134    134     while( c>0 ){
   135    135       int isError = 0;
   136    136       c = u_foldCase(c, opt);
   137    137       U16_APPEND(pCsr->aChar, iOut, nChar, c, isError);

Changes to ext/fts3/fts3_snippet.c.

   572    572         ** or more tokens in zDoc/nDoc.
   573    573         */
   574    574         rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC);
   575    575         if( rc!=SQLITE_OK ){
   576    576           return rc;
   577    577         }
   578    578         while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){
   579         -        const char *ZDUMMY; int DUMMY1, DUMMY2, DUMMY3;
          579  +        const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0;
   580    580           rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent);
   581    581         }
   582    582         pMod->xClose(pC);
   583    583         if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; }
   584    584   
   585    585         nShift = (rc==SQLITE_DONE)+iCurrent-nSnippet;
   586    586         assert( nShift<=nDesired );
................................................................................
   616    616     int iEnd = 0;                   /* Byte offset of end of current token */
   617    617     int isShiftDone = 0;            /* True after snippet is shifted */
   618    618     int iPos = pFragment->iPos;     /* First token of snippet */
   619    619     u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */
   620    620     int iCol = pFragment->iCol+1;   /* Query column to extract text from */
   621    621     sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */
   622    622     sqlite3_tokenizer_cursor *pC;   /* Tokenizer cursor open on zDoc/nDoc */
   623         -  const char *ZDUMMY;             /* Dummy argument used with tokenizer */
   624         -  int DUMMY1;                     /* Dummy argument used with tokenizer */
   625    623     
   626    624     zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol);
   627    625     if( zDoc==0 ){
   628    626       if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){
   629    627         return SQLITE_NOMEM;
   630    628       }
   631    629       return SQLITE_OK;
................................................................................
   636    634     pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule;
   637    635     rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC);
   638    636     if( rc!=SQLITE_OK ){
   639    637       return rc;
   640    638     }
   641    639   
   642    640     while( rc==SQLITE_OK ){
   643         -    int iBegin;                   /* Offset in zDoc of start of token */
   644         -    int iFin;                     /* Offset in zDoc of end of token */
   645         -    int isHighlight;              /* True for highlighted terms */
          641  +    const char *ZDUMMY;           /* Dummy argument used with tokenizer */
          642  +    int DUMMY1 = -1;              /* Dummy argument used with tokenizer */
          643  +    int iBegin = 0;               /* Offset in zDoc of start of token */
          644  +    int iFin = 0;                 /* Offset in zDoc of end of token */
          645  +    int isHighlight = 0;          /* True for highlighted terms */
   646    646   
          647  +    /* Variable DUMMY1 is initialized to a negative value above. Elsewhere
          648  +    ** in the FTS code the variable that the third argument to xNext points to
          649  +    ** is initialized to zero before the first (*but not necessarily
          650  +    ** subsequent*) call to xNext(). This is done for a particular application
          651  +    ** that needs to know whether or not the tokenizer is being used for
          652  +    ** snippet generation or for some other purpose.
          653  +    **
          654  +    ** Extreme care is required when writing code to depend on this
          655  +    ** initialization. It is not a documented part of the tokenizer interface.
          656  +    ** If a tokenizer is used directly by any code outside of FTS, this
          657  +    ** convention might not be respected.  */
   647    658       rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent);
   648    659       if( rc!=SQLITE_OK ){
   649    660         if( rc==SQLITE_DONE ){
   650    661           /* Special case - the last token of the snippet is also the last token
   651    662           ** of the column. Append any punctuation that occurred between the end
   652    663           ** of the previous token and the end of the document to the output. 
   653    664           ** Then break out of the loop. */
................................................................................
  1329   1340   */
  1330   1341   void sqlite3Fts3Offsets(
  1331   1342     sqlite3_context *pCtx,          /* SQLite function call context */
  1332   1343     Fts3Cursor *pCsr                /* Cursor object */
  1333   1344   ){
  1334   1345     Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
  1335   1346     sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule;
  1336         -  const char *ZDUMMY;             /* Dummy argument used with xNext() */
  1337         -  int NDUMMY;                     /* Dummy argument used with xNext() */
  1338   1347     int rc;                         /* Return Code */
  1339   1348     int nToken;                     /* Number of tokens in query */
  1340   1349     int iCol;                       /* Column currently being processed */
  1341   1350     StrBuffer res = {0, 0, 0};      /* Result string */
  1342   1351     TermOffsetCtx sCtx;             /* Context for fts3ExprTermOffsetInit() */
  1343   1352   
  1344   1353     if( !pCsr->pExpr ){
................................................................................
  1363   1372     sCtx.pCsr = pCsr;
  1364   1373   
  1365   1374     /* Loop through the table columns, appending offset information to 
  1366   1375     ** string-buffer res for each column.
  1367   1376     */
  1368   1377     for(iCol=0; iCol<pTab->nColumn; iCol++){
  1369   1378       sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */
  1370         -    int iStart;
  1371         -    int iEnd;
  1372         -    int iCurrent;
         1379  +    const char *ZDUMMY;           /* Dummy argument used with xNext() */
         1380  +    int NDUMMY = 0;               /* Dummy argument used with xNext() */
         1381  +    int iStart = 0;
         1382  +    int iEnd = 0;
         1383  +    int iCurrent = 0;
  1373   1384       const char *zDoc;
  1374   1385       int nDoc;
  1375   1386   
  1376   1387       /* Initialize the contents of sCtx.aTerm[] for column iCol. There is 
  1377   1388       ** no way that this operation can fail, so the return code from
  1378   1389       ** fts3ExprIterate() can be discarded.
  1379   1390       */

Changes to ext/fts3/fts3_tokenizer.c.

   247    247     int nName;
   248    248     const char *zInput;
   249    249     int nInput;
   250    250   
   251    251     const char *azArg[64];
   252    252   
   253    253     const char *zToken;
   254         -  int nToken;
   255         -  int iStart;
   256         -  int iEnd;
   257         -  int iPos;
          254  +  int nToken = 0;
          255  +  int iStart = 0;
          256  +  int iEnd = 0;
          257  +  int iPos = 0;
   258    258     int i;
   259    259   
   260    260     Tcl_Obj *pRet;
   261    261   
   262    262     if( argc<2 ){
   263    263       sqlite3_result_error(context, "insufficient arguments", -1);
   264    264       return;

Changes to ext/fts3/fts3_write.c.

   772    772   ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
   773    773   */
   774    774   static int fts3PendingTermsAdd(
   775    775     Fts3Table *p,                   /* Table into which text will be inserted */
   776    776     int iLangid,                    /* Language id to use */
   777    777     const char *zText,              /* Text of document to be inserted */
   778    778     int iCol,                       /* Column into which text is being inserted */
   779         -  u32 *pnWord                     /* OUT: Number of tokens inserted */
          779  +  u32 *pnWord                     /* IN/OUT: Incr. by number tokens inserted */
   780    780   ){
   781    781     int rc;
   782         -  int iStart;
   783         -  int iEnd;
   784         -  int iPos;
          782  +  int iStart = 0;
          783  +  int iEnd = 0;
          784  +  int iPos = 0;
   785    785     int nWord = 0;
   786    786   
   787    787     char const *zToken;
   788         -  int nToken;
          788  +  int nToken = 0;
   789    789   
   790    790     sqlite3_tokenizer *pTokenizer = p->pTokenizer;
   791    791     sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
   792    792     sqlite3_tokenizer_cursor *pCsr;
   793    793     int (*xNext)(sqlite3_tokenizer_cursor *pCursor,
   794    794         const char**,int*,int*,int*,int*);
   795    795   
................................................................................
   836    836         rc = fts3PendingTermsAddOne(
   837    837             p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix
   838    838         );
   839    839       }
   840    840     }
   841    841   
   842    842     pModule->xClose(pCsr);
   843         -  *pnWord = nWord;
          843  +  *pnWord += nWord;
   844    844     return (rc==SQLITE_DONE ? SQLITE_OK : rc);
   845    845   }
   846    846   
   847    847   /* 
   848    848   ** Calling this function indicates that subsequent calls to 
   849    849   ** fts3PendingTermsAdd() are to add term/position-list pairs for the
   850    850   ** contents of the document with docid iDocid.
................................................................................
  1040   1040   ** (an integer) of a row about to be deleted. Remove all terms from the
  1041   1041   ** full-text index.
  1042   1042   */
  1043   1043   static void fts3DeleteTerms( 
  1044   1044     int *pRC,               /* Result code */
  1045   1045     Fts3Table *p,           /* The FTS table to delete from */
  1046   1046     sqlite3_value *pRowid,  /* The docid to be deleted */
  1047         -  u32 *aSz                /* Sizes of deleted document written here */
         1047  +  u32 *aSz,               /* Sizes of deleted document written here */
         1048  +  int *pbFound            /* OUT: Set to true if row really does exist */
  1048   1049   ){
  1049   1050     int rc;
  1050   1051     sqlite3_stmt *pSelect;
  1051   1052   
         1053  +  assert( *pbFound==0 );
  1052   1054     if( *pRC ) return;
  1053   1055     rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
  1054   1056     if( rc==SQLITE_OK ){
  1055   1057       if( SQLITE_ROW==sqlite3_step(pSelect) ){
  1056   1058         int i;
  1057   1059         int iLangid = langidFromSelect(p, pSelect);
  1058   1060         rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
................................................................................
  1062   1064           aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
  1063   1065         }
  1064   1066         if( rc!=SQLITE_OK ){
  1065   1067           sqlite3_reset(pSelect);
  1066   1068           *pRC = rc;
  1067   1069           return;
  1068   1070         }
         1071  +      *pbFound = 1;
  1069   1072       }
  1070   1073       rc = sqlite3_reset(pSelect);
  1071   1074     }else{
  1072   1075       sqlite3_reset(pSelect);
  1073   1076     }
  1074   1077     *pRC = rc;
  1075   1078   }
................................................................................
  3286   3289         }
  3287   3290       }
  3288   3291   
  3289   3292       while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
  3290   3293         int iCol;
  3291   3294         int iLangid = langidFromSelect(p, pStmt);
  3292   3295         rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
  3293         -      aSz[p->nColumn] = 0;
         3296  +      memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
  3294   3297         for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
  3295   3298           const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
  3296   3299           rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
  3297   3300           aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
  3298   3301         }
  3299   3302         if( p->bHasDocsize ){
  3300   3303           fts3InsertDocsize(&rc, p, aSz);
................................................................................
  4930   4933           const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
  4931   4934           int nText = sqlite3_column_bytes(pStmt, iCol+1);
  4932   4935           sqlite3_tokenizer_cursor *pT = 0;
  4933   4936   
  4934   4937           rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
  4935   4938           while( rc==SQLITE_OK ){
  4936   4939             char const *zToken;       /* Buffer containing token */
  4937         -          int nToken;               /* Number of bytes in token */
  4938         -          int iDum1, iDum2;         /* Dummy variables */
  4939         -          int iPos;                 /* Position of token in zText */
         4940  +          int nToken = 0;           /* Number of bytes in token */
         4941  +          int iDum1 = 0, iDum2 = 0; /* Dummy variables */
         4942  +          int iPos = 0;             /* Position of token in zText */
  4940   4943   
  4941   4944             rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
  4942   4945             if( rc==SQLITE_OK ){
  4943   4946               int i;
  4944   4947               cksum2 = cksum2 ^ fts3ChecksumEntry(
  4945   4948                   zToken, nToken, iLang, 0, iDocid, iCol, iPos
  4946   4949               );
................................................................................
  5099   5102       for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){
  5100   5103         const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
  5101   5104         sqlite3_tokenizer_cursor *pTC = 0;
  5102   5105     
  5103   5106         rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
  5104   5107         while( rc==SQLITE_OK ){
  5105   5108           char const *zToken;       /* Buffer containing token */
  5106         -        int nToken;               /* Number of bytes in token */
  5107         -        int iDum1, iDum2;         /* Dummy variables */
  5108         -        int iPos;                 /* Position of token in zText */
         5109  +        int nToken = 0;           /* Number of bytes in token */
         5110  +        int iDum1 = 0, iDum2 = 0; /* Dummy variables */
         5111  +        int iPos = 0;             /* Position of token in zText */
  5109   5112     
  5110   5113           rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
  5111   5114           for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
  5112   5115             Fts3PhraseToken *pPT = pDef->pToken;
  5113   5116             if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
  5114   5117              && (pPT->bFirst==0 || iPos==0)
  5115   5118              && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
................................................................................
  5190   5193   ** SQLite value pRowid contains the rowid of a row that may or may not be
  5191   5194   ** present in the FTS3 table. If it is, delete it and adjust the contents
  5192   5195   ** of subsiduary data structures accordingly.
  5193   5196   */
  5194   5197   static int fts3DeleteByRowid(
  5195   5198     Fts3Table *p, 
  5196   5199     sqlite3_value *pRowid, 
  5197         -  int *pnDoc,
         5200  +  int *pnChng,                    /* IN/OUT: Decrement if row is deleted */
  5198   5201     u32 *aSzDel
  5199   5202   ){
  5200         -  int isEmpty = 0;
  5201         -  int rc = fts3IsEmpty(p, pRowid, &isEmpty);
  5202         -  if( rc==SQLITE_OK ){
  5203         -    if( isEmpty ){
  5204         -      /* Deleting this row means the whole table is empty. In this case
  5205         -      ** delete the contents of all three tables and throw away any
  5206         -      ** data in the pendingTerms hash table.  */
  5207         -      rc = fts3DeleteAll(p, 1);
  5208         -      *pnDoc = *pnDoc - 1;
  5209         -    }else{
  5210         -      fts3DeleteTerms(&rc, p, pRowid, aSzDel);
  5211         -      if( p->zContentTbl==0 ){
  5212         -        fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
  5213         -        if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
         5203  +  int rc = SQLITE_OK;             /* Return code */
         5204  +  int bFound = 0;                 /* True if *pRowid really is in the table */
         5205  +
         5206  +  fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound);
         5207  +  if( bFound && rc==SQLITE_OK ){
         5208  +    int isEmpty = 0;              /* Deleting *pRowid leaves the table empty */
         5209  +    rc = fts3IsEmpty(p, pRowid, &isEmpty);
         5210  +    if( rc==SQLITE_OK ){
         5211  +      if( isEmpty ){
         5212  +        /* Deleting this row means the whole table is empty. In this case
         5213  +        ** delete the contents of all three tables and throw away any
         5214  +        ** data in the pendingTerms hash table.  */
         5215  +        rc = fts3DeleteAll(p, 1);
         5216  +        *pnChng = 0;
         5217  +        memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2);
  5214   5218         }else{
  5215         -        *pnDoc = *pnDoc - 1;
  5216         -      }
  5217         -      if( p->bHasDocsize ){
  5218         -        fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
         5219  +        *pnChng = *pnChng - 1;
         5220  +        if( p->zContentTbl==0 ){
         5221  +          fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
         5222  +        }
         5223  +        if( p->bHasDocsize ){
         5224  +          fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
         5225  +        }
  5219   5226         }
  5220   5227       }
  5221   5228     }
  5222   5229   
  5223   5230     return rc;
  5224   5231   }
  5225   5232   
................................................................................
  5242   5249     sqlite3_value **apVal,          /* Array of arguments */
  5243   5250     sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
  5244   5251   ){
  5245   5252     Fts3Table *p = (Fts3Table *)pVtab;
  5246   5253     int rc = SQLITE_OK;             /* Return Code */
  5247   5254     int isRemove = 0;               /* True for an UPDATE or DELETE */
  5248   5255     u32 *aSzIns = 0;                /* Sizes of inserted documents */
  5249         -  u32 *aSzDel;                    /* Sizes of deleted documents */
         5256  +  u32 *aSzDel = 0;                /* Sizes of deleted documents */
  5250   5257     int nChng = 0;                  /* Net change in number of documents */
  5251   5258     int bInsertDone = 0;
  5252   5259   
  5253   5260     assert( p->pSegments==0 );
  5254   5261     assert( 
  5255   5262         nArg==1                     /* DELETE operations */
  5256   5263      || nArg==(2 + p->nColumn + 3)  /* INSERT or UPDATE operations */
................................................................................
  5270   5277   
  5271   5278     if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){
  5272   5279       rc = SQLITE_CONSTRAINT;
  5273   5280       goto update_out;
  5274   5281     }
  5275   5282   
  5276   5283     /* Allocate space to hold the change in document sizes */
  5277         -  aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 );
  5278         -  if( aSzIns==0 ){
         5284  +  aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
         5285  +  if( aSzDel==0 ){
  5279   5286       rc = SQLITE_NOMEM;
  5280   5287       goto update_out;
  5281   5288     }
  5282         -  aSzDel = &aSzIns[p->nColumn+1];
  5283         -  memset(aSzIns, 0, sizeof(aSzIns[0])*(p->nColumn+1)*2);
         5289  +  aSzIns = &aSzDel[p->nColumn+1];
         5290  +  memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
  5284   5291   
  5285   5292     /* If this is an INSERT operation, or an UPDATE that modifies the rowid
  5286   5293     ** value, then this operation requires constraint handling.
  5287   5294     **
  5288   5295     ** If the on-conflict mode is REPLACE, this means that the existing row
  5289   5296     ** should be deleted from the database before inserting the new row. Or,
  5290   5297     ** if the on-conflict mode is other than REPLACE, then this method must
................................................................................
  5361   5368     }
  5362   5369   
  5363   5370     if( p->bFts4 ){
  5364   5371       fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng);
  5365   5372     }
  5366   5373   
  5367   5374    update_out:
  5368         -  sqlite3_free(aSzIns);
         5375  +  sqlite3_free(aSzDel);
  5369   5376     sqlite3Fts3SegmentsClose(p);
  5370   5377     return rc;
  5371   5378   }
  5372   5379   
  5373   5380   /* 
  5374   5381   ** Flush any data in the pending-terms hash table to disk. If successful,
  5375   5382   ** merge all segments in the database (including the new segment, if 

Changes to main.mk.

   253    253     $(TOP)/src/test_osinst.c \
   254    254     $(TOP)/src/test_pcache.c \
   255    255     $(TOP)/src/test_quota.c \
   256    256     $(TOP)/src/test_rtree.c \
   257    257     $(TOP)/src/test_schema.c \
   258    258     $(TOP)/src/test_server.c \
   259    259     $(TOP)/src/test_stat.c \
          260  +  $(TOP)/src/test_sqllog.c \
   260    261     $(TOP)/src/test_superlock.c \
   261    262     $(TOP)/src/test_syscall.c \
   262    263     $(TOP)/src/test_tclvar.c \
   263    264     $(TOP)/src/test_thread.c \
   264    265     $(TOP)/src/test_vfs.c \
   265    266     $(TOP)/src/test_wholenumber.c \
   266    267     $(TOP)/src/test_wsd.c
................................................................................
   542    543   #
   543    544   TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
   544    545   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
   545    546   
   546    547   testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
   547    548   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   548    549   		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   549         -		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
          550  +		-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
   550    551   
   551    552   amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   552    553   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   553    554   		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                  \
   554    555   		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   555    556   
   556    557   fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
................................................................................
   615    616   	rm -f testloadext.dll libtestloadext.so
   616    617   	rm -f amalgamation-testfixture amalgamation-testfixture.exe
   617    618   	rm -f fts3-testfixture fts3-testfixture.exe
   618    619   	rm -f testfixture testfixture.exe
   619    620   	rm -f threadtest3 threadtest3.exe
   620    621   	rm -f sqlite3.c fts?amal.c tclsqlite3.c
   621    622   	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
   622         -	rm -f sqlite-output.vsix
          623  +	rm -f sqlite-*-output.vsix

Changes to src/attach.c.

   467    467     for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
   468    468       if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
   469    469         sqlite3ErrorMsg(pFix->pParse,
   470    470            "%s %T cannot reference objects in database %s",
   471    471            pFix->zType, pFix->pName, pItem->zDatabase);
   472    472         return 1;
   473    473       }
   474         -    sqlite3_free(pItem->zDatabase);
          474  +    sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
   475    475       pItem->zDatabase = 0;
   476    476       pItem->pSchema = pFix->pSchema;
   477    477   #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
   478    478       if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
   479    479       if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
   480    480   #endif
   481    481     }

Changes to src/btree.c.

  5740   5740     Pgno pgnoNew;                        /* Page number of pNew */
  5741   5741   
  5742   5742     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  5743   5743     assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  5744   5744     assert( pPage->nOverflow==1 );
  5745   5745   
  5746   5746     /* This error condition is now caught prior to reaching this function */
  5747         -  if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
         5747  +  if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
  5748   5748   
  5749   5749     /* Allocate a new page. This page will become the right-sibling of 
  5750   5750     ** pPage. Make the parent page writable, so that the new divider cell
  5751   5751     ** may be inserted. If both these operations are successful, proceed.
  5752   5752     */
  5753   5753     rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
  5754   5754   

Changes to src/build.c.

   123    123   ** Note that if an error occurred, it might be the case that
   124    124   ** no VDBE code was generated.
   125    125   */
   126    126   void sqlite3FinishCoding(Parse *pParse){
   127    127     sqlite3 *db;
   128    128     Vdbe *v;
   129    129   
          130  +  assert( pParse->pToplevel==0 );
   130    131     db = pParse->db;
   131    132     if( db->mallocFailed ) return;
   132    133     if( pParse->nested ) return;
   133    134     if( pParse->nErr ) return;
   134    135   
   135    136     /* Begin by generating some termination code at the end of the
   136    137     ** vdbe program
................................................................................
  3585   3586   ** If iDb<0 then code the OP_Goto only - don't set flag to verify the
  3586   3587   ** schema on any databases.  This can be used to position the OP_Goto
  3587   3588   ** early in the code, before we know if any database tables will be used.
  3588   3589   */
  3589   3590   void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  3590   3591     Parse *pToplevel = sqlite3ParseToplevel(pParse);
  3591   3592   
         3593  +#ifndef SQLITE_OMIT_TRIGGER
         3594  +  if( pToplevel!=pParse ){
         3595  +    /* This branch is taken if a trigger is currently being coded. In this
         3596  +    ** case, set cookieGoto to a non-zero value to show that this function
         3597  +    ** has been called. This is used by the sqlite3ExprCodeConstants()
         3598  +    ** function. */
         3599  +    pParse->cookieGoto = -1;
         3600  +  }
         3601  +#endif
  3592   3602     if( pToplevel->cookieGoto==0 ){
  3593   3603       Vdbe *v = sqlite3GetVdbe(pToplevel);
  3594   3604       if( v==0 ) return;  /* This only happens if there was a prior error */
  3595   3605       pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
  3596   3606     }
  3597   3607     if( iDb>=0 ){
  3598   3608       sqlite3 *db = pToplevel->db;

Changes to src/delete.c.

   108    108         pFrom->a[0].pSelect = pDup;
   109    109         assert( pFrom->a[0].pOn==0 );
   110    110         assert( pFrom->a[0].pUsing==0 );
   111    111       }else{
   112    112         sqlite3SelectDelete(db, pDup);
   113    113       }
   114    114       pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
          115  +    if( pDup ) pDup->selFlags |= SF_Materialize;
   115    116     }
   116    117     sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
   117    118     sqlite3Select(pParse, pDup, &dest);
   118    119     sqlite3SelectDelete(db, pDup);
   119    120   }
   120    121   #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
   121    122   

Changes to src/expr.c.

   935    935       pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
   936    936       pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
   937    937       pNewItem->jointype = pOldItem->jointype;
   938    938       pNewItem->iCursor = pOldItem->iCursor;
   939    939       pNewItem->addrFillSub = pOldItem->addrFillSub;
   940    940       pNewItem->regReturn = pOldItem->regReturn;
   941    941       pNewItem->isCorrelated = pOldItem->isCorrelated;
          942  +    pNewItem->viaCoroutine = pOldItem->viaCoroutine;
   942    943       pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
   943    944       pNewItem->notIndexed = pOldItem->notIndexed;
   944    945       pNewItem->pIndex = pOldItem->pIndex;
   945    946       pTab = pNewItem->pTab = pOldItem->pTab;
   946    947       if( pTab ){
   947    948         pTab->nRef++;
   948    949       }
................................................................................
  4025   4026           }
  4026   4027           /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
  4027   4028           */
  4028   4029           assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
  4029   4030           ExprSetIrreducible(pExpr);
  4030   4031           pExpr->iAgg = (i16)i;
  4031   4032           pExpr->pAggInfo = pAggInfo;
         4033  +        return WRC_Prune;
         4034  +      }else{
         4035  +        return WRC_Continue;
  4032   4036         }
  4033         -      return WRC_Prune;
  4034   4037       }
  4035   4038     }
  4036   4039     return WRC_Continue;
  4037   4040   }
  4038   4041   static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
  4039   4042     UNUSED_PARAMETER(pWalker);
  4040   4043     UNUSED_PARAMETER(pSelect);
  4041   4044     return WRC_Continue;
  4042   4045   }
  4043   4046   
  4044   4047   /*
  4045         -** Analyze the given expression looking for aggregate functions and
  4046         -** for variables that need to be added to the pParse->aAgg[] array.
  4047         -** Make additional entries to the pParse->aAgg[] array as necessary.
         4048  +** Analyze the pExpr expression looking for aggregate functions and
         4049  +** for variables that need to be added to AggInfo object that pNC->pAggInfo
         4050  +** points to.  Additional entries are made on the AggInfo object as
         4051  +** necessary.
  4048   4052   **
  4049   4053   ** This routine should only be called after the expression has been
  4050   4054   ** analyzed by sqlite3ResolveExprNames().
  4051   4055   */
  4052   4056   void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
  4053   4057     Walker w;
  4054   4058     memset(&w, 0, sizeof(w));

Changes to src/func.c.

   163    163         double rVal = sqlite3_value_double(argv[0]);
   164    164         if( rVal<0 ) rVal = -rVal;
   165    165         sqlite3_result_double(context, rVal);
   166    166         break;
   167    167       }
   168    168     }
   169    169   }
          170  +
          171  +/*
          172  +** Implementation of the instr() function.
          173  +**
          174  +** instr(haystack,needle) finds the first occurrence of needle
          175  +** in haystack and returns the number of previous characters plus 1,
          176  +** or 0 if needle does not occur within haystack.
          177  +**
          178  +** If both haystack and needle are BLOBs, then the result is one more than
          179  +** the number of bytes in haystack prior to the first occurrence of needle,
          180  +** or 0 if needle never occurs in haystack.
          181  +*/
          182  +static void instrFunc(
          183  +  sqlite3_context *context,
          184  +  int argc,
          185  +  sqlite3_value **argv
          186  +){
          187  +  const unsigned char *zHaystack;
          188  +  const unsigned char *zNeedle;
          189  +  int nHaystack;
          190  +  int nNeedle;
          191  +  int typeHaystack, typeNeedle;
          192  +  int N = 1;
          193  +  int isText;
          194  +
          195  +  UNUSED_PARAMETER(argc);
          196  +  typeHaystack = sqlite3_value_type(argv[0]);
          197  +  typeNeedle = sqlite3_value_type(argv[1]);
          198  +  if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
          199  +  nHaystack = sqlite3_value_bytes(argv[0]);
          200  +  nNeedle = sqlite3_value_bytes(argv[1]);
          201  +  if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
          202  +    zHaystack = sqlite3_value_blob(argv[0]);
          203  +    zNeedle = sqlite3_value_blob(argv[1]);
          204  +    isText = 0;
          205  +  }else{
          206  +    zHaystack = sqlite3_value_text(argv[0]);
          207  +    zNeedle = sqlite3_value_text(argv[1]);
          208  +    isText = 1;
          209  +  }
          210  +  while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
          211  +    N++;
          212  +    do{
          213  +      nHaystack--;
          214  +      zHaystack++;
          215  +    }while( isText && (zHaystack[0]&0xc0)==0x80 );
          216  +  }
          217  +  if( nNeedle>nHaystack ) N = 0;
          218  +  sqlite3_result_int(context, N);
          219  +}
   170    220   
   171    221   /*
   172    222   ** Implementation of the substr() function.
   173    223   **
   174    224   ** substr(x,p1,p2)  returns p2 characters of x[] beginning with p1.
   175    225   ** p1 is 1-indexed.  So substr(x,1,1) returns the first character
   176    226   ** of x.  If x is text, then we actually count UTF-8 characters.
................................................................................
  1532   1582       FUNCTION(min,                0, 0, 1, 0                ),
  1533   1583       AGGREGATE(min,               1, 0, 1, minmaxStep,      minMaxFinalize ),
  1534   1584       FUNCTION(max,               -1, 1, 1, minmaxFunc       ),
  1535   1585       FUNCTION(max,                0, 1, 1, 0                ),
  1536   1586       AGGREGATE(max,               1, 1, 1, minmaxStep,      minMaxFinalize ),
  1537   1587       FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
  1538   1588       FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
         1589  +    FUNCTION(instr,              2, 0, 0, instrFunc        ),
  1539   1590       FUNCTION(substr,             2, 0, 0, substrFunc       ),
  1540   1591       FUNCTION(substr,             3, 0, 0, substrFunc       ),
  1541   1592       FUNCTION(abs,                1, 0, 0, absFunc          ),
  1542   1593   #ifndef SQLITE_OMIT_FLOATING_POINT
  1543   1594       FUNCTION(round,              1, 0, 0, roundFunc        ),
  1544   1595       FUNCTION(round,              2, 0, 0, roundFunc        ),
  1545   1596   #endif

Changes to src/global.c.

   172    172      0,                         /* isMallocInit */
   173    173      0,                         /* isPCacheInit */
   174    174      0,                         /* pInitMutex */
   175    175      0,                         /* nRefInitMutex */
   176    176      0,                         /* xLog */
   177    177      0,                         /* pLogArg */
   178    178      0,                         /* bLocaltimeFault */
          179  +#ifdef SQLITE_ENABLE_SQLLOG
          180  +   0,                         /* xSqllog */
          181  +   0                          /* pSqllogArg */
          182  +#endif
   179    183   };
   180    184   
   181    185   
   182    186   /*
   183    187   ** Hash table for global functions - functions common to all
   184    188   ** database connections.  After initialization, this table is
   185    189   ** read-only.

Changes to src/hash.c.

   189    189         pEntry->chain = elem->next;
   190    190       }
   191    191       pEntry->count--;
   192    192       assert( pEntry->count>=0 );
   193    193     }
   194    194     sqlite3_free( elem );
   195    195     pH->count--;
   196         -  if( pH->count<=0 ){
          196  +  if( pH->count==0 ){
   197    197       assert( pH->first==0 );
   198    198       assert( pH->count==0 );
   199    199       sqlite3HashClear(pH);
   200    200     }
   201    201   }
   202    202   
   203    203   /* Attempt to locate an element of the hash table pH with a key

Changes to src/insert.c.

    21     21     Parse *p,       /* Generate code into this VDBE */
    22     22     int iCur,       /* The cursor number of the table */
    23     23     int iDb,        /* The database index in sqlite3.aDb[] */
    24     24     Table *pTab,    /* The table to be opened */
    25     25     int opcode      /* OP_OpenRead or OP_OpenWrite */
    26     26   ){
    27     27     Vdbe *v;
    28         -  if( IsVirtual(pTab) ) return;
           28  +  assert( !IsVirtual(pTab) );
    29     29     v = sqlite3GetVdbe(p);
    30     30     assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
    31     31     sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
    32     32     sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
    33     33     sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
    34     34     VdbeComment((v, "%s", pTab->zName));
    35     35   }

Changes to src/journal.c.

   223    223   */
   224    224   int sqlite3JournalCreate(sqlite3_file *p){
   225    225     if( p->pMethods!=&JournalFileMethods ){
   226    226       return SQLITE_OK;
   227    227     }
   228    228     return createFile((JournalFile *)p);
   229    229   }
          230  +
          231  +/*
          232  +** The file-handle passed as the only argument is guaranteed to be an open
          233  +** file. It may or may not be of class JournalFile. If the file is a
          234  +** JournalFile, and the underlying file on disk has not yet been opened,
          235  +** return 0. Otherwise, return 1.
          236  +*/
          237  +int sqlite3JournalExists(sqlite3_file *p){
          238  +  return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0);
          239  +}
   230    240   
   231    241   /* 
   232    242   ** Return the number of bytes required to store a JournalFile that uses vfs
   233    243   ** pVfs to create the underlying on-disk files.
   234    244   */
   235    245   int sqlite3JournalSize(sqlite3_vfs *pVfs){
   236    246     return (pVfs->szOsFile+sizeof(JournalFile));
   237    247   }
   238    248   #endif

Changes to src/main.c.

   127    127   
   128    128     /* If SQLite is already completely initialized, then this call
   129    129     ** to sqlite3_initialize() should be a no-op.  But the initialization
   130    130     ** must be complete.  So isInit must not be set until the very end
   131    131     ** of this routine.
   132    132     */
   133    133     if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
          134  +
          135  +#ifdef SQLITE_ENABLE_SQLLOG
          136  +  {
          137  +    extern void sqlite3_init_sqllog(void);
          138  +    sqlite3_init_sqllog();
          139  +  }
          140  +#endif
   134    141   
   135    142     /* Make sure the mutex subsystem is initialized.  If unable to 
   136    143     ** initialize the mutex subsystem, return early with the error.
   137    144     ** If the system is so sick that we are unable to allocate a mutex,
   138    145     ** there is not much SQLite is going to be able to do.
   139    146     **
   140    147     ** The mutex subsystem must take care of serializing its own
................................................................................
   475    482         break;
   476    483       }
   477    484   
   478    485       case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
   479    486         sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
   480    487         break;
   481    488       }
          489  +
          490  +#ifdef SQLITE_ENABLE_SQLLOG
          491  +    case SQLITE_CONFIG_SQLLOG: {
          492  +      typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
          493  +      sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
          494  +      sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
          495  +      break;
          496  +    }
          497  +#endif
   482    498   
   483    499       case SQLITE_CONFIG_READONLY: {
   484    500         sqlite3GlobalConfig.bReadOnly = va_arg(ap, int);
   485    501         break;
   486    502       }
   487    503   
   488    504       default: {
................................................................................
   853    869     */
   854    870     if( !forceZombie && connectionIsBusy(db) ){
   855    871       sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
   856    872          "statements or unfinished backups");
   857    873       sqlite3_mutex_leave(db->mutex);
   858    874       return SQLITE_BUSY;
   859    875     }
          876  +
          877  +#ifdef SQLITE_ENABLE_SQLLOG
          878  +  if( sqlite3GlobalConfig.xSqllog ){
          879  +    /* Closing the handle. Fourth parameter is passed the value 2. */
          880  +    sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
          881  +  }
          882  +#endif
   860    883   
   861    884     /* Convert the connection into a zombie and then close it.
   862    885     */
   863    886     db->magic = SQLITE_MAGIC_ZOMBIE;
   864    887     sqlite3LeaveMutexAndCloseZombie(db);
   865    888     return SQLITE_OK;
   866    889   }
................................................................................
  2497   2520     if( rc==SQLITE_NOMEM ){
  2498   2521       sqlite3_close(db);
  2499   2522       db = 0;
  2500   2523     }else if( rc!=SQLITE_OK ){
  2501   2524       db->magic = SQLITE_MAGIC_SICK;
  2502   2525     }
  2503   2526     *ppDb = db;
         2527  +#ifdef SQLITE_ENABLE_SQLLOG
         2528  +  if( sqlite3GlobalConfig.xSqllog ){
         2529  +    /* Opening a db handle. Fourth parameter is passed 0. */
         2530  +    void *pArg = sqlite3GlobalConfig.pSqllogArg;
         2531  +    sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
         2532  +  }
         2533  +#endif
  2504   2534     return sqlite3ApiExit(0, rc);
  2505   2535   }
  2506   2536   
  2507   2537   /*
  2508   2538   ** Open a new database handle.
  2509   2539   */
  2510   2540   int sqlite3_open(
................................................................................
  3065   3095       ** operation N should be 0.  The idea is that a test program (like the
  3066   3096       ** SQL Logic Test or SLT test module) can run the same SQL multiple times
  3067   3097       ** with various optimizations disabled to verify that the same answer
  3068   3098       ** is obtained in every case.
  3069   3099       */
  3070   3100       case SQLITE_TESTCTRL_OPTIMIZATIONS: {
  3071   3101         sqlite3 *db = va_arg(ap, sqlite3*);
  3072         -      db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff);
         3102  +      db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
  3073   3103         break;
  3074   3104       }
  3075   3105   
  3076   3106   #ifdef SQLITE_N_KEYWORD
  3077   3107       /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
  3078   3108       **
  3079   3109       ** If zWord is a keyword recognized by the parser, then return the

Changes to src/os_unix.c.

    42     42   **   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
    43     43   **   *  Definitions of sqlite3_vfs objects for all locking methods
    44     44   **      plus implementations of sqlite3_os_init() and sqlite3_os_end().
    45     45   */
    46     46   #include "sqliteInt.h"
    47     47   #if SQLITE_OS_UNIX              /* This file is used on unix only */
    48     48   
           49  +/* Use posix_fallocate() if it is available
           50  +*/
           51  +#if !defined(HAVE_POSIX_FALLOCATE) \
           52  +      && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
           53  +# define HAVE_POSIX_FALLOCATE 1
           54  +#endif
           55  +
    49     56   /*
    50     57   ** There are various methods for file locking used for concurrency
    51     58   ** control:
    52     59   **
    53     60   **   1. POSIX locking (the default),
    54     61   **   2. No locking,
    55     62   **   3. Dot-file locking,
................................................................................
   214    221     unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
   215    222     int lastErrno;                      /* The unix errno from last I/O error */
   216    223     void *lockingContext;               /* Locking style specific state */
   217    224     UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
   218    225     const char *zPath;                  /* Name of the file */
   219    226     unixShm *pShm;                      /* Shared memory segment information */
   220    227     int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
          228  +#ifdef __QNXNTO__
          229  +  int sectorSize;                     /* Device sector size */
          230  +  int deviceCharacteristics;          /* Precomputed device characteristics */
          231  +#endif
   221    232   #if SQLITE_ENABLE_LOCKING_STYLE
   222    233     int openFlags;                      /* The flags specified at open() */
   223    234   #endif
   224    235   #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
   225    236     unsigned fsFlags;                   /* cached details from statfs() */
   226    237   #endif
   227    238   #if OS_VXWORKS
................................................................................
  3566   3577     }else if( (*pArg)==0 ){
  3567   3578       pFile->ctrlFlags &= ~mask;
  3568   3579     }else{
  3569   3580       pFile->ctrlFlags |= mask;
  3570   3581     }
  3571   3582   }
  3572   3583   
         3584  +/* Forward declaration */
         3585  +static int unixGetTempname(int nBuf, char *zBuf);
         3586  +
  3573   3587   /*
  3574   3588   ** Information and control of an open file handle.
  3575   3589   */
  3576   3590   static int unixFileControl(sqlite3_file *id, int op, void *pArg){
  3577   3591     unixFile *pFile = (unixFile*)id;
  3578   3592     switch( op ){
  3579   3593       case SQLITE_FCNTL_LOCKSTATE: {
................................................................................
  3603   3617         unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
  3604   3618         return SQLITE_OK;
  3605   3619       }
  3606   3620       case SQLITE_FCNTL_VFSNAME: {
  3607   3621         *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
  3608   3622         return SQLITE_OK;
  3609   3623       }
         3624  +    case SQLITE_FCNTL_TEMPFILENAME: {
         3625  +      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
         3626  +      if( zTFile ){
         3627  +        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
         3628  +        *(char**)pArg = zTFile;
         3629  +      }
         3630  +      return SQLITE_OK;
         3631  +    }
  3610   3632   #ifdef SQLITE_DEBUG
  3611   3633       /* The pager calls this method to signal that it has done
  3612   3634       ** a rollback and that the database is therefore unchanged and
  3613   3635       ** it hence it is OK for the transaction change counter to be
  3614   3636       ** unchanged.
  3615   3637       */
  3616   3638       case SQLITE_FCNTL_DB_UNCHANGED: {
................................................................................
  3634   3656   ** larger for some devices.
  3635   3657   **
  3636   3658   ** SQLite code assumes this function cannot fail. It also assumes that
  3637   3659   ** if two files are created in the same file-system directory (i.e.
  3638   3660   ** a database and its journal file) that the sector size will be the
  3639   3661   ** same for both.
  3640   3662   */
  3641         -static int unixSectorSize(sqlite3_file *pFile){
  3642         -  (void)pFile;
         3663  +#ifndef __QNXNTO__ 
         3664  +static int unixSectorSize(sqlite3_file *NotUsed){
         3665  +  UNUSED_PARAMETER(NotUsed);
  3643   3666     return SQLITE_DEFAULT_SECTOR_SIZE;
  3644   3667   }
         3668  +#endif
         3669  +
         3670  +/*
         3671  +** The following version of unixSectorSize() is optimized for QNX.
         3672  +*/
         3673  +#ifdef __QNXNTO__
         3674  +#include <sys/dcmd_blk.h>
         3675  +#include <sys/statvfs.h>
         3676  +static int unixSectorSize(sqlite3_file *id){
         3677  +  unixFile *pFile = (unixFile*)id;
         3678  +  if( pFile->sectorSize == 0 ){
         3679  +    struct statvfs fsInfo;
         3680  +       
         3681  +    /* Set defaults for non-supported filesystems */
         3682  +    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
         3683  +    pFile->deviceCharacteristics = 0;
         3684  +    if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
         3685  +      return pFile->sectorSize;
         3686  +    }
         3687  +
         3688  +    if( !strcmp(fsInfo.f_basetype, "tmp") ) {
         3689  +      pFile->sectorSize = fsInfo.f_bsize;
         3690  +      pFile->deviceCharacteristics =
         3691  +        SQLITE_IOCAP_ATOMIC4K |       /* All ram filesystem writes are atomic */
         3692  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3693  +                                      ** the write succeeds */
         3694  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3695  +                                      ** so it is ordered */
         3696  +        0;
         3697  +    }else if( strstr(fsInfo.f_basetype, "etfs") ){
         3698  +      pFile->sectorSize = fsInfo.f_bsize;
         3699  +      pFile->deviceCharacteristics =
         3700  +        /* etfs cluster size writes are atomic */
         3701  +        (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) |
         3702  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3703  +                                      ** the write succeeds */
         3704  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3705  +                                      ** so it is ordered */
         3706  +        0;
         3707  +    }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){
         3708  +      pFile->sectorSize = fsInfo.f_bsize;
         3709  +      pFile->deviceCharacteristics =
         3710  +        SQLITE_IOCAP_ATOMIC |         /* All filesystem writes are atomic */
         3711  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3712  +                                      ** the write succeeds */
         3713  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3714  +                                      ** so it is ordered */
         3715  +        0;
         3716  +    }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){
         3717  +      pFile->sectorSize = fsInfo.f_bsize;
         3718  +      pFile->deviceCharacteristics =
         3719  +        /* full bitset of atomics from max sector size and smaller */
         3720  +        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
         3721  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3722  +                                      ** so it is ordered */
         3723  +        0;
         3724  +    }else if( strstr(fsInfo.f_basetype, "dos") ){
         3725  +      pFile->sectorSize = fsInfo.f_bsize;
         3726  +      pFile->deviceCharacteristics =
         3727  +        /* full bitset of atomics from max sector size and smaller */
         3728  +        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
         3729  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3730  +                                      ** so it is ordered */
         3731  +        0;
         3732  +    }else{
         3733  +      pFile->deviceCharacteristics =
         3734  +        SQLITE_IOCAP_ATOMIC512 |      /* blocks are atomic */
         3735  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3736  +                                      ** the write succeeds */
         3737  +        0;
         3738  +    }
         3739  +  }
         3740  +  /* Last chance verification.  If the sector size isn't a multiple of 512
         3741  +  ** then it isn't valid.*/
         3742  +  if( pFile->sectorSize % 512 != 0 ){
         3743  +    pFile->deviceCharacteristics = 0;
         3744  +    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
         3745  +  }
         3746  +  return pFile->sectorSize;
         3747  +}
         3748  +#endif /* __QNXNTO__ */
  3645   3749   
  3646   3750   /*
  3647   3751   ** Return the device characteristics for the file.
  3648   3752   **
  3649   3753   ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
  3650   3754   ** However, that choice is contraversial since technically the underlying
  3651   3755   ** file system does not always provide powersafe overwrites.  (In other
................................................................................
  3654   3758   ** very rare.  And asserting PSOW makes a large reduction in the amount
  3655   3759   ** of required I/O for journaling, since a lot of padding is eliminated.
  3656   3760   **  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
  3657   3761   ** available to turn it off and URI query parameter available to turn it off.
  3658   3762   */
  3659   3763   static int unixDeviceCharacteristics(sqlite3_file *id){
  3660   3764     unixFile *p = (unixFile*)id;
         3765  +  int rc = 0;
         3766  +#ifdef __QNXNTO__
         3767  +  if( p->sectorSize==0 ) unixSectorSize(id);
         3768  +  rc = p->deviceCharacteristics;
         3769  +#endif
  3661   3770     if( p->ctrlFlags & UNIXFILE_PSOW ){
  3662         -    return SQLITE_IOCAP_POWERSAFE_OVERWRITE;
  3663         -  }else{
  3664         -    return 0;
         3771  +    rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
  3665   3772     }
         3773  +  return rc;
  3666   3774   }
  3667   3775   
  3668   3776   #ifndef SQLITE_OMIT_WAL
  3669   3777   
  3670   3778   
  3671   3779   /*
  3672   3780   ** Object used to represent an shared memory buffer.  
................................................................................
  4074   4182           /* The requested memory region does not exist. If bExtend is set to
  4075   4183           ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
  4076   4184           **
  4077   4185           ** Alternatively, if bExtend is true, use ftruncate() to allocate
  4078   4186           ** the requested memory region.
  4079   4187           */
  4080   4188           if( !bExtend ) goto shmpage_out;
         4189  +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
         4190  +        if( osFallocate(pShmNode->h, sStat.st_size, nByte)!=0 ){
         4191  +          rc = unixLogError(SQLITE_IOERR_SHMSIZE, "fallocate",
         4192  +                            pShmNode->zFilename);
         4193  +          goto shmpage_out;
         4194  +        }
         4195  +#else
  4081   4196           if( robust_ftruncate(pShmNode->h, nByte) ){
  4082   4197             rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
  4083   4198                               pShmNode->zFilename);
  4084   4199             goto shmpage_out;
  4085   4200           }
         4201  +#endif
  4086   4202         }
  4087   4203       }
  4088   4204   
  4089   4205       /* Map the requested memory region into this processes address space. */
  4090   4206       apNew = (char **)sqlite3_realloc(
  4091   4207           pShmNode->apRegion, (iRegion+1)*sizeof(char *)
  4092   4208       );
................................................................................
  5280   5396     sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
  5281   5397     const char *zPath,        /* Name of file to be deleted */
  5282   5398     int dirSync               /* If true, fsync() directory after deleting file */
  5283   5399   ){
  5284   5400     int rc = SQLITE_OK;
  5285   5401     UNUSED_PARAMETER(NotUsed);
  5286   5402     SimulateIOError(return SQLITE_IOERR_DELETE);
  5287         -  if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
  5288         -    return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
         5403  +  if( osUnlink(zPath)==(-1) ){
         5404  +    if( errno==ENOENT ){
         5405  +      rc = SQLITE_IOERR_DELETE_NOENT;
         5406  +    }else{
         5407  +      rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
         5408  +    }
         5409  +    return rc;
  5289   5410     }
  5290   5411   #ifndef SQLITE_DISABLE_DIRSYNC
  5291   5412     if( (dirSync & 1)!=0 ){
  5292   5413       int fd;
  5293   5414       rc = osOpenDirectory(zPath, &fd);
  5294   5415       if( rc==SQLITE_OK ){
  5295   5416   #if OS_VXWORKS

Changes to src/os_win.c.

  2188   2188         if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
  2189   2189   #else
  2190   2190         if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
  2191   2191   #endif
  2192   2192           if( retryIoerr(&nRetry, &lastErrno) ) continue;
  2193   2193           break;
  2194   2194         }
  2195         -      if( nWrite<=0 ){
         2195  +      assert( nWrite==0 || nWrite<=(DWORD)nRem );
         2196  +      if( nWrite==0 || nWrite>(DWORD)nRem ){
  2196   2197           lastErrno = osGetLastError();
  2197   2198           break;
  2198   2199         }
  2199   2200   #if !SQLITE_OS_WINCE
  2200   2201         offset += nWrite;
  2201   2202         overlapped.Offset = (LONG)(offset & 0xffffffff);
  2202   2203         overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
................................................................................
  2686   2687     }else if( (*pArg)==0 ){
  2687   2688       pFile->ctrlFlags &= ~mask;
  2688   2689     }else{
  2689   2690       pFile->ctrlFlags |= mask;
  2690   2691     }
  2691   2692   }
  2692   2693   
         2694  +/* Forward declaration */
         2695  +static int getTempname(int nBuf, char *zBuf);
         2696  +
  2693   2697   /*
  2694   2698   ** Control and query of the open file handle.
  2695   2699   */
  2696   2700   static int winFileControl(sqlite3_file *id, int op, void *pArg){
  2697   2701     winFile *pFile = (winFile*)id;
  2698   2702     switch( op ){
  2699   2703       case SQLITE_FCNTL_LOCKSTATE: {
................................................................................
  2745   2749         }
  2746   2750         if( a[1]>0 ){
  2747   2751           win32IoerrRetryDelay = a[1];
  2748   2752         }else{
  2749   2753           a[1] = win32IoerrRetryDelay;
  2750   2754         }
  2751   2755         return SQLITE_OK;
         2756  +    }
         2757  +    case SQLITE_FCNTL_TEMPFILENAME: {
         2758  +      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
         2759  +      if( zTFile ){
         2760  +        getTempname(pFile->pVfs->mxPathname, zTFile);
         2761  +        *(char**)pArg = zTFile;
         2762  +      }
         2763  +      return SQLITE_OK;
  2752   2764       }
  2753   2765     }
  2754   2766     return SQLITE_NOTFOUND;
  2755   2767   }
  2756   2768   
  2757   2769   /*
  2758   2770   ** Return the sector size in bytes of the underlying block device for
................................................................................
  3883   3895   #if SQLITE_OS_WINRT
  3884   3896         WIN32_FILE_ATTRIBUTE_DATA sAttrData;
  3885   3897         memset(&sAttrData, 0, sizeof(sAttrData));
  3886   3898         if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
  3887   3899                                     &sAttrData) ){
  3888   3900           attr = sAttrData.dwFileAttributes;
  3889   3901         }else{
  3890         -        rc = SQLITE_OK; /* Already gone? */
         3902  +        lastErrno = osGetLastError();
         3903  +        if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
         3904  +          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
         3905  +        }else{
         3906  +          rc = SQLITE_ERROR;
         3907  +        }
  3891   3908           break;
  3892   3909         }
  3893   3910   #else
  3894   3911         attr = osGetFileAttributesW(zConverted);
  3895   3912   #endif
  3896   3913         if ( attr==INVALID_FILE_ATTRIBUTES ){
  3897         -        rc = SQLITE_OK; /* Already gone? */
         3914  +        lastErrno = osGetLastError();
         3915  +        if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
         3916  +          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
         3917  +        }else{
         3918  +          rc = SQLITE_ERROR;
         3919  +        }
  3898   3920           break;
  3899   3921         }
  3900   3922         if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
  3901   3923           rc = SQLITE_ERROR; /* Files only. */
  3902   3924           break;
  3903   3925         }
  3904   3926         if ( osDeleteFileW(zConverted) ){
................................................................................
  3912   3934       } while(1);
  3913   3935     }
  3914   3936   #ifdef SQLITE_WIN32_HAS_ANSI
  3915   3937     else{
  3916   3938       do {
  3917   3939         attr = osGetFileAttributesA(zConverted);
  3918   3940         if ( attr==INVALID_FILE_ATTRIBUTES ){
  3919         -        rc = SQLITE_OK; /* Already gone? */
         3941  +        lastErrno = osGetLastError();
         3942  +        if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
         3943  +          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
         3944  +        }else{
         3945  +          rc = SQLITE_ERROR;
         3946  +        }
  3920   3947           break;
  3921   3948         }
  3922   3949         if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
  3923   3950           rc = SQLITE_ERROR; /* Files only. */
  3924   3951           break;
  3925   3952         }
  3926   3953         if ( osDeleteFileA(zConverted) ){
................................................................................
  3930   3957         if ( !retryIoerr(&cnt, &lastErrno) ){
  3931   3958           rc = SQLITE_ERROR; /* No more retries. */
  3932   3959           break;
  3933   3960         }
  3934   3961       } while(1);
  3935   3962     }
  3936   3963   #endif
  3937         -  if( rc ){
         3964  +  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
  3938   3965       rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
  3939   3966                "winDelete", zFilename);
  3940   3967     }else{
  3941   3968       logIoerr(cnt);
  3942   3969     }
  3943   3970     sqlite3_free(zConverted);
  3944   3971     OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));

Changes to src/pager.c.

  1937   1937         pPager->journalOff = 0;
  1938   1938       }else{
  1939   1939         /* This branch may be executed with Pager.journalMode==MEMORY if
  1940   1940         ** a hot-journal was just rolled back. In this case the journal
  1941   1941         ** file should be closed and deleted. If this connection writes to
  1942   1942         ** the database file, it will do so using an in-memory journal. 
  1943   1943         */
         1944  +      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
  1944   1945         assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
  1945   1946              || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
  1946   1947              || pPager->journalMode==PAGER_JOURNALMODE_WAL 
  1947   1948         );
  1948   1949         sqlite3OsClose(pPager->jfd);
  1949         -      if( !pPager->tempFile ){
         1950  +      if( bDelete ){
  1950   1951           rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
  1951   1952         }
  1952   1953       }
  1953   1954     }
  1954   1955   
  1955   1956   #ifdef SQLITE_CHECK_PAGES
  1956   1957     sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
................................................................................
  3155   3156       int isWal;                    /* True if WAL file exists */
  3156   3157       Pgno nPage;                   /* Size of the database file */
  3157   3158   
  3158   3159       rc = pagerPagecount(pPager, &nPage);
  3159   3160       if( rc ) return rc;
  3160   3161       if( nPage==0 ){
  3161   3162         rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
         3163  +      if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
  3162   3164         isWal = 0;
  3163   3165       }else{
  3164   3166         rc = sqlite3OsAccess(
  3165   3167             pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
  3166   3168         );
  3167   3169       }
  3168   3170       if( rc==SQLITE_OK ){
................................................................................
  3480   3482     pPager->xBusyHandler = xBusyHandler;
  3481   3483     pPager->pBusyHandlerArg = pBusyHandlerArg;
  3482   3484   
  3483   3485     if( isOpen(pPager->fd) ){
  3484   3486       void **ap = (void **)&pPager->xBusyHandler;
  3485   3487       assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
  3486   3488       assert( ap[1]==pBusyHandlerArg );
  3487         -    sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
         3489  +    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
  3488   3490     }
  3489   3491   }
  3490   3492   
  3491   3493   /*
  3492   3494   ** Change the page size used by the Pager object. The new page size 
  3493   3495   ** is passed in *pPageSize.
  3494   3496   **
................................................................................
  5881   5883     #else
  5882   5884         rc = pager_incr_changecounter(pPager, 0);
  5883   5885     #endif
  5884   5886         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  5885   5887     
  5886   5888         /* If this transaction has made the database smaller, then all pages
  5887   5889         ** being discarded by the truncation must be written to the journal
  5888         -      ** file. This can only happen in auto-vacuum mode.
         5890  +      ** file.
  5889   5891         **
  5890   5892         ** Before reading the pages with page numbers larger than the 
  5891   5893         ** current value of Pager.dbSize, set dbSize back to the value
  5892   5894         ** that it took at the start of the transaction. Otherwise, the
  5893   5895         ** calls to sqlite3PagerGet() return zeroed pages instead of 
  5894   5896         ** reading data from the database file.
  5895   5897         */
  5896         -  #ifndef SQLITE_OMIT_AUTOVACUUM
  5897   5898         if( pPager->dbSize<pPager->dbOrigSize 
  5898   5899          && pPager->journalMode!=PAGER_JOURNALMODE_OFF
  5899   5900         ){
  5900   5901           Pgno i;                                   /* Iterator variable */
  5901   5902           const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
  5902   5903           const Pgno dbSize = pPager->dbSize;       /* Database image size */ 
  5903   5904           pPager->dbSize = pPager->dbOrigSize;
................................................................................
  5909   5910               rc = sqlite3PagerWrite(pPage);
  5910   5911               sqlite3PagerUnref(pPage);
  5911   5912               if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  5912   5913             }
  5913   5914           }
  5914   5915           pPager->dbSize = dbSize;
  5915   5916         } 
  5916         -  #endif
  5917   5917     
  5918   5918         /* Write the master journal name into the journal file. If a master 
  5919   5919         ** journal file name has already been written to the journal file, 
  5920   5920         ** or if zMaster is NULL (no master journal), then this call is a no-op.
  5921   5921         */
  5922   5922         rc = writeMasterJournal(pPager, zMaster);
  5923   5923         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;

Changes to src/select.c.

  3905   3905     for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
  3906   3906       struct SrcList_item *pItem = &pTabList->a[i];
  3907   3907       SelectDest dest;
  3908   3908       Select *pSub = pItem->pSelect;
  3909   3909       int isAggSub;
  3910   3910   
  3911   3911       if( pSub==0 ) continue;
         3912  +
         3913  +    /* Sometimes the code for a subquery will be generated more than
         3914  +    ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
         3915  +    ** for example.  In that case, do not regenerate the code to manifest
         3916  +    ** a view or the co-routine to implement a view.  The first instance
         3917  +    ** is sufficient, though the subroutine to manifest the view does need
         3918  +    ** to be invoked again. */
  3912   3919       if( pItem->addrFillSub ){
  3913         -      sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
         3920  +      if( pItem->viaCoroutine==0 ){
         3921  +        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
         3922  +      }
  3914   3923         continue;
  3915   3924       }
  3916   3925   
  3917   3926       /* Increment Parse.nHeight by the height of the largest expression
  3918   3927       ** tree refered to by this, the parent select. The child select
  3919   3928       ** may contain expression trees of at most
  3920   3929       ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
................................................................................
  3927   3936       if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
  3928   3937         /* This subquery can be absorbed into its parent. */
  3929   3938         if( isAggSub ){
  3930   3939           isAgg = 1;
  3931   3940           p->selFlags |= SF_Aggregate;
  3932   3941         }
  3933   3942         i = -1;
         3943  +    }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0
         3944  +      && OptimizationEnabled(db, SQLITE_SubqCoroutine)
         3945  +    ){
         3946  +      /* Implement a co-routine that will return a single row of the result
         3947  +      ** set on each invocation.
         3948  +      */
         3949  +      int addrTop;
         3950  +      int addrEof;
         3951  +      pItem->regReturn = ++pParse->nMem;
         3952  +      addrEof = ++pParse->nMem;
         3953  +      /* Before coding the OP_Goto to jump to the start of the main routine,
         3954  +      ** ensure that the jump to the verify-schema routine has already
         3955  +      ** been coded. Otherwise, the verify-schema would likely be coded as 
         3956  +      ** part of the co-routine. If the main routine then accessed the 
         3957  +      ** database before invoking the co-routine for the first time (for 
         3958  +      ** example to initialize a LIMIT register from a sub-select), it would 
         3959  +      ** be doing so without having verified the schema version and obtained 
         3960  +      ** the required db locks. See ticket d6b36be38.  */
         3961  +      sqlite3CodeVerifySchema(pParse, -1);
         3962  +      sqlite3VdbeAddOp0(v, OP_Goto);
         3963  +      addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
         3964  +      sqlite3VdbeChangeP5(v, 1);
         3965  +      VdbeComment((v, "coroutine for %s", pItem->pTab->zName));
         3966  +      pItem->addrFillSub = addrTop;
         3967  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof);
         3968  +      sqlite3VdbeChangeP5(v, 1);
         3969  +      sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
         3970  +      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
         3971  +      sqlite3Select(pParse, pSub, &dest);
         3972  +      pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
         3973  +      pItem->viaCoroutine = 1;
         3974  +      sqlite3VdbeChangeP2(v, addrTop, dest.iSdst);
         3975  +      sqlite3VdbeChangeP3(v, addrTop, dest.nSdst);
         3976  +      sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof);
         3977  +      sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn);
         3978  +      VdbeComment((v, "end %s", pItem->pTab->zName));
         3979  +      sqlite3VdbeJumpHere(v, addrTop-1);
         3980  +      sqlite3ClearTempRegCache(pParse);
  3934   3981       }else{
  3935   3982         /* Generate a subroutine that will fill an ephemeral table with
  3936   3983         ** the content of this subquery.  pItem->addrFillSub will point
  3937   3984         ** to the address of the generated subroutine.  pItem->regReturn
  3938   3985         ** is a register allocated to hold the subroutine return address
  3939   3986         */
  3940   3987         int topAddr;

Changes to src/shell.c.

   537    537   static void output_c_string(FILE *out, const char *z){
   538    538     unsigned int c;
   539    539     fputc('"', out);
   540    540     while( (c = *(z++))!=0 ){
   541    541       if( c=='\\' ){
   542    542         fputc(c, out);
   543    543         fputc(c, out);
          544  +    }else if( c=='"' ){
          545  +      fputc('\\', out);
          546  +      fputc('"', out);
   544    547       }else if( c=='\t' ){
   545    548         fputc('\\', out);
   546    549         fputc('t', out);
   547    550       }else if( c=='\n' ){
   548    551         fputc('\\', out);
   549    552         fputc('n', out);
   550    553       }else if( c=='\r' ){
................................................................................
   792    795         fprintf(p->out,"</TR>\n");
   793    796         break;
   794    797       }
   795    798       case MODE_Tcl: {
   796    799         if( p->cnt++==0 && p->showHeader ){
   797    800           for(i=0; i<nArg; i++){
   798    801             output_c_string(p->out,azCol[i] ? azCol[i] : "");
   799         -          fprintf(p->out, "%s", p->separator);
          802  +          if(i<nArg-1) fprintf(p->out, "%s", p->separator);
   800    803           }
   801    804           fprintf(p->out,"\n");
   802    805         }
   803    806         if( azArg==0 ) break;
   804    807         for(i=0; i<nArg; i++){
   805    808           output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
   806         -        fprintf(p->out, "%s", p->separator);
          809  +        if(i<nArg-1) fprintf(p->out, "%s", p->separator);
   807    810         }
   808    811         fprintf(p->out,"\n");
   809    812         break;
   810    813       }
   811    814       case MODE_Csv: {
   812    815         if( p->cnt++==0 && p->showHeader ){
   813    816           for(i=0; i<nArg; i++){
................................................................................
  2014   2017         p->mode = MODE_Column;
  2015   2018       }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
  2016   2019         p->mode = MODE_List;
  2017   2020       }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
  2018   2021         p->mode = MODE_Html;
  2019   2022       }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
  2020   2023         p->mode = MODE_Tcl;
         2024  +      sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
  2021   2025       }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
  2022   2026         p->mode = MODE_Csv;
  2023   2027         sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
  2024   2028       }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
  2025   2029         p->mode = MODE_List;
  2026   2030         sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
  2027   2031       }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
................................................................................
  2707   2711     if( zSql ){
  2708   2712       if( !_all_whitespace(zSql) ){
  2709   2713         fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
  2710   2714       }
  2711   2715       free(zSql);
  2712   2716     }
  2713   2717     free(zLine);
  2714         -  return errCnt;
         2718  +  return errCnt>0;
  2715   2719   }
  2716   2720   
  2717   2721   /*
  2718   2722   ** Return a pathname which is the user's home directory.  A
  2719   2723   ** 0 return indicates an error of some kind.
  2720   2724   */
  2721   2725   static char *find_home_dir(void){
................................................................................
  2820   2824   /*
  2821   2825   ** Show available command line options
  2822   2826   */
  2823   2827   static const char zOptions[] = 
  2824   2828     "   -bail                stop after hitting an error\n"
  2825   2829     "   -batch               force batch I/O\n"
  2826   2830     "   -column              set output mode to 'column'\n"
  2827         -  "   -cmd command         run \"command\" before reading stdin\n"
         2831  +  "   -cmd COMMAND         run \"COMMAND\" before reading stdin\n"
  2828   2832     "   -csv                 set output mode to 'csv'\n"
  2829   2833     "   -echo                print commands before execution\n"
  2830         -  "   -init filename       read/process named file\n"
         2834  +  "   -init FILENAME       read/process named file\n"
  2831   2835     "   -[no]header          turn headers on or off\n"
         2836  +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
         2837  +  "   -heap SIZE           Size of heap for memsys3 or memsys5\n"
         2838  +#endif
  2832   2839     "   -help                show this message\n"
  2833   2840     "   -html                set output mode to HTML\n"
  2834   2841     "   -interactive         force interactive I/O\n"
  2835   2842     "   -line                set output mode to 'line'\n"
  2836   2843     "   -list                set output mode to 'list'\n"
  2837   2844   #ifdef SQLITE_ENABLE_MULTIPLEX
  2838   2845     "   -multiplex           enable the multiplexor VFS\n"
  2839   2846   #endif
  2840         -  "   -nullvalue 'text'    set text string for NULL values\n"
  2841         -  "   -separator 'x'       set output field separator (|)\n"
         2847  +  "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
         2848  +  "   -separator SEP       set output field separator. Default: '|'\n"
  2842   2849     "   -stats               print memory stats before each finalize\n"
  2843   2850     "   -version             show SQLite version\n"
  2844   2851     "   -vfs NAME            use NAME as the default VFS\n"
  2845   2852   #ifdef SQLITE_ENABLE_VFSTRACE
  2846   2853     "   -vfstrace            enable tracing of all VFS calls\n"
  2847   2854   #endif
  2848   2855   ;
................................................................................
  2869   2876     data->showHeader = 0;
  2870   2877     sqlite3_config(SQLITE_CONFIG_URI, 1);
  2871   2878     sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
  2872   2879     sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
  2873   2880     sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
  2874   2881     sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
  2875   2882   }
         2883  +
         2884  +/*
         2885  +** Get the argument to an --option.  Throw an error and die if no argument
         2886  +** is available.
         2887  +*/
         2888  +static char *cmdline_option_value(int argc, char **argv, int i){
         2889  +  if( i==argc ){
         2890  +    fprintf(stderr, "%s: Error: missing argument to %s\n",
         2891  +            argv[0], argv[argc-1]);
         2892  +    exit(1);
         2893  +  }
         2894  +  return argv[i];
         2895  +}
  2876   2896   
  2877   2897   int main(int argc, char **argv){
  2878   2898     char *zErrMsg = 0;
  2879   2899     struct callback_data data;
  2880   2900     const char *zInitFile = 0;
  2881   2901     char *zFirstCmd = 0;
  2882   2902     int i;
................................................................................
  2899   2919   #endif
  2900   2920   
  2901   2921     /* Do an initial pass through the command-line argument to locate
  2902   2922     ** the name of the database file, the name of the initialization file,
  2903   2923     ** the size of the alternative malloc heap,
  2904   2924     ** and the first command to execute.
  2905   2925     */
  2906         -  for(i=1; i<argc-1; i++){
         2926  +  for(i=1; i<argc; i++){
  2907   2927       char *z;
  2908         -    if( argv[i][0]!='-' ) break;
  2909   2928       z = argv[i];
         2929  +    if( z[0]!='-' ){
         2930  +      if( data.zDbFilename==0 ){
         2931  +        data.zDbFilename = z;
         2932  +        continue;
         2933  +      }
         2934  +      if( zFirstCmd==0 ){
         2935  +        zFirstCmd = z;
         2936  +        continue;
         2937  +      }
         2938  +      fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
         2939  +      fprintf(stderr,"Use -help for a list of options.\n");
         2940  +      return 1;
         2941  +    }
  2910   2942       if( z[1]=='-' ) z++;
  2911   2943       if( strcmp(z,"-separator")==0
  2912   2944        || strcmp(z,"-nullvalue")==0
  2913   2945        || strcmp(z,"-cmd")==0
  2914   2946       ){
  2915         -      i++;
         2947  +      (void)cmdline_option_value(argc, argv, ++i);
  2916   2948       }else if( strcmp(z,"-init")==0 ){
  2917         -      i++;
  2918         -      zInitFile = argv[i];
  2919         -    /* Need to check for batch mode here to so we can avoid printing
  2920         -    ** informational messages (like from process_sqliterc) before 
  2921         -    ** we do the actual processing of arguments later in a second pass.
  2922         -    */
         2949  +      zInitFile = cmdline_option_value(argc, argv, ++i);
  2923   2950       }else if( strcmp(z,"-batch")==0 ){
         2951  +      /* Need to check for batch mode here to so we can avoid printing
         2952  +      ** informational messages (like from process_sqliterc) before 
         2953  +      ** we do the actual processing of arguments later in a second pass.
         2954  +      */
  2924   2955         stdin_is_interactive = 0;
  2925   2956       }else if( strcmp(z,"-heap")==0 ){
  2926   2957   #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  2927   2958         int j, c;
  2928   2959         const char *zSize;
  2929   2960         sqlite3_int64 szHeap;
  2930   2961   
  2931         -      zSize = argv[++i];
         2962  +      zSize = cmdline_option_value(argc, argv, ++i);
  2932   2963         szHeap = atoi(zSize);
  2933   2964         for(j=0; (c = zSize[j])!=0; j++){
  2934   2965           if( c=='M' ){ szHeap *= 1000000; break; }
  2935   2966           if( c=='K' ){ szHeap *= 1000; break; }
  2936   2967           if( c=='G' ){ szHeap *= 1000000000; break; }
  2937   2968         }
  2938   2969         if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
................................................................................
  2951   2982   #endif
  2952   2983   #ifdef SQLITE_ENABLE_MULTIPLEX
  2953   2984       }else if( strcmp(z,"-multiplex")==0 ){
  2954   2985         extern int sqlite3_multiple_initialize(const char*,int);
  2955   2986         sqlite3_multiplex_initialize(0, 1);
  2956   2987   #endif
  2957   2988       }else if( strcmp(z,"-vfs")==0 ){
  2958         -      sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
         2989  +      sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
  2959   2990         if( pVfs ){
  2960   2991           sqlite3_vfs_register(pVfs, 1);
  2961   2992         }else{
  2962   2993           fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
  2963   2994           exit(1);
  2964   2995         }
  2965   2996       }
  2966   2997     }
  2967         -  if( i<argc ){
  2968         -    data.zDbFilename = argv[i++];
  2969         -  }else{
         2998  +  if( data.zDbFilename==0 ){
  2970   2999   #ifndef SQLITE_OMIT_MEMORYDB
  2971   3000       data.zDbFilename = ":memory:";
  2972   3001   #else
  2973         -    data.zDbFilename = 0;
         3002  +    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
         3003  +    return 1;
  2974   3004   #endif
  2975   3005     }
  2976         -  if( i<argc ){
  2977         -    zFirstCmd = argv[i++];
  2978         -  }
  2979         -  if( i<argc ){
  2980         -    fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
  2981         -    fprintf(stderr,"Use -help for a list of options.\n");
  2982         -    return 1;
  2983         -  }
  2984   3006     data.out = stdout;
  2985   3007   
  2986         -#ifdef SQLITE_OMIT_MEMORYDB
  2987         -  if( data.zDbFilename==0 ){
  2988         -    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
  2989         -    return 1;
  2990         -  }
  2991         -#endif
  2992         -
  2993   3008     /* Go ahead and open the database file if it already exists.  If the
  2994   3009     ** file does not exist, delay opening it.  This prevents empty database
  2995   3010     ** files from being created if a user mistypes the database name argument
  2996   3011     ** to the sqlite command-line tool.
  2997   3012     */
  2998   3013     if( access(data.zDbFilename, 0)==0 ){
  2999   3014       open_db(&data);
................................................................................
  3009   3024     }
  3010   3025   
  3011   3026     /* Make a second pass through the command-line argument and set
  3012   3027     ** options.  This second pass is delayed until after the initialization
  3013   3028     ** file is processed so that the command-line arguments will override
  3014   3029     ** settings in the initialization file.
  3015   3030     */
  3016         -  for(i=1; i<argc && argv[i][0]=='-'; i++){
         3031  +  for(i=1; i<argc; i++){
  3017   3032       char *z = argv[i];
         3033  +    if( z[0]!='-' ) continue;
  3018   3034       if( z[1]=='-' ){ z++; }
  3019   3035       if( strcmp(z,"-init")==0 ){
  3020   3036         i++;
  3021   3037       }else if( strcmp(z,"-html")==0 ){
  3022   3038         data.mode = MODE_Html;
  3023   3039       }else if( strcmp(z,"-list")==0 ){
  3024   3040         data.mode = MODE_List;
................................................................................
  3026   3042         data.mode = MODE_Line;
  3027   3043       }else if( strcmp(z,"-column")==0 ){
  3028   3044         data.mode = MODE_Column;
  3029   3045       }else if( strcmp(z,"-csv")==0 ){
  3030   3046         data.mode = MODE_Csv;
  3031   3047         memcpy(data.separator,",",2);
  3032   3048       }else if( strcmp(z,"-separator")==0 ){
  3033         -      i++;
  3034         -      if(i>=argc){
  3035         -        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
  3036         -                        Argv0, z);
  3037         -        fprintf(stderr,"Use -help for a list of options.\n");
  3038         -        return 1;
  3039         -      }
  3040   3049         sqlite3_snprintf(sizeof(data.separator), data.separator,
  3041         -                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);
         3050  +                       "%s",cmdline_option_value(argc,argv,++i));
  3042   3051       }else if( strcmp(z,"-nullvalue")==0 ){
  3043         -      i++;
  3044         -      if(i>=argc){
  3045         -        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
  3046         -                        Argv0, z);
  3047         -        fprintf(stderr,"Use -help for a list of options.\n");
  3048         -        return 1;
  3049         -      }
  3050   3052         sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
  3051         -                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
         3053  +                       "%s",cmdline_option_value(argc,argv,++i));
  3052   3054       }else if( strcmp(z,"-header")==0 ){
  3053   3055         data.showHeader = 1;
  3054   3056       }else if( strcmp(z,"-noheader")==0 ){
  3055   3057         data.showHeader = 0;
  3056   3058       }else if( strcmp(z,"-echo")==0 ){
  3057   3059         data.echoOn = 1;
  3058   3060       }else if( strcmp(z,"-stats")==0 ){
................................................................................
  3078   3080       }else if( strcmp(z,"-multiplex")==0 ){
  3079   3081         i++;
  3080   3082   #endif
  3081   3083       }else if( strcmp(z,"-help")==0 ){
  3082   3084         usage(1);
  3083   3085       }else if( strcmp(z,"-cmd")==0 ){
  3084   3086         if( i==argc-1 ) break;
  3085         -      i++;
  3086         -      z = argv[i];
         3087  +      z = cmdline_option_value(argc,argv,++i);
  3087   3088         if( z[0]=='.' ){
  3088   3089           rc = do_meta_command(z, &data);
  3089   3090           if( rc && bail_on_error ) return rc;
  3090   3091         }else{
  3091   3092           open_db(&data);
  3092   3093           rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
  3093   3094           if( zErrMsg!=0 ){

Changes to src/sqlite.h.in.

   465    465   #define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
   466    466   #define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
   467    467   #define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
   468    468   #define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
   469    469   #define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
   470    470   #define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
   471    471   #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
          472  +#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
   472    473   #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
   473    474   #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
   474    475   #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
   475    476   #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
   476    477   #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
   477    478   #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
   478    479   #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
................................................................................
   847    848   ** VFS has handled the PRAGMA itself and the parser generates a no-op
   848    849   ** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
   849    850   ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
   850    851   ** that the VFS encountered an error while handling the [PRAGMA] and the
   851    852   ** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
   852    853   ** file control occurs at the beginning of pragma statement analysis and so
   853    854   ** it is able to override built-in [PRAGMA] statements.
   854         -** </ul>
   855    855   **
   856    856   ** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
   857    857   ** ^This file-control may be invoked by SQLite on the database file handle
   858    858   ** shortly after it is opened in order to provide a custom VFS with access
   859    859   ** to the connections busy-handler callback. The argument is of type (void **)
   860    860   ** - an array of two (void *) values. The first (void *) actually points
   861    861   ** to a function of type (int (*)(void *)). In order to invoke the connections
   862    862   ** busy-handler, this function should be invoked with the second (void *) in
   863    863   ** the array as the only argument. If it returns non-zero, then the operation
   864    864   ** should be retried. If it returns zero, the custom VFS should abandon the
   865    865   ** current operation.
          866  +**
          867  +** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
          868  +** ^Application can invoke this file-control to have SQLite generate a
          869  +** temporary filename using the same algorithm that is followed to generate
          870  +** temporary filenames for TEMP tables and other internal uses.  The
          871  +** argument should be a char** which will be filled with the filename
          872  +** written into memory obtained from [sqlite3_malloc()].  The caller should
          873  +** invoke [sqlite3_free()] on the result to avoid a memory leak.
          874  +**
          875  +** </ul>
   866    876   */
   867    877   #define SQLITE_FCNTL_LOCKSTATE               1
   868    878   #define SQLITE_GET_LOCKPROXYFILE             2
   869    879   #define SQLITE_SET_LOCKPROXYFILE             3
   870    880   #define SQLITE_LAST_ERRNO                    4
   871    881   #define SQLITE_FCNTL_SIZE_HINT               5
   872    882   #define SQLITE_FCNTL_CHUNK_SIZE              6
................................................................................
   875    885   #define SQLITE_FCNTL_WIN32_AV_RETRY          9
   876    886   #define SQLITE_FCNTL_PERSIST_WAL            10
   877    887   #define SQLITE_FCNTL_OVERWRITE              11
   878    888   #define SQLITE_FCNTL_VFSNAME                12
   879    889   #define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
   880    890   #define SQLITE_FCNTL_PRAGMA                 14
   881    891   #define SQLITE_FCNTL_BUSYHANDLER            15
          892  +#define SQLITE_FCNTL_TEMPFILENAME           16
   882    893   
   883    894   /*
   884    895   ** CAPI3REF: Mutex Handle
   885    896   **
   886    897   ** The mutex module within SQLite defines [sqlite3_mutex] to be an
   887    898   ** abstract type for a mutex object.  The SQLite core never looks
   888    899   ** at the internal representation of an [sqlite3_mutex].  It only
................................................................................
  1607   1618   ** default, read-only mode is globally disabled.
  1608   1619   **
  1609   1620   ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
  1610   1621   ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
  1611   1622   ** <dd> These options are obsolete and should not be used by new code.
  1612   1623   ** They are retained for backwards compatibility but are now no-ops.
  1613   1624   ** </dl>
         1625  +**
         1626  +** [[SQLITE_CONFIG_SQLLOG]]
         1627  +** <dt>SQLITE_CONFIG_SQLLOG
         1628  +** <dd>This option is only available if sqlite is compiled with the
         1629  +** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
         1630  +** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
         1631  +** The second should be of type (void*). The callback is invoked by the library
         1632  +** in three separate circumstances, identified by the value passed as the
         1633  +** fourth parameter. If the fourth parameter is 0, then the database connection
         1634  +** passed as the second argument has just been opened. The third argument
         1635  +** points to a buffer containing the name of the main database file. If the
         1636  +** fourth parameter is 1, then the SQL statement that the third parameter
         1637  +** points to has just been executed. Or, if the fourth parameter is 2, then
         1638  +** the connection being passed as the second parameter is being closed. The
         1639  +** third parameter is passed NULL In this case.
         1640  +** </dl>
  1614   1641   */
  1615   1642   #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
  1616   1643   #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
  1617   1644   #define SQLITE_CONFIG_SERIALIZED    3  /* nil */
  1618   1645   #define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
  1619   1646   #define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
  1620   1647   #define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
................................................................................
  1628   1655   #define SQLITE_CONFIG_PCACHE       14  /* no-op */
  1629   1656   #define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
  1630   1657   #define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
  1631   1658   #define SQLITE_CONFIG_URI          17  /* int */
  1632   1659   #define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
  1633   1660   #define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
  1634   1661   #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
  1635         -#define SQLITE_CONFIG_READONLY     21  /* int */
         1662  +#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
         1663  +#define SQLITE_CONFIG_READONLY     22  /* int */
  1636   1664   
  1637   1665   /*
  1638   1666   ** CAPI3REF: Database Connection Configuration Options
  1639   1667   **
  1640   1668   ** These constants are the available integer configuration options that
  1641   1669   ** can be passed as the second argument to the [sqlite3_db_config()] interface.
  1642   1670   **

Changes to src/sqliteInt.h.

   823    823     Db *aDb;                      /* All backends */
   824    824     int nDb;                      /* Number of backends currently in use */
   825    825     int flags;                    /* Miscellaneous flags. See below */
   826    826     i64 lastRowid;                /* ROWID of most recent insert (see above) */
   827    827     unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
   828    828     int errCode;                  /* Most recent error code (SQLITE_*) */
   829    829     int errMask;                  /* & result codes with this before returning */
   830         -  u8 dbOptFlags;                /* Flags to enable/disable optimizations */
          830  +  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
   831    831     u8 autoCommit;                /* The auto-commit flag. */
   832    832     u8 temp_store;                /* 1: file 2: memory 0: default */
   833    833     u8 mallocFailed;              /* True if we have seen a malloc failure */
   834    834     u8 dfltLockMode;              /* Default locking-mode for attached dbs */
   835    835     signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
   836    836     u8 suppressErr;               /* Do not issue error messages if true */
   837    837     u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
................................................................................
   968    968   #define SQLITE_ColumnCache    0x0002   /* Column cache */
   969    969   #define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
   970    970   #define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
   971    971   #define SQLITE_IdxRealAsInt   0x0010   /* Store REAL as INT in indices */
   972    972   #define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
   973    973   #define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
   974    974   #define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
   975         -#define SQLITE_AllOpts        0x00ff   /* All optimizations */
          975  +#define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
          976  +#define SQLITE_AllOpts        0xffff   /* All optimizations */
   976    977   
   977    978   /*
   978    979   ** Macros for testing whether or not optimizations are enabled or disabled.
   979    980   */
   980    981   #ifndef SQLITE_OMIT_BUILTIN_TEST
   981    982   #define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
   982    983   #define OptimizationEnabled(db, mask)   (((db)->dbOptFlags&(mask))==0)
................................................................................
  1145   1146   #define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
  1146   1147   
  1147   1148   /*
  1148   1149   ** A "Collating Sequence" is defined by an instance of the following
  1149   1150   ** structure. Conceptually, a collating sequence consists of a name and
  1150   1151   ** a comparison routine that defines the order of that sequence.
  1151   1152   **
  1152         -** There may two separate implementations of the collation function, one
  1153         -** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
  1154         -** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
  1155         -** native byte order. When a collation sequence is invoked, SQLite selects
  1156         -** the version that will require the least expensive encoding
  1157         -** translations, if any.
  1158         -**
  1159         -** The CollSeq.pUser member variable is an extra parameter that passed in
  1160         -** as the first argument to the UTF-8 comparison function, xCmp.
  1161         -** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
  1162         -** xCmp16.
  1163         -**
  1164         -** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
         1153  +** If CollSeq.xCmp is NULL, it means that the
  1165   1154   ** collating sequence is undefined.  Indices built on an undefined
  1166   1155   ** collating sequence may not be read or written.
  1167   1156   */
  1168   1157   struct CollSeq {
  1169   1158     char *zName;          /* Name of the collating sequence, UTF-8 encoded */
  1170   1159     u8 enc;               /* Text encoding handled by xCmp() */
  1171   1160     void *pUser;          /* First argument to xCmp() */
................................................................................
  1874   1863       char *zName;      /* Name of the table */
  1875   1864       char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
  1876   1865       Table *pTab;      /* An SQL table corresponding to zName */
  1877   1866       Select *pSelect;  /* A SELECT statement used in place of a table name */
  1878   1867       int addrFillSub;  /* Address of subroutine to manifest a subquery */
  1879   1868       int regReturn;    /* Register holding return address of addrFillSub */
  1880   1869       u8 jointype;      /* Type of join between this able and the previous */
  1881         -    u8 notIndexed;    /* True if there is a NOT INDEXED clause */
  1882         -    u8 isCorrelated;  /* True if sub-query is correlated */
         1870  +    unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
         1871  +    unsigned isCorrelated :1;  /* True if sub-query is correlated */
         1872  +    unsigned viaCoroutine :1;  /* Implemented as a co-routine */
  1883   1873   #ifndef SQLITE_OMIT_EXPLAIN
  1884   1874       u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
  1885   1875   #endif
  1886   1876       int iCursor;      /* The VDBE cursor number used to access this table */
  1887   1877       Expr *pOn;        /* The ON clause of a join */
  1888   1878       IdList *pUsing;   /* The USING clause of a join */
  1889   1879       Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
................................................................................
  1961   1951         struct InLoop {
  1962   1952           int iCur;              /* The VDBE cursor used by this IN operator */
  1963   1953           int addrInTop;         /* Top of the IN loop */
  1964   1954         } *aInLoop;           /* Information about each nested IN operator */
  1965   1955       } in;                 /* Used when plan.wsFlags&WHERE_IN_ABLE */
  1966   1956       Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
  1967   1957     } u;
         1958  +  double rOptCost;      /* "Optimal" cost for this level */
  1968   1959   
  1969   1960     /* The following field is really not part of the current level.  But
  1970   1961     ** we need a place to cache virtual table index information for each
  1971   1962     ** virtual table in the FROM clause and the WhereLevel structure is
  1972   1963     ** a convenient place since there is one WhereLevel for each FROM clause
  1973   1964     ** element.
  1974   1965     */
................................................................................
  2099   2090     Expr *pOffset;         /* OFFSET expression. NULL means not used. */
  2100   2091   };
  2101   2092   
  2102   2093   /*
  2103   2094   ** Allowed values for Select.selFlags.  The "SF" prefix stands for
  2104   2095   ** "Select Flag".
  2105   2096   */
  2106         -#define SF_Distinct        0x01  /* Output should be DISTINCT */
  2107         -#define SF_Resolved        0x02  /* Identifiers have been resolved */
  2108         -#define SF_Aggregate       0x04  /* Contains aggregate functions */
  2109         -#define SF_UsesEphemeral   0x08  /* Uses the OpenEphemeral opcode */
  2110         -#define SF_Expanded        0x10  /* sqlite3SelectExpand() called on this */
  2111         -#define SF_HasTypeInfo     0x20  /* FROM subqueries have Table metadata */
  2112         -#define SF_UseSorter       0x40  /* Sort using a sorter */
  2113         -#define SF_Values          0x80  /* Synthesized from VALUES clause */
         2097  +#define SF_Distinct        0x0001  /* Output should be DISTINCT */
         2098  +#define SF_Resolved        0x0002  /* Identifiers have been resolved */
         2099  +#define SF_Aggregate       0x0004  /* Contains aggregate functions */
         2100  +#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
         2101  +#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
         2102  +#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
         2103  +#define SF_UseSorter       0x0040  /* Sort using a sorter */
         2104  +#define SF_Values          0x0080  /* Synthesized from VALUES clause */
         2105  +#define SF_Materialize     0x0100  /* Force materialization of views */
  2114   2106   
  2115   2107   
  2116   2108   /*
  2117   2109   ** The results of a select can be distributed in several ways.  The
  2118   2110   ** "SRT" prefix means "SELECT Result Type".
  2119   2111   */
  2120   2112   #define SRT_Union        1  /* Store result as keys in an index */
................................................................................
  2508   2500     int isMallocInit;                 /* True after malloc is initialized */
  2509   2501     int isPCacheInit;                 /* True after malloc is initialized */
  2510   2502     sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
  2511   2503     int nRefInitMutex;                /* Number of users of pInitMutex */
  2512   2504     void (*xLog)(void*,int,const char*); /* Function for logging */
  2513   2505     void *pLogArg;                       /* First argument to xLog() */
  2514   2506     int bLocaltimeFault;              /* True to fail localtime() calls */
         2507  +#ifdef SQLITE_ENABLE_SQLLOG
         2508  +  void(*xSqllog)(void*,sqlite3*,const char*, int);
         2509  +  void *pSqllogArg;
         2510  +#endif
  2515   2511   };
  2516   2512   
  2517   2513   /*
  2518   2514   ** Context pointer passed down through the tree-walk.
  2519   2515   */
  2520   2516   struct Walker {
  2521   2517     int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
................................................................................
  3242   3238   #define IN_INDEX_INDEX           3
  3243   3239   int sqlite3FindInIndex(Parse *, Expr *, int*);
  3244   3240   
  3245   3241   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
  3246   3242     int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
  3247   3243     int sqlite3JournalSize(sqlite3_vfs *);
  3248   3244     int sqlite3JournalCreate(sqlite3_file *);
         3245  +  int sqlite3JournalExists(sqlite3_file *p);
  3249   3246   #else
  3250   3247     #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
         3248  +  #define sqlite3JournalExists(p) 1
  3251   3249   #endif
  3252   3250   
  3253   3251   void sqlite3MemJournalOpen(sqlite3_file *);
  3254   3252   int sqlite3MemJournalSize(void);
  3255   3253   int sqlite3IsMemJournal(sqlite3_file *);
  3256   3254   
  3257   3255   #if SQLITE_MAX_EXPR_DEPTH>0

Changes to src/status.c.

   204    204       */
   205    205       case SQLITE_DBSTATUS_STMT_USED: {
   206    206         struct Vdbe *pVdbe;         /* Used to iterate through VMs */
   207    207         int nByte = 0;              /* Used to accumulate return value */
   208    208   
   209    209         db->pnBytesFreed = &nByte;
   210    210         for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
   211         -        sqlite3VdbeDeleteObject(db, pVdbe);
          211  +        sqlite3VdbeClearObject(db, pVdbe);
          212  +        sqlite3DbFree(db, pVdbe);
   212    213         }
   213    214         db->pnBytesFreed = 0;
   214    215   
   215    216         *pHighwater = 0;
   216    217         *pCurrent = nByte;
   217    218   
   218    219         break;

Changes to src/test1.c.

  5317   5317     }
  5318   5318     sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName);
  5319   5319     Tcl_AppendResult(interp, zVfsName, (char*)0);
  5320   5320     sqlite3_free(zVfsName);
  5321   5321     return TCL_OK;  
  5322   5322   }
  5323   5323   
         5324  +/*
         5325  +** tclcmd:   file_control_tempfilename DB ?AUXDB?
         5326  +**
         5327  +** Return a string that is a temporary filename
         5328  +*/
         5329  +static int file_control_tempfilename(
         5330  +  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
         5331  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         5332  +  int objc,              /* Number of arguments */
         5333  +  Tcl_Obj *CONST objv[]  /* Command arguments */
         5334  +){
         5335  +  sqlite3 *db;
         5336  +  const char *zDbName = "main";
         5337  +  char *zTName = 0;
         5338  +
         5339  +  if( objc!=2 && objc!=3 ){
         5340  +    Tcl_AppendResult(interp, "wrong # args: should be \"",
         5341  +        Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
         5342  +    return TCL_ERROR;
         5343  +  }
         5344  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
         5345  +    return TCL_ERROR;
         5346  +  }
         5347  +  if( objc==3 ){
         5348  +    zDbName = Tcl_GetString(objv[2]);
         5349  +  }
         5350  +  sqlite3_file_control(db, zDbName, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTName);
         5351  +  Tcl_AppendResult(interp, zTName, (char*)0);
         5352  +  sqlite3_free(zTName);
         5353  +  return TCL_OK;  
         5354  +}
         5355  +
  5324   5356   
  5325   5357   /*
  5326   5358   ** tclcmd:   sqlite3_vfs_list
  5327   5359   **
  5328   5360   **   Return a tcl list containing the names of all registered vfs's.
  5329   5361   */
  5330   5362   static int vfs_list(
................................................................................
  6146   6178        { "file_control_lockproxy_test", file_control_lockproxy_test,  0   },
  6147   6179        { "file_control_chunksize_test", file_control_chunksize_test,  0   },
  6148   6180        { "file_control_sizehint_test",  file_control_sizehint_test,   0   },
  6149   6181        { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
  6150   6182        { "file_control_persist_wal",    file_control_persist_wal,     0   },
  6151   6183        { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
  6152   6184        { "file_control_vfsname",        file_control_vfsname,         0   },
         6185  +     { "file_control_tempfilename",   file_control_tempfilename,    0   },
  6153   6186        { "sqlite3_vfs_list",           vfs_list,     0   },
  6154   6187        { "sqlite3_create_function_v2", test_create_function_v2, 0 },
  6155   6188   
  6156   6189        /* Functions from os.h */
  6157   6190   #ifndef SQLITE_OMIT_UTF16
  6158   6191        { "add_test_collate",        test_collate, 0            },
  6159   6192        { "add_test_collate_needed", test_collate_needed, 0     },

Changes to src/test6.c.

   308    308           u8 *zGarbage;
   309    309           int iFirst = (int)(pWrite->iOffset/g.iSectorSize);
   310    310           int iLast = (int)((pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize);
   311    311   
   312    312           assert(pWrite->zBuf);
   313    313   
   314    314   #ifdef TRACE_CRASHTEST
   315         -        printf("Trashing %d sectors @ sector %d (%s)\n", 
   316         -            1+iLast-iFirst, iFirst, pWrite->pFile->zName
          315  +        printf("Trashing %d sectors @ %lld (sector %d) (%s)\n", 
          316  +            1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName
   317    317           );
   318    318   #endif
   319    319   
   320    320           zGarbage = crash_malloc(g.iSectorSize);
   321    321           if( zGarbage ){
   322    322             sqlite3_int64 i;
   323    323             for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){
................................................................................
   624    624       pWrapper->nData = (4096 + pWrapper->iSize);
   625    625       pWrapper->zData = crash_malloc(pWrapper->nData);
   626    626       if( pWrapper->zData ){
   627    627         /* os_unix.c contains an assert() that fails if the caller attempts
   628    628         ** to read data from the 512-byte locking region of a file opened
   629    629         ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file
   630    630         ** never contains valid data anyhow. So avoid doing such a read here.
          631  +      **
          632  +      ** UPDATE: It also contains an assert() verifying that each call
          633  +      ** to the xRead() method reads less than 128KB of data.
   631    634         */
   632    635         const int isDb = (flags&SQLITE_OPEN_MAIN_DB);
   633         -      i64 iChunk = pWrapper->iSize;
   634         -      if( iChunk>PENDING_BYTE && isDb ){
   635         -        iChunk = PENDING_BYTE;
   636         -      }
          636  +      i64 iOff;
          637  +
   637    638         memset(pWrapper->zData, 0, pWrapper->nData);
   638         -      rc = sqlite3OsRead(pReal, pWrapper->zData, (int)iChunk, 0); 
   639         -      if( SQLITE_OK==rc && pWrapper->iSize>(PENDING_BYTE+512) && isDb ){
   640         -        i64 iOff = PENDING_BYTE+512;
   641         -        iChunk = pWrapper->iSize - iOff;
   642         -        rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], (int)iChunk, iOff);
          639  +      for(iOff=0; iOff<pWrapper->iSize; iOff += 512){
          640  +        int nRead = pWrapper->iSize - (int)iOff;
          641  +        if( nRead>512 ) nRead = 512;
          642  +        if( isDb && iOff==PENDING_BYTE ) continue;
          643  +        rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff);
   643    644         }
   644    645       }else{
   645    646         rc = SQLITE_NOMEM;
   646    647       }
   647    648     }
   648    649     if( rc!=SQLITE_OK && pWrapper->pMethod ){
   649    650       sqlite3OsClose(pFile);

Changes to src/test_intarray.h.

    72     72   ** virtual table is dropped.  Since the virtual tables are created in the
    73     73   ** TEMP database, they are automatically dropped when the database connection
    74     74   ** closes so the application does not normally need to take any special
    75     75   ** action to free the intarray objects.
    76     76   */
    77     77   #include "sqlite3.h"
    78     78   
           79  +/*
           80  +** Make sure we can call this stuff from C++.
           81  +*/
           82  +#ifdef __cplusplus
           83  +extern "C" {
           84  +#endif
           85  +
    79     86   /*
    80     87   ** An sqlite3_intarray is an abstract type to stores an instance of
    81     88   ** an integer array.
    82     89   */
    83     90   typedef struct sqlite3_intarray sqlite3_intarray;
    84     91   
    85     92   /*
................................................................................
   108    115   */
   109    116   int sqlite3_intarray_bind(
   110    117     sqlite3_intarray *pIntArray,   /* The intarray object to bind to */
   111    118     int nElements,                 /* Number of elements in the intarray */
   112    119     sqlite3_int64 *aElements,      /* Content of the intarray */
   113    120     void (*xFree)(void*)           /* How to dispose of the intarray when done */
   114    121   );
          122  +
          123  +#ifdef __cplusplus
          124  +}  /* End of the 'extern "C"' block */
          125  +#endif

Changes to src/test_malloc.c.

   716    716     if( objc!=2 ){
   717    717       Tcl_WrongNumArgs(interp, 1, objv, "TITLE");
   718    718       return TCL_ERROR;
   719    719     }
   720    720   #ifdef SQLITE_MEMDEBUG
   721    721     {
   722    722       const char *zTitle;
   723         -    zTitle = Tcl_GetString(objv[1]);
   724    723       extern int sqlite3MemdebugSettitle(const char*);
          724  +    zTitle = Tcl_GetString(objv[1]);
   725    725       sqlite3MemdebugSettitle(zTitle);
   726    726     }
   727    727   #endif
   728    728     return TCL_OK;
   729    729   }
   730    730   
   731    731   #define MALLOC_LOG_FRAMES  10 

Changes to src/test_multiplex.h.

    42     42   **   This file control is used to set the maximum number of chunks
    43     43   **   allowed to be used for a mutliplex file set.
    44     44   */
    45     45   #define MULTIPLEX_CTRL_ENABLE          214014
    46     46   #define MULTIPLEX_CTRL_SET_CHUNK_SIZE  214015
    47     47   #define MULTIPLEX_CTRL_SET_MAX_CHUNKS  214016
    48     48   
           49  +#ifdef __cplusplus
           50  +extern "C" {
           51  +#endif
           52  +
    49     53   /*
    50     54   ** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize()
    51     55   **
    52     56   ** Use the VFS named zOrigVfsName as the VFS that does the actual work.  
    53     57   ** Use the default if zOrigVfsName==NULL.  
    54     58   **
    55     59   ** The multiplex VFS shim is named "multiplex".  It will become the default
................................................................................
    83     87   ** All SQLite database connections must be closed before calling this
    84     88   ** routine.
    85     89   **
    86     90   ** THIS ROUTINE IS NOT THREADSAFE.  Call this routine exactly once while
    87     91   ** shutting down in order to free all remaining multiplex groups.
    88     92   */
    89     93   extern int sqlite3_multiplex_shutdown(void);
           94  +
           95  +#ifdef __cplusplus
           96  +}  /* End of the 'extern "C"' block */
           97  +#endif
    90     98   
    91     99   #endif

Changes to src/test_quota.c.

  1175   1175       pGroup->iSize += szNew - pFile->iSize;
  1176   1176       quotaLeave();
  1177   1177     }
  1178   1178   #if SQLITE_OS_UNIX
  1179   1179     rc = ftruncate(fileno(p->f), szNew);
  1180   1180   #endif
  1181   1181   #if SQLITE_OS_WIN
  1182         -  rc = _chsize_s(_fileno(p->f), szNew);
         1182  +#  if defined(__MINGW32__) && defined(SQLITE_TEST)
         1183  +     /* _chsize_s() is missing from MingW (as of 2012-11-06).  Use
         1184  +     ** _chsize() as a work-around for testing purposes. */
         1185  +     rc = _chsize(_fileno(p->f), (long)szNew);
         1186  +#  else
         1187  +     rc = _chsize_s(_fileno(p->f), szNew);
         1188  +#  endif
  1183   1189   #endif
  1184   1190     if( pFile && rc==0 ){
  1185   1191       quotaGroup *pGroup = pFile->pGroup;
  1186   1192       quotaEnter();
  1187   1193       pGroup->iSize += szNew - pFile->iSize;
  1188   1194       pFile->iSize = szNew;
  1189   1195       quotaLeave();

Added src/test_sqllog.c.

            1  +/*
            2  +** 2012 November 26
            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  +** OVERVIEW
           14  +**
           15  +**   This file contains experimental code used to record data from live
           16  +**   SQLite applications that may be useful for offline analysis. Specifically:
           17  +**
           18  +**     1) The initial contents of all database files opened by the 
           19  +**        application, and
           20  +**
           21  +**     2) All SQL statements executed by the application.
           22  +**
           23  +** USAGE
           24  +**
           25  +**   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.
           28  +**
           29  +**   At runtime, logging is enabled by setting environment variable
           30  +**   SQLITE_SQLLOG_DIR to the name of a directory in which to store logged 
           31  +**   data. The directory must already exist.
           32  +**
           33  +**   Usually, if the application opens the same database file more than once
           34  +**   (either by attaching it or by using more than one database handle), only
           35  +**   a single copy is made. This behaviour may be overridden (so that a 
           36  +**   separate copy is taken each time the database file is opened or attached)
           37  +**   by setting the environment variable SQLITE_SQLLOG_REUSE_FILES to 0.
           38  +**
           39  +** OUTPUT:
           40  +**
           41  +**   The SQLITE_SQLLOG_DIR is populated with three types of files:
           42  +**
           43  +**      sqllog_N.db   - Copies of database files. N may be any integer.
           44  +**
           45  +**      sqllog_N.sql  - A list of SQL statements executed by a single
           46  +**                      connection. N may be any integer.
           47  +**
           48  +**      sqllog.idx    - An index mapping from integer N to a database
           49  +**                      file name - indicating the full path of the
           50  +**                      database from which sqllog_N.db was copied.
           51  +**
           52  +** ERROR HANDLING:
           53  +**
           54  +**   This module attempts to make a best effort to continue logging if an
           55  +**   IO or other error is encountered. For example, if a log file cannot 
           56  +**   be opened logs are not collected for that connection, but other
           57  +**   logging proceeds as expected. Errors are logged by calling sqlite3_log().
           58  +*/
           59  +
           60  +#include "sqlite3.h"
           61  +#include "stdio.h"
           62  +#include "stdlib.h"
           63  +#include "string.h"
           64  +#include "assert.h"
           65  +
           66  +#include "sys/types.h"
           67  +#include "unistd.h"
           68  +static int getProcessId(void){
           69  +#if SQLITE_OS_WIN
           70  +  return (int)_getpid();
           71  +#else
           72  +  return (int)getpid();
           73  +#endif
           74  +}
           75  +
           76  +
           77  +#define ENVIRONMENT_VARIABLE1_NAME "SQLITE_SQLLOG_DIR"
           78  +#define ENVIRONMENT_VARIABLE2_NAME "SQLITE_SQLLOG_REUSE_FILES"
           79  +
           80  +/* Assume that all database and database file names are shorted than this. */
           81  +#define SQLLOG_NAMESZ 512
           82  +
           83  +/* Maximum number of simultaneous database connections the process may
           84  +** open (if any more are opened an error is logged using sqlite3_log()
           85  +** and processing is halted).
           86  +*/
           87  +#define MAX_CONNECTIONS 256
           88  +
           89  +struct SLConn {
           90  +  int isErr;                      /* True if an error has occurred */
           91  +  sqlite3 *db;                    /* Connection handle */
           92  +  int iLog;                       /* First integer value used in file names */
           93  +  FILE *fd;                       /* File descriptor for log file */
           94  +};
           95  +
           96  +struct SLGlobal {
           97  +  /* Protected by MUTEX_STATIC_MASTER */
           98  +  sqlite3_mutex *mutex;           /* Recursive mutex */
           99  +  int nConn;                      /* Size of aConn[] array */
          100  +
          101  +  /* Protected by SLGlobal.mutex */
          102  +  int bReuse;                     /* True to avoid extra copies of db files */
          103  +  char zPrefix[SQLLOG_NAMESZ];    /* Prefix for all created files */
          104  +  char zIdx[SQLLOG_NAMESZ];       /* Full path to *.idx file */
          105  +  int iNextLog;                   /* Used to allocate file names */
          106  +  int iNextDb;                    /* Used to allocate database file names */
          107  +  int bRec;                       /* True if testSqllog() is called rec. */
          108  +  int iClock;                     /* Clock value */
          109  +  struct SLConn aConn[MAX_CONNECTIONS];
          110  +} sqllogglobal;
          111  +
          112  +/*
          113  +** Return true if c is an ASCII whitespace character.
          114  +*/
          115  +static int sqllog_isspace(char c){
          116  +  return (c==' ' || c=='\t' || c=='\n' || c=='\v' || c=='\f' || c=='\r');
          117  +}
          118  +
          119  +/*
          120  +** The first argument points to a nul-terminated string containing an SQL
          121  +** command. Before returning, this function sets *pz to point to the start
          122  +** of the first token in this command, and *pn to the number of bytes in 
          123  +** the token. This is used to check if the SQL command is an "ATTACH" or 
          124  +** not.
          125  +*/
          126  +static void sqllogTokenize(const char *z, const char **pz, int *pn){
          127  +  const char *p = z;
          128  +  int n;
          129  +
          130  +  /* Skip past any whitespace */
          131  +  while( sqllog_isspace(*p) ){
          132  +    p++;
          133  +  }
          134  +
          135  +  /* Figure out how long the first token is */
          136  +  *pz = p;
          137  +  n = 0;
          138  +  while( (p[n]>='a' && p[n]<='z') || (p[n]>='A' && p[n]<='Z') ) n++;
          139  +  *pn = n;
          140  +}
          141  +
          142  +/*
          143  +** Check if the logs directory already contains a copy of database file 
          144  +** zFile. If so, return a pointer to the full path of the copy. Otherwise,
          145  +** return NULL.
          146  +**
          147  +** If a non-NULL value is returned, then the caller must arrange to 
          148  +** eventually free it using sqlite3_free().
          149  +*/
          150  +static char *sqllogFindFile(const char *zFile){
          151  +  char *zRet = 0;
          152  +  FILE *fd = 0;
          153  +
          154  +  /* Open the index file for reading */
          155  +  fd = fopen(sqllogglobal.zIdx, "r");
          156  +  if( fd==0 ){
          157  +    sqlite3_log(SQLITE_IOERR, "sqllogFindFile(): error in fopen()");
          158  +    return 0;
          159  +  }
          160  +
          161  +  /* Loop through each entry in the index file. If zFile is not NULL and the
          162  +  ** entry is a match, then set zRet to point to the filename of the existing
          163  +  ** copy and break out of the loop.  */
          164  +  while( feof(fd)==0 ){
          165  +    char zLine[SQLLOG_NAMESZ*2+5];
          166  +    if( fgets(zLine, sizeof(zLine), fd) ){
          167  +      int n;
          168  +      char *z;
          169  +
          170  +      zLine[sizeof(zLine)-1] = '\0';
          171  +      z = zLine;
          172  +      while( *z>='0' && *z<='9' ) z++;
          173  +      while( *z==' ' ) z++;
          174  +
          175  +      n = strlen(z);
          176  +      while( n>0 && sqllog_isspace(z[n-1]) ) n--;
          177  +
          178  +      if( n==strlen(zFile) && 0==memcmp(zFile, z, n) ){
          179  +        char zBuf[16];
          180  +        memset(zBuf, 0, sizeof(zBuf));
          181  +        z = zLine;
          182  +        while( *z>='0' && *z<='9' ){
          183  +          zBuf[z-zLine] = *z;
          184  +          z++;
          185  +        }
          186  +        zRet = sqlite3_mprintf("%s_%s.db", sqllogglobal.zPrefix, zBuf);
          187  +        break;
          188  +      }
          189  +    }
          190  +  }
          191  +
          192  +  if( ferror(fd) ){
          193  +    sqlite3_log(SQLITE_IOERR, "sqllogFindFile(): error reading index file");
          194  +  }
          195  +
          196  +  fclose(fd);
          197  +  return zRet;
          198  +}
          199  +
          200  +static int sqllogFindAttached(
          201  +  struct SLConn *p,               /* Database connection */
          202  +  const char *zSearch,            /* Name to search for (or NULL) */
          203  +  char *zName,                    /* OUT: Name of attached database */
          204  +  char *zFile                     /* OUT: Name of attached file */
          205  +){
          206  +  sqlite3_stmt *pStmt;
          207  +  int rc;
          208  +
          209  +  /* The "PRAGMA database_list" command returns a list of databases in the
          210  +  ** order that they were attached. So a newly attached database is 
          211  +  ** described by the last row returned.  */
          212  +  assert( sqllogglobal.bRec==0 );
          213  +  sqllogglobal.bRec = 1;
          214  +  rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
          215  +  if( rc==SQLITE_OK ){
          216  +    while( SQLITE_ROW==sqlite3_step(pStmt) ){
          217  +      const char *zVal1; int nVal1;
          218  +      const char *zVal2; int nVal2;
          219  +
          220  +      zVal1 = (const char*)sqlite3_column_text(pStmt, 1);
          221  +      nVal1 = sqlite3_column_bytes(pStmt, 1);
          222  +      memcpy(zName, zVal1, nVal1+1);
          223  +
          224  +      zVal2 = (const char*)sqlite3_column_text(pStmt, 2);
          225  +      nVal2 = sqlite3_column_bytes(pStmt, 2);
          226  +      memcpy(zFile, zVal2, nVal2+1);
          227  +
          228  +      if( zSearch && strlen(zSearch)==nVal1 
          229  +       && 0==sqlite3_strnicmp(zSearch, zVal1, nVal1)
          230  +      ){
          231  +        break;
          232  +      }
          233  +    }
          234  +    rc = sqlite3_finalize(pStmt);
          235  +  }
          236  +  sqllogglobal.bRec = 0;
          237  +
          238  +  if( rc!=SQLITE_OK ){
          239  +    sqlite3_log(rc, "sqllogFindAttached(): error in \"PRAGMA database_list\"");
          240  +  }
          241  +  return rc;
          242  +}
          243  +
          244  +
          245  +/*
          246  +** Parameter zSearch is the name of a database attached to the database 
          247  +** connection associated with the first argument. This function creates
          248  +** a backup of this database in the logs directory.
          249  +**
          250  +** The name used for the backup file is automatically generated. Call
          251  +** it zFile.
          252  +**
          253  +** If the bLog parameter is true, then a statement of the following form
          254  +** is written to the log file associated with *p:
          255  +**
          256  +**    ATTACH 'zFile' AS 'zName';
          257  +**
          258  +** Otherwise, if bLog is false, a comment is added to the log file:
          259  +**
          260  +**    -- Main database file is 'zFile'
          261  +**
          262  +** The SLGlobal.mutex mutex is always held when this function is called.
          263  +*/
          264  +static void sqllogCopydb(struct SLConn *p, const char *zSearch, int bLog){
          265  +  char zName[SQLLOG_NAMESZ];      /* Attached database name */
          266  +  char zFile[SQLLOG_NAMESZ];      /* Database file name */
          267  +  char *zFree;
          268  +  char *zInit = 0;
          269  +  int rc;
          270  +
          271  +  rc = sqllogFindAttached(p, zSearch, zName, zFile);
          272  +  if( rc!=SQLITE_OK ) return;
          273  +
          274  +  if( zFile[0]=='\0' ){
          275  +    zInit = sqlite3_mprintf("");
          276  +  }else{
          277  +    if( sqllogglobal.bReuse ){
          278  +      zInit = sqllogFindFile(zFile);
          279  +    }else{
          280  +      zInit = 0;
          281  +    }
          282  +    if( zInit==0 ){
          283  +      int rc;
          284  +      sqlite3 *copy = 0;
          285  +      int iDb;
          286  +
          287  +      /* Generate a file-name to use for the copy of this database */
          288  +      iDb = sqllogglobal.iNextDb++;
          289  +      zInit = sqlite3_mprintf("%s_%d.db", sqllogglobal.zPrefix, iDb);
          290  +
          291  +      /* Create the backup */
          292  +      assert( sqllogglobal.bRec==0 );
          293  +      sqllogglobal.bRec = 1;
          294  +      rc = sqlite3_open(zInit, &copy);
          295  +      if( rc==SQLITE_OK ){
          296  +        sqlite3_backup *pBak;
          297  +        sqlite3_exec(copy, "PRAGMA synchronous = 0", 0, 0, 0);
          298  +        pBak = sqlite3_backup_init(copy, "main", p->db, zName);
          299  +        if( pBak ){
          300  +          sqlite3_backup_step(pBak, -1);
          301  +          rc = sqlite3_backup_finish(pBak);
          302  +        }else{
          303  +          rc = sqlite3_errcode(copy);
          304  +        }
          305  +        sqlite3_close(copy);
          306  +      }
          307  +      sqllogglobal.bRec = 0;
          308  +
          309  +      if( rc==SQLITE_OK ){
          310  +        /* Write an entry into the database index file */
          311  +        FILE *fd = fopen(sqllogglobal.zIdx, "a");
          312  +        if( fd ){
          313  +          fprintf(fd, "%d %s\n", iDb, zFile);
          314  +          fclose(fd);
          315  +        }
          316  +      }else{
          317  +        sqlite3_log(rc, "sqllogCopydb(): error backing up database");
          318  +      }
          319  +    }
          320  +  }
          321  +
          322  +  if( bLog ){
          323  +    zFree = sqlite3_mprintf("ATTACH '%q' AS '%q'; -- clock=%d\n", 
          324  +        zInit, zName, sqllogglobal.iClock++
          325  +    );
          326  +  }else{
          327  +    zFree = sqlite3_mprintf("-- Main database is '%q'\n", zInit);
          328  +  }
          329  +  fprintf(p->fd, "%s", zFree);
          330  +  sqlite3_free(zFree);
          331  +
          332  +  sqlite3_free(zInit);
          333  +}
          334  +
          335  +/*
          336  +** If it is not already open, open the log file for connection *p. 
          337  +**
          338  +** The SLGlobal.mutex mutex is always held when this function is called.
          339  +*/
          340  +static void sqllogOpenlog(struct SLConn *p){
          341  +  /* If the log file has not yet been opened, open it now. */
          342  +  if( p->fd==0 ){
          343  +    char *zLog;
          344  +
          345  +    /* If it is still NULL, have global.zPrefix point to a copy of 
          346  +    ** environment variable $ENVIRONMENT_VARIABLE1_NAME.  */
          347  +    if( sqllogglobal.zPrefix[0]==0 ){
          348  +      FILE *fd;
          349  +      char *zVar = getenv(ENVIRONMENT_VARIABLE1_NAME);
          350  +      if( zVar==0 || strlen(zVar)+10>=(sizeof(sqllogglobal.zPrefix)) ) return;
          351  +      sprintf(sqllogglobal.zPrefix, "%s/sqllog_%d", zVar, getProcessId());
          352  +      sprintf(sqllogglobal.zIdx, "%s.idx", sqllogglobal.zPrefix);
          353  +      if( getenv(ENVIRONMENT_VARIABLE2_NAME) ){
          354  +        sqllogglobal.bReuse = atoi(getenv(ENVIRONMENT_VARIABLE2_NAME));
          355  +      }
          356  +      fd = fopen(sqllogglobal.zIdx, "w");
          357  +      if( fd ) fclose(fd);
          358  +    }
          359  +
          360  +    /* Open the log file */
          361  +    zLog = sqlite3_mprintf("%s_%d.sql", sqllogglobal.zPrefix, p->iLog);
          362  +    p->fd = fopen(zLog, "w");
          363  +    sqlite3_free(zLog);
          364  +    if( p->fd==0 ){
          365  +      sqlite3_log(SQLITE_IOERR, "sqllogOpenlog(): Failed to open log file");
          366  +    }
          367  +  }
          368  +}
          369  +
          370  +/*
          371  +** This function is called if the SQLLOG callback is invoked to report
          372  +** execution of an SQL statement. Parameter p is the connection the statement
          373  +** was executed by and parameter zSql is the text of the statement itself.
          374  +*/
          375  +static void testSqllogStmt(struct SLConn *p, const char *zSql){
          376  +  const char *zFirst;             /* Pointer to first token in zSql */
          377  +  int nFirst;                     /* Size of token zFirst in bytes */
          378  +
          379  +  sqllogTokenize(zSql, &zFirst, &nFirst);
          380  +  if( nFirst!=6 || 0!=sqlite3_strnicmp("ATTACH", zFirst, 6) ){
          381  +    /* Not an ATTACH statement. Write this directly to the log. */
          382  +    fprintf(p->fd, "%s; -- clock=%d\n", zSql, sqllogglobal.iClock++);
          383  +  }else{
          384  +    /* This is an ATTACH statement. Copy the database. */
          385  +    sqllogCopydb(p, 0, 1);
          386  +  }
          387  +}
          388  +
          389  +/*
          390  +** The SQLITE_CONFIG_SQLLOG callback registered by sqlite3_init_sqllog().
          391  +*/
          392  +static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){
          393  +  struct SLConn *p = 0;
          394  +  sqlite3_mutex *master = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
          395  +
          396  +  assert( eType==0 || eType==1 || eType==2 );
          397  +  assert( (eType==2)==(zSql==0) );
          398  +
          399  +  /* This is a database open command. */
          400  +  if( eType==0 ){
          401  +    sqlite3_mutex_enter(master);
          402  +    if( sqllogglobal.mutex==0 ){
          403  +      sqllogglobal.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
          404  +    }
          405  +    p = &sqllogglobal.aConn[sqllogglobal.nConn++];
          406  +    p->fd = 0;
          407  +    p->db = db;
          408  +    p->iLog = sqllogglobal.iNextLog++;
          409  +    sqlite3_mutex_leave(master);
          410  +
          411  +    /* Open the log and take a copy of the main database file */
          412  +    sqlite3_mutex_enter(sqllogglobal.mutex);
          413  +    if( sqllogglobal.bRec==0 ){
          414  +      sqllogOpenlog(p);
          415  +      if( p->fd ) sqllogCopydb(p, "main", 0);
          416  +    }
          417  +    sqlite3_mutex_leave(sqllogglobal.mutex);
          418  +  }
          419  +
          420  +  else{
          421  +
          422  +    int i;
          423  +    for(i=0; i<sqllogglobal.nConn; i++){
          424  +      p = &sqllogglobal.aConn[i];
          425  +      if( p->db==db ) break;
          426  +    }
          427  +    if( i==sqllogglobal.nConn ) return;
          428  +
          429  +    /* A database handle close command */
          430  +    if( eType==2 ){
          431  +      sqlite3_mutex_enter(master);
          432  +      if( p->fd ) fclose(p->fd);
          433  +      p->db = 0;
          434  +      p->fd = 0;
          435  +
          436  +      sqllogglobal.nConn--;
          437  +      if( sqllogglobal.nConn==0 ){
          438  +        sqlite3_mutex_free(sqllogglobal.mutex);
          439  +        sqllogglobal.mutex = 0;
          440  +      }else{
          441  +        int nShift = &sqllogglobal.aConn[sqllogglobal.nConn] - p;
          442  +        if( nShift>0 ){
          443  +          memmove(p, &p[1], nShift*sizeof(struct SLConn));
          444  +        }
          445  +      }
          446  +      sqlite3_mutex_leave(master);
          447  +
          448  +    /* An ordinary SQL command. */
          449  +    }else if( p->fd ){
          450  +      sqlite3_mutex_enter(sqllogglobal.mutex);
          451  +      if( sqllogglobal.bRec==0 ){
          452  +        testSqllogStmt(p, zSql);
          453  +      }
          454  +      sqlite3_mutex_leave(sqllogglobal.mutex);
          455  +    }
          456  +  }
          457  +}
          458  +
          459  +/*
          460  +** This function is called either before sqlite3_initialized() or by it.
          461  +** It checks if the SQLITE_SQLLOG_DIR variable is defined, and if so 
          462  +** registers an SQLITE_CONFIG_SQLLOG callback to record the applications
          463  +** database activity.
          464  +*/
          465  +void sqlite3_init_sqllog(void){
          466  +  if( getenv(ENVIRONMENT_VARIABLE1_NAME) ){
          467  +    if( SQLITE_OK==sqlite3_config(SQLITE_CONFIG_SQLLOG, testSqllog, 0) ){
          468  +      memset(&sqllogglobal, 0, sizeof(sqllogglobal));
          469  +      sqllogglobal.bReuse = 1;
          470  +    }
          471  +  }
          472  +}

Changes to src/test_vfstrace.c.

   471    471       }
   472    472       case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER";       break;
   473    473       case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED";       break;
   474    474       case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY";   break;
   475    475       case SQLITE_FCNTL_PERSIST_WAL:  zOp = "PERSIST_WAL";        break;
   476    476       case SQLITE_FCNTL_OVERWRITE:    zOp = "OVERWRITE";          break;
   477    477       case SQLITE_FCNTL_VFSNAME:      zOp = "VFSNAME";            break;
          478  +    case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME";       break;
   478    479       case 0xca093fa0:                zOp = "DB_UNCHANGED";       break;
   479    480       case SQLITE_FCNTL_PRAGMA: {
   480    481         const char *const* a = (const char*const*)pArg;
   481    482         sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
   482    483         zOp = zBuf;
   483    484         break;
   484    485       }
................................................................................
   492    493                     pInfo->zVfsName, p->zFName, zOp);
   493    494     rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
   494    495     vfstrace_print_errcode(pInfo, " -> %s\n", rc);
   495    496     if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
   496    497       *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
   497    498                                       pInfo->zVfsName, *(char**)pArg);
   498    499     }
   499         -  if( op==SQLITE_FCNTL_PRAGMA && rc==SQLITE_OK && *(char**)pArg ){
          500  +  if( (op==SQLITE_FCNTL_PRAGMA || op==SQLITE_FCNTL_TEMPFILENAME)
          501  +   && rc==SQLITE_OK && *(char**)pArg ){
   500    502       vfstrace_printf(pInfo, "%s.xFileControl(%s,%s) returns %s",
   501    503                       pInfo->zVfsName, p->zFName, zOp, *(char**)pArg);
   502    504     }
   503    505     return rc;
   504    506   }
   505    507   
   506    508   /*

Changes to src/trigger.c.

   724    724       **     INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
   725    725       **   END;
   726    726       **
   727    727       **   INSERT INTO t1 ... ;            -- insert into t2 uses REPLACE policy
   728    728       **   INSERT OR IGNORE INTO t1 ... ;  -- insert into t2 uses IGNORE policy
   729    729       */
   730    730       pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
          731  +
          732  +    /* Clear the cookieGoto flag. When coding triggers, the cookieGoto 
          733  +    ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
          734  +    ** that it is not safe to refactor constants (this happens after the
          735  +    ** start of the first loop in the SQL statement is coded - at that 
          736  +    ** point code may be conditionally executed, so it is no longer safe to 
          737  +    ** initialize constant register values).  */
          738  +    assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
          739  +    pParse->cookieGoto = 0;
   731    740   
   732    741       switch( pStep->op ){
   733    742         case TK_UPDATE: {
   734    743           sqlite3Update(pParse, 
   735    744             targetSrcList(pParse, pStep),
   736    745             sqlite3ExprListDup(db, pStep->pExprList, 0), 
   737    746             sqlite3ExprDup(db, pStep->pWhere, 0), 

Changes to src/vdbe.c.

  2233   2233       }else{
  2234   2234         assert( sqlite3BtreeCursorIsValid(pCrsr) );
  2235   2235         VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &payloadSize);
  2236   2236         assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
  2237   2237       }
  2238   2238     }else if( ALWAYS(pC->pseudoTableReg>0) ){
  2239   2239       pReg = &aMem[pC->pseudoTableReg];
         2240  +    if( pC->multiPseudo ){
         2241  +      sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem);
         2242  +      Deephemeralize(pDest);
         2243  +      goto op_column_out;
         2244  +    }
  2240   2245       assert( pReg->flags & MEM_Blob );
  2241   2246       assert( memIsValid(pReg) );
  2242   2247       payloadSize = pReg->n;
  2243   2248       zRec = pReg->z;
  2244   2249       pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
  2245   2250       assert( payloadSize==0 || zRec!=0 );
  2246   2251     }else{
................................................................................
  3291   3296       }
  3292   3297     }
  3293   3298     pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
  3294   3299     pCx->isIndex = !pCx->isTable;
  3295   3300     break;
  3296   3301   }
  3297   3302   
  3298         -/* Opcode: OpenSorter P1 P2 * P4 *
         3303  +/* Opcode: SorterOpen P1 P2 * P4 *
  3299   3304   **
  3300   3305   ** This opcode works like OP_OpenEphemeral except that it opens
  3301   3306   ** a transient index that is specifically designed to sort large
  3302   3307   ** tables using an external merge-sort algorithm.
  3303   3308   */
  3304   3309   case OP_SorterOpen: {
  3305   3310     VdbeCursor *pCx;
................................................................................
  3314   3319   #else
  3315   3320     pOp->opcode = OP_OpenEphemeral;
  3316   3321     pc--;
  3317   3322   #endif
  3318   3323     break;
  3319   3324   }
  3320   3325   
  3321         -/* Opcode: OpenPseudo P1 P2 P3 * *
         3326  +/* Opcode: OpenPseudo P1 P2 P3 * P5
  3322   3327   **
  3323   3328   ** Open a new cursor that points to a fake table that contains a single
  3324   3329   ** row of data.  The content of that one row in the content of memory
  3325         -** register P2.  In other words, cursor P1 becomes an alias for the 
  3326         -** MEM_Blob content contained in register P2.
         3330  +** register P2 when P5==0.  In other words, cursor P1 becomes an alias for the 
         3331  +** MEM_Blob content contained in register P2.  When P5==1, then the
         3332  +** row is represented by P3 consecutive registers beginning with P2.
  3327   3333   **
  3328   3334   ** A pseudo-table created by this opcode is used to hold a single
  3329   3335   ** row output from the sorter so that the row can be decomposed into
  3330   3336   ** individual columns using the OP_Column opcode.  The OP_Column opcode
  3331   3337   ** is the only cursor opcode that works with a pseudo-table.
  3332   3338   **
  3333   3339   ** P3 is the number of fields in the records that will be stored by
................................................................................
  3339   3345     assert( pOp->p1>=0 );
  3340   3346     pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
  3341   3347     if( pCx==0 ) goto no_mem;
  3342   3348     pCx->nullRow = 1;
  3343   3349     pCx->pseudoTableReg = pOp->p2;
  3344   3350     pCx->isTable = 1;
  3345   3351     pCx->isIndex = 0;
         3352  +  pCx->multiPseudo = pOp->p5;
  3346   3353     break;
  3347   3354   }
  3348   3355   
  3349   3356   /* Opcode: Close P1 * * * *
  3350   3357   **
  3351   3358   ** Close a cursor previously opened as P1.  If P1 is not
  3352   3359   ** currently open, this instruction is a no-op.
................................................................................
  4303   4310     i64 v;
  4304   4311     sqlite3_vtab *pVtab;
  4305   4312     const sqlite3_module *pModule;
  4306   4313   
  4307   4314     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4308   4315     pC = p->apCsr[pOp->p1];
  4309   4316     assert( pC!=0 );
  4310         -  assert( pC->pseudoTableReg==0 );
         4317  +  assert( pC->pseudoTableReg==0 || pC->nullRow );
  4311   4318     if( pC->nullRow ){
  4312   4319       pOut->flags = MEM_Null;
  4313   4320       break;
  4314   4321     }else if( pC->deferredMoveto ){
  4315   4322       v = pC->movetoTarget;
  4316   4323   #ifndef SQLITE_OMIT_VIRTUALTABLE
  4317   4324     }else if( pC->pVtabCursor ){

Changes to src/vdbe.h.

   184    184   void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
   185    185   void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
   186    186   void sqlite3VdbeUsesBtree(Vdbe*, int);
   187    187   VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
   188    188   int sqlite3VdbeMakeLabel(Vdbe*);
   189    189   void sqlite3VdbeRunOnlyOnce(Vdbe*);
   190    190   void sqlite3VdbeDelete(Vdbe*);
   191         -void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*);
          191  +void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
   192    192   void sqlite3VdbeMakeReady(Vdbe*,Parse*);
   193    193   int sqlite3VdbeFinalize(Vdbe*);
   194    194   void sqlite3VdbeResolveLabel(Vdbe*, int);
   195    195   int sqlite3VdbeCurrentAddr(Vdbe*);
   196    196   #ifdef SQLITE_DEBUG
   197    197     int sqlite3VdbeAssertMayAbort(Vdbe *, int);
   198    198     void sqlite3VdbeTrace(Vdbe*,FILE*);

Changes to src/vdbeInt.h.

    59     59     Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
    60     60     Bool nullRow;         /* True if pointing to a row with no data */
    61     61     Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
    62     62     Bool isTable;         /* True if a table requiring integer keys */
    63     63     Bool isIndex;         /* True if an index containing keys only - no data */
    64     64     Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
    65     65     Bool isSorter;        /* True if a new-style sorter */
           66  +  Bool multiPseudo;     /* Multi-register pseudo-cursor */
    66     67     sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
    67     68     const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
    68     69     i64 seqCount;         /* Sequence counter */
    69     70     i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
    70     71     i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
    71     72     VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
    72     73   

Changes to src/vdbeaux.c.

    49     49   
    50     50   /*
    51     51   ** Remember the SQL string for a prepared statement.
    52     52   */
    53     53   void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
    54     54     assert( isPrepareV2==1 || isPrepareV2==0 );
    55     55     if( p==0 ) return;
    56         -#ifdef SQLITE_OMIT_TRACE
           56  +#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
    57     57     if( !isPrepareV2 ) return;
    58     58   #endif
    59     59     assert( p->zSql==0 );
    60     60     p->zSql = sqlite3DbStrNDup(p->db, z, n);
    61     61     p->isPrepareV2 = (u8)isPrepareV2;
    62     62   }
    63     63   
................................................................................
   719    719     }
   720    720     assert( p->nOp>0 );
   721    721     assert( addr<p->nOp );
   722    722     if( addr<0 ){
   723    723       addr = p->nOp - 1;
   724    724     }
   725    725     pOp = &p->aOp[addr];
          726  +  assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
   726    727     freeP4(db, pOp->p4type, pOp->p4.p);
   727    728     pOp->p4.p = 0;
   728    729     if( n==P4_INT32 ){
   729    730       /* Note: this cast is safe, because the origin data point was an int
   730    731       ** that was cast to a (const char *). */
   731    732       pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
   732    733       pOp->p4type = P4_INT32;
................................................................................
  2322   2323       db->errCode = rc;
  2323   2324     }else{
  2324   2325       sqlite3Error(db, rc, 0);
  2325   2326     }
  2326   2327     return rc;
  2327   2328   }
  2328   2329   
         2330  +#ifdef SQLITE_ENABLE_SQLLOG
         2331  +/*
         2332  +** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, 
         2333  +** invoke it.
         2334  +*/
         2335  +static void vdbeInvokeSqllog(Vdbe *v){
         2336  +  if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){
         2337  +    char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql);
         2338  +    assert( v->db->init.busy==0 );
         2339  +    if( zExpanded ){
         2340  +      sqlite3GlobalConfig.xSqllog(
         2341  +          sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1
         2342  +      );
         2343  +      sqlite3DbFree(v->db, zExpanded);
         2344  +    }
         2345  +  }
         2346  +}
         2347  +#else
         2348  +# define vdbeInvokeSqllog(x)
         2349  +#endif
         2350  +
  2329   2351   /*
  2330   2352   ** Clean up a VDBE after execution but do not delete the VDBE just yet.
  2331   2353   ** Write any error messages into *pzErrMsg.  Return the result code.
  2332   2354   **
  2333   2355   ** After this routine is run, the VDBE should be ready to be executed
  2334   2356   ** again.
  2335   2357   **
................................................................................
  2349   2371   
  2350   2372     /* If the VDBE has be run even partially, then transfer the error code
  2351   2373     ** and error message from the VDBE into the main database structure.  But
  2352   2374     ** if the VDBE has just been set to run but has not actually executed any
  2353   2375     ** instructions yet, leave the main database error information unchanged.
  2354   2376     */
  2355   2377     if( p->pc>=0 ){
         2378  +    vdbeInvokeSqllog(p);
  2356   2379       sqlite3VdbeTransferError(p);
  2357   2380       sqlite3DbFree(db, p->zErrMsg);
  2358   2381       p->zErrMsg = 0;
  2359   2382       if( p->runOnlyOnce ) p->expired = 1;
  2360   2383     }else if( p->rc && p->expired ){
  2361   2384       /* The expired flag was set on the VDBE before the first call
  2362   2385       ** to sqlite3_step(). For consistency (since sqlite3_step() was
................................................................................
  2430   2453         }
  2431   2454         pAux->pAux = 0;
  2432   2455       }
  2433   2456     }
  2434   2457   }
  2435   2458   
  2436   2459   /*
  2437         -** Free all memory associated with the Vdbe passed as the second argument.
         2460  +** Free all memory associated with the Vdbe passed as the second argument,
         2461  +** except for object itself, which is preserved.
         2462  +**
  2438   2463   ** The difference between this function and sqlite3VdbeDelete() is that
  2439   2464   ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
  2440         -** the database connection.
         2465  +** the database connection and frees the object itself.
  2441   2466   */
  2442         -void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
         2467  +void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
  2443   2468     SubProgram *pSub, *pNext;
  2444   2469     int i;
  2445   2470     assert( p->db==0 || p->db==db );
  2446   2471     releaseMemArray(p->aVar, p->nVar);
  2447   2472     releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  2448   2473     for(pSub=p->pProgram; pSub; pSub=pNext){
  2449   2474       pNext = pSub->pNext;
................................................................................
  2453   2478     for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  2454   2479     vdbeFreeOpArray(db, p->aOp, p->nOp);
  2455   2480     sqlite3DbFree(db, p->aLabel);
  2456   2481     sqlite3DbFree(db, p->aColName);
  2457   2482     sqlite3DbFree(db, p->zSql);
  2458   2483     sqlite3DbFree(db, p->pFree);
  2459   2484   #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
  2460         -  sqlite3DbFree(db, p->zExplain);
         2485  +  sqlite3_free(p->zExplain);
  2461   2486     sqlite3DbFree(db, p->pExplain);
  2462   2487   #endif
  2463         -  sqlite3DbFree(db, p);
  2464   2488   }
  2465   2489   
  2466   2490   /*
  2467   2491   ** Delete an entire VDBE.
  2468   2492   */
  2469   2493   void sqlite3VdbeDelete(Vdbe *p){
  2470   2494     sqlite3 *db;
  2471   2495   
  2472   2496     if( NEVER(p==0) ) return;
  2473   2497     db = p->db;
  2474   2498     assert( sqlite3_mutex_held(db->mutex) );
         2499  +  sqlite3VdbeClearObject(db, p);
  2475   2500     if( p->pPrev ){
  2476   2501       p->pPrev->pNext = p->pNext;
  2477   2502     }else{
  2478   2503       assert( db->pVdbe==p );
  2479   2504       db->pVdbe = p->pNext;
  2480   2505     }
  2481   2506     if( p->pNext ){
  2482   2507       p->pNext->pPrev = p->pPrev;
  2483   2508     }
  2484   2509     p->magic = VDBE_MAGIC_DEAD;
  2485   2510     p->db = 0;
  2486         -  sqlite3VdbeDeleteObject(db, p);
         2511  +  sqlite3DbFree(db, p);
  2487   2512   }
  2488   2513   
  2489   2514   /*
  2490   2515   ** Make sure the cursor p is ready to read or write the row to which it
  2491   2516   ** was last positioned.  Return an error code if an OOM fault or I/O error
  2492   2517   ** prevents us from positioning the cursor to its correct position.
  2493   2518   **

Changes to src/vdbesort.c.

   191    191     ** than p->nBuffer bytes remaining in the PMA, read all remaining data.  */
   192    192     iBuf = p->iReadOff % p->nBuffer;
   193    193     if( iBuf==0 ){
   194    194       int nRead;                    /* Bytes to read from disk */
   195    195       int rc;                       /* sqlite3OsRead() return code */
   196    196   
   197    197       /* Determine how many bytes of data to read. */
   198         -    nRead = (int)(p->iEof - p->iReadOff);
   199         -    if( nRead>p->nBuffer ) nRead = p->nBuffer;
          198  +    if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){
          199  +      nRead = p->nBuffer;
          200  +    }else{
          201  +      nRead = (int)(p->iEof - p->iReadOff);
          202  +    }
   200    203       assert( nRead>0 );
   201    204   
   202    205       /* Read data from the file. Return early if an error occurs. */
   203    206       rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
   204    207       assert( rc!=SQLITE_IOERR_SHORT_READ );
   205    208       if( rc!=SQLITE_OK ) return rc;
   206    209     }

Changes to src/vtab.c.

   491    491     if( !pVTable ){
   492    492       sqlite3DbFree(db, zModuleName);
   493    493       return SQLITE_NOMEM;
   494    494     }
   495    495     pVTable->db = db;
   496    496     pVTable->pMod = pMod;
   497    497   
   498         -  assert( pTab->azModuleArg[1]==0 );
   499    498     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   500    499     pTab->azModuleArg[1] = db->aDb[iDb].zName;
   501    500   
   502    501     /* Invoke the virtual table constructor */
   503    502     assert( &db->pVtabCtx );
   504    503     assert( xConstruct );
   505    504     sCtx.pTab = pTab;
   506    505     sCtx.pVTable = pVTable;
   507    506     pPriorCtx = db->pVtabCtx;
   508    507     db->pVtabCtx = &sCtx;
   509    508     rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
   510    509     db->pVtabCtx = pPriorCtx;
   511    510     if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
   512         -  pTab->azModuleArg[1] = 0;
   513    511   
   514    512     if( SQLITE_OK!=rc ){
   515    513       if( zErr==0 ){
   516    514         *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
   517    515       }else {
   518    516         *pzErr = sqlite3MPrintf(db, "%s", zErr);
   519    517         sqlite3_free(zErr);

Changes to src/where.c.

  1811   1811       /* There is no point in building an automatic index for a single scan */
  1812   1812       return;
  1813   1813     }
  1814   1814     if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){
  1815   1815       /* Automatic indices are disabled at run-time */
  1816   1816       return;
  1817   1817     }
  1818         -  if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
         1818  +  if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0
         1819  +   && (p->cost.plan.wsFlags & WHERE_COVER_SCAN)==0
         1820  +  ){
  1819   1821       /* We already have some kind of index in use for this query. */
  1820   1822       return;
         1823  +  }
         1824  +  if( pSrc->viaCoroutine ){
         1825  +    /* Cannot index a co-routine */
         1826  +    return;
  1821   1827     }
  1822   1828     if( pSrc->notIndexed ){
  1823   1829       /* The NOT INDEXED clause appears in the SQL. */
  1824   1830       return;
  1825   1831     }
  1826   1832     if( pSrc->isCorrelated ){
  1827   1833       /* The source is a correlated sub-query. No point in indexing it. */
................................................................................
  2992   2998   **
  2993   2999   ** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
  2994   3000   ** the SQL statement, then this function only considers plans using the 
  2995   3001   ** named index. If no such plan is found, then the returned cost is
  2996   3002   ** SQLITE_BIG_DBL. If a plan is found that uses the named index, 
  2997   3003   ** then the cost is calculated in the usual way.
  2998   3004   **
  2999         -** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table 
         3005  +** If a NOT INDEXED clause was attached to the table 
  3000   3006   ** in the SELECT statement, then no indexes are considered. However, the 
  3001   3007   ** selected plan may still take advantage of the built-in rowid primary key
  3002   3008   ** index.
  3003   3009   */
  3004   3010   static void bestBtreeIndex(WhereBestIdx *p){
  3005   3011     Parse *pParse = p->pParse;  /* The parsing context */
  3006   3012     WhereClause *pWC = p->pWC;  /* The WHERE clause */
................................................................................
  4019   4025     ** row of the left table of the join.
  4020   4026     */
  4021   4027     if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
  4022   4028       pLevel->iLeftJoin = ++pParse->nMem;
  4023   4029       sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
  4024   4030       VdbeComment((v, "init LEFT JOIN no-match flag"));
  4025   4031     }
         4032  +
         4033  +  /* Special case of a FROM clause subquery implemented as a co-routine */
         4034  +  if( pTabItem->viaCoroutine ){
         4035  +    int regYield = pTabItem->regReturn;
         4036  +    sqlite3VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
         4037  +    pLevel->p2 =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
         4038  +    VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
         4039  +    sqlite3VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
         4040  +    pLevel->op = OP_Goto;
         4041  +  }else
  4026   4042   
  4027   4043   #ifndef SQLITE_OMIT_VIRTUALTABLE
  4028   4044     if(  (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
  4029   4045       /* Case 0:  The table is a virtual-table.  Use the VFilter and VNext
  4030   4046       **          to access the data.
  4031   4047       */
  4032   4048       int iReg;   /* P3 Value for OP_VFilter */
................................................................................
  5082   5098           assert( sWBI.pSrc->pIndex==0 
  5083   5099                     || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
  5084   5100                     || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex );
  5085   5101   
  5086   5102           if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
  5087   5103             notIndexed |= m;
  5088   5104           }
         5105  +        if( isOptimal ){
         5106  +          pWInfo->a[j].rOptCost = sWBI.cost.rCost;
         5107  +        }else if( iFrom<nTabList-1 ){
         5108  +          /* If two or more tables have nearly the same outer loop cost,
         5109  +          ** very different inner loop (optimal) cost, we want to choose
         5110  +          ** for the outer loop that table which benefits the least from
         5111  +          ** being in the inner loop.  The following code scales the 
         5112  +          ** outer loop cost estimate to accomplish that. */
         5113  +          WHERETRACE(("   scaling cost from %.1f to %.1f\n",
         5114  +                      sWBI.cost.rCost,
         5115  +                      sWBI.cost.rCost/pWInfo->a[j].rOptCost));
         5116  +          sWBI.cost.rCost /= pWInfo->a[j].rOptCost;
         5117  +        }
  5089   5118   
  5090   5119           /* Conditions under which this table becomes the best so far:
  5091   5120           **
  5092   5121           **   (1) The table must not depend on other tables that have not
  5093   5122           **       yet run.  (In other words, it must not depend on tables
  5094   5123           **       in inner loops.)
  5095   5124           **
  5096         -        **   (2) A full-table-scan plan cannot supercede indexed plan unless
  5097         -        **       the full-table-scan is an "optimal" plan as defined above.
         5125  +        **   (2) (This rule was removed on 2012-11-09.  The scaling of the
         5126  +        **       cost using the optimal scan cost made this rule obsolete.)
  5098   5127           **
  5099   5128           **   (3) All tables have an INDEXED BY clause or this table lacks an
  5100   5129           **       INDEXED BY clause or this table uses the specific
  5101   5130           **       index specified by its INDEXED BY clause.  This rule ensures
  5102   5131           **       that a best-so-far is always selected even if an impossible
  5103   5132           **       combination of INDEXED BY clauses are given.  The error
  5104   5133           **       will be detected and relayed back to the application later.
................................................................................
  5105   5134           **       The NEVER() comes about because rule (2) above prevents
  5106   5135           **       An indexable full-table-scan from reaching rule (3).
  5107   5136           **
  5108   5137           **   (4) The plan cost must be lower than prior plans, where "cost"
  5109   5138           **       is defined by the compareCost() function above. 
  5110   5139           */
  5111   5140           if( (sWBI.cost.used&sWBI.notValid)==0                    /* (1) */
  5112         -            && (bestJ<0 || (notIndexed&m)!=0                     /* (2) */
  5113         -                || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
  5114         -                || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
  5115   5141               && (nUnconstrained==0 || sWBI.pSrc->pIndex==0        /* (3) */
  5116   5142                   || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
  5117   5143               && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan))   /* (4) */
  5118   5144           ){
  5119   5145             WHERETRACE(("   === table %d (%s) is best so far\n"
  5120   5146                         "       cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n",
  5121   5147                         j, sWBI.pSrc->pTab->zName,
................................................................................
  5227   5253         /* Do nothing */
  5228   5254       }else
  5229   5255   #ifndef SQLITE_OMIT_VIRTUALTABLE
  5230   5256       if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
  5231   5257         const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
  5232   5258         int iCur = pTabItem->iCursor;
  5233   5259         sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
         5260  +    }else if( IsVirtual(pTab) ){
         5261  +      /* noop */
  5234   5262       }else
  5235   5263   #endif
  5236   5264       if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
  5237   5265            && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
  5238   5266         int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
  5239   5267         sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
  5240   5268         testcase( pTab->nCol==BMS-1 );

Changes to test/aggnested.test.

    63     63       REPLACE INTO t2 VALUES(2,99,999,9999);
    64     64       SELECT (SELECT GROUP_CONCAT(CASE WHEN a1=1 THEN'A' ELSE 'B' END) FROM t2),
    65     65               t1.* 
    66     66       FROM t1;
    67     67     }
    68     68   } {A,B,B 3 33 333 3333}
    69     69   db2 close
           70  +
           71  +##################### Test cases for ticket [bfbf38e5e9956ac69f] ############
           72  +#
           73  +# This first test case is the original problem report:
           74  +do_test aggnested-3.0 {
           75  +  db eval {
           76  +    CREATE TABLE AAA (
           77  +      aaa_id       INTEGER PRIMARY KEY AUTOINCREMENT
           78  +    );
           79  +    CREATE TABLE RRR (
           80  +      rrr_id      INTEGER     PRIMARY KEY AUTOINCREMENT,
           81  +      rrr_date    INTEGER     NOT NULL,
           82  +      rrr_aaa     INTEGER
           83  +    );
           84  +    CREATE TABLE TTT (
           85  +      ttt_id      INTEGER PRIMARY KEY AUTOINCREMENT,
           86  +      target_aaa  INTEGER NOT NULL,
           87  +      source_aaa  INTEGER NOT NULL
           88  +    );
           89  +    insert into AAA (aaa_id) values (2);
           90  +    insert into TTT (ttt_id, target_aaa, source_aaa)
           91  +    values (4469, 2, 2);
           92  +    insert into TTT (ttt_id, target_aaa, source_aaa)
           93  +    values (4476, 2, 1);
           94  +    insert into RRR (rrr_id, rrr_date, rrr_aaa)
           95  +    values (0, 0, NULL);
           96  +    insert into RRR (rrr_id, rrr_date, rrr_aaa)
           97  +    values (2, 4312, 2);
           98  +    SELECT i.aaa_id,
           99  +      (SELECT sum(CASE WHEN (t.source_aaa == i.aaa_id) THEN 1 ELSE 0 END)
          100  +         FROM TTT t
          101  +      ) AS segfault
          102  +    FROM
          103  +     (SELECT curr.rrr_aaa as aaa_id
          104  +        FROM RRR curr
          105  +          -- you also can comment out the next line
          106  +          -- it causes segfault to happen after one row is outputted
          107  +          INNER JOIN AAA a ON (curr.rrr_aaa = aaa_id)
          108  +          LEFT JOIN RRR r ON (r.rrr_id <> 0 AND r.rrr_date < curr.rrr_date)
          109  +       GROUP BY curr.rrr_id
          110  +      HAVING r.rrr_date IS NULL
          111  +    ) i;
          112  +  }
          113  +} {2 1}
          114  +
          115  +# Further variants of the test case, as found in the ticket
          116  +#
          117  +do_test aggnested-3.1 {
          118  +  db eval {
          119  +    DROP TABLE IF EXISTS t1;
          120  +    DROP TABLE IF EXISTS t2;
          121  +    CREATE TABLE t1 (
          122  +      id1 INTEGER PRIMARY KEY AUTOINCREMENT,
          123  +      value1 INTEGER
          124  +    );
          125  +    INSERT INTO t1 VALUES(4469,2),(4476,1);
          126  +    CREATE TABLE t2 (
          127  +      id2 INTEGER PRIMARY KEY AUTOINCREMENT,
          128  +      value2 INTEGER
          129  +    );
          130  +    INSERT INTO t2 VALUES(0,1),(2,2);
          131  +    SELECT
          132  +     (SELECT sum(value2==xyz) FROM t2)
          133  +    FROM
          134  +     (SELECT curr.value1 as xyz
          135  +        FROM t1 AS curr LEFT JOIN t1 AS other
          136  +       GROUP BY curr.id1);
          137  +  }
          138  +} {1 1}
          139  +do_test aggnested-3.2 {
          140  +  db eval {
          141  +    DROP TABLE IF EXISTS t1;
          142  +    DROP TABLE IF EXISTS t2;
          143  +    CREATE TABLE t1 (
          144  +      id1 INTEGER,
          145  +      value1 INTEGER,
          146  +      x1 INTEGER
          147  +    );
          148  +    INSERT INTO t1 VALUES(4469,2,98),(4469,1,99),(4469,3,97);
          149  +    CREATE TABLE t2 (
          150  +      value2 INTEGER
          151  +    );
          152  +    INSERT INTO t2 VALUES(1);
          153  +    SELECT
          154  +     (SELECT sum(value2==xyz) FROM t2)
          155  +    FROM
          156  +     (SELECT value1 as xyz, max(x1) AS pqr
          157  +        FROM t1
          158  +       GROUP BY id1);
          159  +  }
          160  +} {0}
          161  +do_test aggnested-3.3 {
          162  +  db eval {
          163  +    DROP TABLE IF EXISTS t1;
          164  +    DROP TABLE IF EXISTS t2;
          165  +    CREATE TABLE t1(id1, value1);
          166  +    INSERT INTO t1 VALUES(4469,2),(4469,1);
          167  +    CREATE TABLE t2 (value2);
          168  +    INSERT INTO t2 VALUES(1);
          169  +    SELECT (SELECT sum(value2=value1) FROM t2), max(value1)
          170  +      FROM t1
          171  +     GROUP BY id1;
          172  +  }
          173  +} {0 2}
          174  +
          175  +# A batch of queries all doing approximately the same operation involving
          176  +# two nested aggregate queries.
          177  +#
          178  +do_test aggnested-3.11 {
          179  +  db eval {
          180  +    DROP TABLE IF EXISTS t1;
          181  +    DROP TABLE IF EXISTS t2;
          182  +    CREATE TABLE t1(id1, value1);
          183  +    INSERT INTO t1 VALUES(4469,12),(4469,11),(4470,34);
          184  +    CREATE INDEX t1id1 ON t1(id1);
          185  +    CREATE TABLE t2 (value2);
          186  +    INSERT INTO t2 VALUES(12),(34),(34);
          187  +    INSERT INTO t2 SELECT value2 FROM t2;
          188  +
          189  +    SELECT max(value1), (SELECT count(*) FROM t2 WHERE value2=max(value1))
          190  +      FROM t1
          191  +     GROUP BY id1;
          192  +  }
          193  +} {12 2 34 4}
          194  +do_test aggnested-3.12 {
          195  +  db eval {
          196  +    SELECT max(value1), (SELECT count(*) FROM t2 WHERE value2=value1)
          197  +      FROM t1
          198  +     GROUP BY id1;
          199  +  }
          200  +} {12 2 34 4}
          201  +do_test aggnested-3.13 {
          202  +  db eval {
          203  +    SELECT value1, (SELECT sum(value2=value1) FROM t2)
          204  +      FROM t1;
          205  +  }
          206  +} {12 2 11 0 34 4}
          207  +do_test aggnested-3.14 {
          208  +  db eval {
          209  +    SELECT value1, (SELECT sum(value2=value1) FROM t2)
          210  +      FROM t1
          211  +     WHERE value1 IN (SELECT max(value1) FROM t1 GROUP BY id1);
          212  +  }
          213  +} {12 2 34 4}
          214  +do_test aggnested-3.15 {
          215  +  # FIXME:  If case 3.16 works, then this case really ought to work too...
          216  +  catchsql {
          217  +    SELECT max(value1), (SELECT sum(value2=max(value1)) FROM t2)
          218  +      FROM t1
          219  +     GROUP BY id1;
          220  +  }
          221  +} {1 {misuse of aggregate function max()}}
          222  +do_test aggnested-3.16 {
          223  +  db eval {
          224  +    SELECT max(value1), (SELECT sum(value2=value1) FROM t2)
          225  +      FROM t1
          226  +     GROUP BY id1;
          227  +  }
          228  +} {12 2 34 4}
          229  + 
    70    230   
    71    231   finish_test

Changes to test/backup4.test.

    59     59   # Test that if the source is zero bytes, the destination database 
    60     60   # consists of a single page only.
    61     61   #
    62     62   do_execsql_test 2.1 {
    63     63     CREATE TABLE t1(a, b);
    64     64     CREATE INDEX i1 ON t1(a, b);
    65     65   }
    66         -
    67         -do_test 2.2 { file size test.db } 3072
           66  +do_test 2.2 { file size test.db } [expr $AUTOVACUUM ? 4096 : 3072]
    68     67   
    69     68   do_test 2.3 {
    70     69     sqlite3 db1 test.db2
    71     70     db1 backup test.db
    72     71     db1 close
    73     72     file size test.db
    74     73   } {1024}
................................................................................
    86     85   # of a single page.
    87     86   #
    88     87   do_execsql_test 3.1 {
    89     88     PRAGMA page_size = 4096;
    90     89     CREATE TABLE t1(a, b);
    91     90     CREATE INDEX i1 ON t1(a, b);
    92     91   }
    93         -
    94         -do_test 3.2 { file size test.db } 12288
           92  +do_test 3.2 { file size test.db } [expr $AUTOVACUUM ? 16384 : 12288]
    95     93   
    96     94   do_test 3.3 {
    97     95     sqlite3 db1 test.db2
    98     96     db1 backup test.db
    99     97     db1 close
   100     98     file size test.db
   101     99   } {1024}
   102    100   
   103    101   do_test 3.4 { file size test.db2 } 0
   104    102   
   105    103   finish_test
   106    104   

Changes to test/crash7.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   # $Id: crash7.test,v 1.1 2008/04/03 14:36:26 danielk1977 Exp $
    13     13   
    14     14   set testdir [file dirname $argv0]
    15     15   source $testdir/tester.tcl
           16  +set testprefix crash7
    16     17   
    17     18   ifcapable !crashtest {
    18     19     finish_test
    19     20     return
    20     21   }
    21     22   
    22     23   proc signature {} {
................................................................................
    74     75          "
    75     76       } {1 {child process exited abnormally}}
    76     77     
    77     78       sqlite3 db test.db
    78     79       integrity_check crash7-1.$ii.integrity
    79     80     } 
    80     81   }
           82  +
           83  +db close
           84  +forcedelete test.db
           85  +sqlite3 db test.db
           86  +do_execsql_test 2.0 {
           87  +  CREATE TABLE t1(a, b, UNIQUE(a, b));
           88  +  INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
           89  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           90  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           91  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           92  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           93  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           94  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           95  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           96  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           97  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           98  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
           99  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
          100  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
          101  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
          102  +  INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
          103  +  DELETE FROM t1 WHERE rowid%2;
          104  +}
          105  +db_save_and_close
          106  +
          107  +for {set i 0} {$i < 20} {incr i} {
          108  +  db_restore_and_reopen
          109  +  do_test 2.[expr $i+1].1 {
          110  +    crashsql -file test.db -seed $i {VACUUM}
          111  +  } {1 {child process exited abnormally}}
          112  +  do_execsql_test 2.[expr $i+1].2 { PRAGMA integrity_check } {ok}
          113  +}
          114  +
    81    115   
    82    116   finish_test

Changes to test/filectrl.test.

    32     32     file_control_lasterrno_test db
    33     33   } {}
    34     34   do_test filectrl-1.5 {
    35     35     db close
    36     36     sqlite3 db test_control_lockproxy.db
    37     37     file_control_lockproxy_test db [get_pwd]
    38     38   } {}
           39  +do_test filectrl-1.6 {
           40  +  sqlite3 db test.db
           41  +  set fn [file_control_tempfilename db]
           42  +  puts -nonewline \[$fn\]
           43  +  set fn
           44  +} {/etilqs_/}
    39     45   db close
    40     46   forcedelete .test_control_lockproxy.db-conch test.proxy
    41     47   finish_test

Changes to test/fts3conf.test.

   132    132       INSERT INTO t1(docid, x) VALUES(1, 'a b c');
   133    133       REPLACE INTO t1(docid, x) VALUES('zero', 'd e f');
   134    134   } {1 {datatype mismatch}}
   135    135   do_execsql_test 2.2.2 { COMMIT }
   136    136   do_execsql_test 2.2.3 { SELECT * FROM t1 } {{a b c} {a b c}}
   137    137   fts3_integrity 2.2.4 db t1
   138    138   
          139  +do_execsql_test 3.1 {
          140  +  CREATE VIRTUAL TABLE t3 USING fts4;
          141  +  REPLACE INTO t3(docid, content) VALUES (1, 'one two');
          142  +  SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
          143  +} {X'0100000002000000'}
          144  +
          145  +do_execsql_test 3.2 {
          146  +  REPLACE INTO t3(docid, content) VALUES (2, 'one two three four');
          147  +  SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'four'
          148  +} {X'0200000003000000'}
          149  +
          150  +do_execsql_test 3.3 {
          151  +  REPLACE INTO t3(docid, content) VALUES (1, 'one two three four five six');
          152  +  SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
          153  +} {X'0200000005000000'}
          154  +
          155  +do_execsql_test 3.4 {
          156  +  UPDATE OR REPLACE t3 SET docid = 2 WHERE docid=1;
          157  +  SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
          158  +} {X'0100000006000000'}
          159  +
          160  +do_execsql_test 3.5 {
          161  +  UPDATE OR REPLACE t3 SET docid = 3 WHERE docid=2;
          162  +  SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
          163  +} {X'0100000006000000'}
          164  +
          165  +do_execsql_test 3.6 {
          166  +  REPLACE INTO t3(docid, content) VALUES (3, 'one two');
          167  +  SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
          168  +} {X'0100000002000000'}
          169  +
          170  +do_execsql_test 3.7 {
          171  +  REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four');
          172  +  REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four five six');
          173  +  SELECT docid FROM t3;
          174  +} {3 4 5}
          175  +
          176  +do_execsql_test 3.8 {
          177  +  UPDATE OR REPLACE t3 SET docid = 5, content='three four' WHERE docid = 4;
          178  +  SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
          179  +} {X'0200000002000000'}
          180  +
   139    181   finish_test

Changes to test/fts3matchinfo.test.

   402    402     SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
   403    403   } {1 {database disk image is malformed}}
   404    404   
   405    405   do_execsql_test  8.4.3.1 { UPDATE t11_stat SET value = NULL; }
   406    406   do_catchsql_test 8.5.3.2 {
   407    407     SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
   408    408   } {1 {database disk image is malformed}}
          409  +
          410  +#-------------------------------------------------------------------------
          411  +do_execsql_test 8.1 {
          412  +  CREATE VIRTUAL TABLE t12 USING fts4;
          413  +  INSERT INTO t12 VALUES('a b c d');
          414  +  SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a';
          415  +} {{0 0 0 0 0 0 1 1 1}}
          416  +do_execsql_test 8.2 {
          417  +  INSERT INTO t12 VALUES('a d c d');
          418  +  SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a';
          419  +} {
          420  +  {0 1 1 0 1 1 1 2 2} {1 1 1 1 1 1 1 2 2}
          421  +}
          422  +do_execsql_test 8.3 {
          423  +  INSERT INTO t12 VALUES('a d d a');
          424  +  SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a';
          425  +} {
          426  +  {0 3 2 0 3 2 1 4 3} {1 3 2 1 3 2 1 4 3} {2 3 2 2 3 2 2 4 3}
          427  +}
   409    428   
   410    429   finish_test
   411    430   

Added test/instr.test.

            1  +# 2012 October 24
            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 file is testing the built-in INSTR() functions.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +
           18  +# Create a table to work with.
           19  +#
           20  +do_test instr-1.1 {
           21  +  db eval {SELECT instr('abcdefg','a');}
           22  +} {1}
           23  +do_test instr-1.2 {
           24  +  db eval {SELECT instr('abcdefg','b');}
           25  +} {2}
           26  +do_test instr-1.3 {
           27  +  db eval {SELECT instr('abcdefg','c');}
           28  +} {3}
           29  +do_test instr-1.4 {
           30  +  db eval {SELECT instr('abcdefg','d');}
           31  +} {4}
           32  +do_test instr-1.5 {
           33  +  db eval {SELECT instr('abcdefg','e');}
           34  +} {5}
           35  +do_test instr-1.6 {
           36  +  db eval {SELECT instr('abcdefg','f');}
           37  +} {6}
           38  +do_test instr-1.7 {
           39  +  db eval {SELECT instr('abcdefg','g');}
           40  +} {7}
           41  +do_test instr-1.8 {
           42  +  db eval {SELECT instr('abcdefg','h');}
           43  +} {0}
           44  +do_test instr-1.9 {
           45  +  db eval {SELECT instr('abcdefg','abcdefg');}
           46  +} {1}
           47  +do_test instr-1.10 {
           48  +  db eval {SELECT instr('abcdefg','abcdefgh');}
           49  +} {0}
           50  +do_test instr-1.11 {
           51  +  db eval {SELECT instr('abcdefg','bcdefg');}
           52  +} {2}
           53  +do_test instr-1.12 {
           54  +  db eval {SELECT instr('abcdefg','bcdefgh');}
           55  +} {0}
           56  +do_test instr-1.13 {
           57  +  db eval {SELECT instr('abcdefg','cdefg');}
           58  +} {3}
           59  +do_test instr-1.14 {
           60  +  db eval {SELECT instr('abcdefg','cdefgh');}
           61  +} {0}
           62  +do_test instr-1.15 {
           63  +  db eval {SELECT instr('abcdefg','defg');}
           64  +} {4}
           65  +do_test instr-1.16 {
           66  +  db eval {SELECT instr('abcdefg','defgh');}
           67  +} {0}
           68  +do_test instr-1.17 {
           69  +  db eval {SELECT instr('abcdefg','efg');}
           70  +} {5}
           71  +do_test instr-1.18 {
           72  +  db eval {SELECT instr('abcdefg','efgh');}
           73  +} {0}
           74  +do_test instr-1.19 {
           75  +  db eval {SELECT instr('abcdefg','fg');}
           76  +} {6}
           77  +do_test instr-1.20 {
           78  +  db eval {SELECT instr('abcdefg','fgh');}
           79  +} {0}
           80  +do_test instr-1.21 {
           81  +  db eval {SELECT coalesce(instr('abcdefg',NULL),'nil');}
           82  +} {nil}
           83  +do_test instr-1.22 {
           84  +  db eval {SELECT coalesce(instr(NULL,'x'),'nil');}
           85  +} {nil}
           86  +do_test instr-1.23 {
           87  +  db eval {SELECT instr(12345,34);}
           88  +} {3}
           89  +do_test instr-1.24 {
           90  +  db eval {SELECT instr(123456.78,34);}
           91  +} {3}
           92  +do_test instr-1.25 {
           93  +  db eval {SELECT instr(123456.78,x'3334');}
           94  +} {3}
           95  +do_test instr-1.26 {
           96  +  db eval {SELECT instr('äbcdefg','efg');}
           97  +} {5}
           98  +do_test instr-1.27 {
           99  +  db eval {SELECT instr('€xyzzy','xyz');}
          100  +} {2}
          101  +do_test instr-1.28 {
          102  +  db eval {SELECT instr('abc€xyzzy','xyz');}
          103  +} {5}
          104  +do_test instr-1.29 {
          105  +  db eval {SELECT instr('abc€xyzzy','€xyz');}
          106  +} {4}
          107  +do_test instr-1.30 {
          108  +  db eval {SELECT instr('abc€xyzzy','c€xyz');}
          109  +} {3}
          110  +do_test instr-1.31 {
          111  +  db eval {SELECT instr(x'0102030405',x'01');}
          112  +} {1}
          113  +do_test instr-1.32 {
          114  +  db eval {SELECT instr(x'0102030405',x'02');}
          115  +} {2}
          116  +do_test instr-1.33 {
          117  +  db eval {SELECT instr(x'0102030405',x'03');}
          118  +} {3}
          119  +do_test instr-1.34 {
          120  +  db eval {SELECT instr(x'0102030405',x'04');}
          121  +} {4}
          122  +do_test instr-1.35 {
          123  +  db eval {SELECT instr(x'0102030405',x'05');}
          124  +} {5}
          125  +do_test instr-1.36 {
          126  +  db eval {SELECT instr(x'0102030405',x'06');}
          127  +} {0}
          128  +do_test instr-1.37 {
          129  +  db eval {SELECT instr(x'0102030405',x'0102030405');}
          130  +} {1}
          131  +do_test instr-1.38 {
          132  +  db eval {SELECT instr(x'0102030405',x'02030405');}
          133  +} {2}
          134  +do_test instr-1.39 {
          135  +  db eval {SELECT instr(x'0102030405',x'030405');}
          136  +} {3}
          137  +do_test instr-1.40 {
          138  +  db eval {SELECT instr(x'0102030405',x'0405');}
          139  +} {4}
          140  +do_test instr-1.41 {
          141  +  db eval {SELECT instr(x'0102030405',x'0506');}
          142  +} {0}
          143  +do_test instr-1.42 {
          144  +  db eval {SELECT instr(x'0102030405',x'');}
          145  +} {1}
          146  +do_test instr-1.43 {
          147  +  db eval {SELECT instr(x'',x'');}
          148  +} {1}
          149  +do_test instr-1.44 {
          150  +  db eval {SELECT instr('','');}
          151  +} {1}
          152  +do_test instr-1.45 {
          153  +  db eval {SELECT instr('abcdefg','');}
          154  +} {1}
          155  +unset -nocomplain longstr
          156  +set longstr abcdefghijklmonpqrstuvwxyz
          157  +append longstr $longstr
          158  +append longstr $longstr
          159  +append longstr $longstr
          160  +append longstr $longstr
          161  +append longstr $longstr
          162  +append longstr $longstr
          163  +append longstr $longstr
          164  +append longstr $longstr
          165  +append longstr $longstr
          166  +append longstr $longstr
          167  +append longstr $longstr
          168  +append longstr $longstr
          169  +# puts [string length $longstr]
          170  +append longstr Xabcde
          171  +do_test instr-1.46 {
          172  +  db eval {SELECT instr($longstr,'X');}
          173  +} {106497}
          174  +do_test instr-1.47 {
          175  +  db eval {SELECT instr($longstr,'Y');}
          176  +} {0}
          177  +do_test instr-1.48 {
          178  +  db eval {SELECT instr($longstr,'Xa');}
          179  +} {106497}
          180  +do_test instr-1.49 {
          181  +  db eval {SELECT instr($longstr,'zXa');}
          182  +} {106496}
          183  +set longstr [string map {a ä} $longstr]
          184  +do_test instr-1.50 {
          185  +  db eval {SELECT instr($longstr,'X');}
          186  +} {106497}
          187  +do_test instr-1.51 {
          188  +  db eval {SELECT instr($longstr,'Y');}
          189  +} {0}
          190  +do_test instr-1.52 {
          191  +  db eval {SELECT instr($longstr,'Xä');}
          192  +} {106497}
          193  +do_test instr-1.53 {
          194  +  db eval {SELECT instr($longstr,'zXä');}
          195  +} {106496}
          196  +do_test instr-1.54 {
          197  +  db eval {SELECT instr(x'78c3a4e282ac79','x');}
          198  +} {1}
          199  +do_test instr-1.55 {
          200  +  db eval {SELECT instr(x'78c3a4e282ac79','y');}
          201  +} {4}
          202  +do_test instr-1.56 {
          203  +  db eval {SELECT instr(x'78c3a4e282ac79',x'79');}
          204  +} {7}
          205  +do_test instr-1.57 {
          206  +  db eval {SELECT instr('xä€y',x'79');}
          207  +} {4}
          208  +
          209  +
          210  +finish_test

Changes to test/malloc3.test.

    23     23   #
    24     24   if {!$MEMDEBUG} {
    25     25      puts "Skipping malloc3 tests: not compiled with -DSQLITE_MEMDEBUG..."
    26     26      finish_test
    27     27      return
    28     28   }
    29     29   
           30  +
           31  +# Do not run these tests with an in-memory journal.
           32  +#
           33  +# In the pager layer, if an IO or OOM error occurs during a ROLLBACK, or
           34  +# when flushing a page to disk due to cache-stress, the pager enters an
           35  +# "error state". The only way out of the error state is to unlock the
           36  +# database file and end the transaction, leaving whatever journal and
           37  +# database files happen to be on disk in place. The next time the current
           38  +# (or any other) connection opens a read transaction, hot-journal rollback
           39  +# is performed if necessary.
           40  +#
           41  +# Of course, this doesn't work with an in-memory journal.
           42  +#
           43  +if {[permutation]=="inmemory_journal"} {
           44  +  finish_test
           45  +  return
           46  +}
           47  +
    30     48   #--------------------------------------------------------------------------
    31     49   # NOTES ON RECOVERING FROM A MALLOC FAILURE
    32     50   # 
    33     51   # The tests in this file test the behaviours described in the following
    34     52   # paragraphs. These tests test the behaviour of the system when malloc() fails
    35     53   # inside of a call to _prepare(), _step(), _finalize() or _reset(). The
    36     54   # handling of malloc() failures within ancillary procedures is tested
................................................................................
   143    161   #--------------------------------------------------------------------------
   144    162   
   145    163   
   146    164   # These procs are used to build up a "program" in global variable
   147    165   # ::run_test_script. At the end of this file, the proc [run_test] is used
   148    166   # to execute the program (and all test cases contained therein).
   149    167   #
          168  +set ::run_test_sql_id 0
   150    169   set ::run_test_script [list]
   151    170   proc TEST {id t} {lappend ::run_test_script -test [list $id $t]}
   152    171   proc PREP {p} {lappend ::run_test_script -prep [string trim $p]}
   153    172   proc DEBUG {s} {lappend ::run_test_script -debug $s}
   154    173   
   155    174   # SQL --
   156    175   #
................................................................................
   158    177   #
   159    178   # Add an 'SQL' primitive to the program (see notes above). If the -norollback
   160    179   # switch is present, then the statement is not allowed to automatically roll
   161    180   # back any active transaction if malloc() fails. It must rollback the statement
   162    181   # transaction only.
   163    182   #
   164    183   proc SQL  {a1 {a2 ""}} {
   165         -  # An SQL primitive parameter is a list of two elements, a boolean value
   166         -  # indicating if the statement may cause transaction rollback when malloc()
   167         -  # fails, and the sql statement itself.
          184  +  # An SQL primitive parameter is a list of three elements, an id, a boolean
          185  +  # value indicating if the statement may cause transaction rollback when
          186  +  # malloc() fails, and the sql statement itself.
          187  +  set id [incr ::run_test_sql_id]
   168    188     if {$a2 == ""} {
   169         -    lappend ::run_test_script -sql [list true [string trim $a1]]
          189  +    lappend ::run_test_script -sql [list $id true [string trim $a1]]
   170    190     } else {
   171         -    lappend ::run_test_script -sql [list false [string trim $a2]]
          191  +    lappend ::run_test_script -sql [list $id false [string trim $a2]]
   172    192     }
   173    193   }
   174    194   
   175    195   # TEST_AUTOCOMMIT --
   176    196   # 
   177    197   #     A shorthand test to see if a transaction is active or not. The first
   178    198   #     argument - $id - is the integer number of the test case. The second
................................................................................
   254    274       }
   255    275     } {abc abc abc_i abc abc_t abc abc_v abc_v 1 2 3}
   256    276   }
   257    277   
   258    278   set sql {
   259    279     BEGIN;DELETE FROM abc;
   260    280   }
   261         -for {set i 1} {$i < 15} {incr i} {
          281  +for {set i 1} {$i < 100} {incr i} {
   262    282     set a $i
   263    283     set b "String value $i"
   264    284     set c [string repeat X $i]
   265    285     append sql "INSERT INTO abc VALUES ($a, '$b', '$c');"
   266    286   }
   267    287   append sql {COMMIT;}
   268    288   PREP $sql
................................................................................
   525    545   
   526    546   proc run_test {arglist iRepeat {pcstart 0} {iFailStart 1}} {
   527    547     if {[llength $arglist] %2} {
   528    548       error "Uneven number of arguments to TEST"
   529    549     }
   530    550   
   531    551     for {set i 0} {$i < $pcstart} {incr i} {
   532         -    set k2 [lindex $arglist [expr 2 * $i]]
   533         -    set v2 [lindex $arglist [expr 2 * $i + 1]]
          552  +    set k2 [lindex $arglist [expr {2 * $i}]]
          553  +    set v2 [lindex $arglist [expr {2 * $i + 1}]]
   534    554       set ac [sqlite3_get_autocommit $::DB]        ;# Auto-Commit
   535    555       switch -- $k2 {
   536         -      -sql  {db eval [lindex $v2 1]}
          556  +      -sql  {db eval [lindex $v2 2]}
   537    557         -prep {db eval $v2}
          558  +      -debug {eval $v2}
   538    559       }
   539    560       set nac [sqlite3_get_autocommit $::DB]       ;# New Auto-Commit 
   540    561       if {$ac && !$nac} {set begin_pc $i}
   541    562     }
   542    563   
   543    564     db rollback_hook [list incr ::rollback_hook_count]
   544    565   
   545    566     set iFail $iFailStart
   546    567     set pc $pcstart
   547    568     while {$pc*2 < [llength $arglist]} {
          569  +    # Fetch the current instruction type and payload.
          570  +    set k [lindex $arglist [expr {2 * $pc}]]
          571  +    set v [lindex $arglist [expr {2 * $pc + 1}]]
   548    572   
   549    573       # Id of this iteration:
   550         -    set k [lindex $arglist [expr 2 * $pc]]
   551    574       set iterid "pc=$pc.iFail=$iFail$k"
   552         -    set v [lindex $arglist [expr 2 * $pc + 1]]
   553    575   
   554    576       switch -- $k {
   555    577   
   556    578         -test { 
   557    579           foreach {id script} $v {}
          580  +        set testid "malloc3-(test $id).$iterid"
          581  +        eval $script
   558    582           incr pc
   559    583         }
   560    584   
   561    585         -sql {
   562    586           set ::rollback_hook_count 0
   563    587   
          588  +        set id [lindex $v 0]
          589  +        set testid "malloc3-(integrity $id).$iterid"
          590  +
   564    591           set ac [sqlite3_get_autocommit $::DB]        ;# Auto-Commit
   565    592           sqlite3_memdebug_fail $iFail -repeat 0
   566         -        set rc [catch {db eval [lindex $v 1]} msg]   ;# True error occurs
          593  +        set rc [catch {db eval [lindex $v 2]} msg]   ;# True error occurs
   567    594           set nac [sqlite3_get_autocommit $::DB]       ;# New Auto-Commit 
   568    595   
   569    596           if {$rc != 0 && $nac && !$ac} {
   570    597             # Before [db eval] the auto-commit flag was clear. Now it
   571    598             # is set. Since an error occured we assume this was not a
   572    599             # commit - therefore a rollback occured. Check that the
   573    600             # rollback-hook was invoked.
   574         -          do_test malloc3-rollback_hook.$iterid {
          601  +          do_test malloc3-rollback_hook_count.$iterid {
   575    602               set ::rollback_hook_count
   576    603             } {1}
   577    604           }
   578    605   
   579    606           set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign]
   580    607           if {$rc == 0} {
   581    608               # Successful execution of sql. The number of failed malloc()
   582    609               # calls should be equal to the number of benign failures.
   583    610               # Otherwise a malloc() failed and the error was not reported.
   584    611               # 
   585         -            if {$nFail!=$nBenign} {
   586         -              error "Unreported malloc() failure"
          612  +            set expr {$nFail!=$nBenign}
          613  +            if {[expr $expr]} {
          614  +              error "Unreported malloc() failure, test \"$testid\", $expr"
   587    615               }
   588    616   
   589    617               if {$ac && !$nac} {
   590    618                 # Before the [db eval] the auto-commit flag was set, now it
   591    619                 # is clear. We can deduce that a "BEGIN" statement has just
   592    620                 # been successfully executed.
   593    621                 set begin_pc $pc
   594    622               } 
   595    623   
   596    624               incr pc
   597    625               set iFail 1
   598         -            integrity_check "malloc3-(integrity).$iterid"
          626  +            integrity_check $testid
   599    627           } elseif {[regexp {.*out of memory} $msg] || [db errorcode] == 3082} {
   600    628               # Out of memory error, as expected.
   601    629               #
   602         -            integrity_check "malloc3-(integrity).$iterid"
          630  +            integrity_check $testid
   603    631               incr iFail
   604    632               if {$nac && !$ac} {
   605         -
   606         -              if {![lindex $v 0] && [db errorcode] != 3082} {
   607         -                # error "Statement \"[lindex $v 1]\" caused a rollback"
          633  +              if {![lindex $v 1] && [db errorcode] != 3082} {
          634  +                # error "Statement \"[lindex $v 2]\" caused a rollback"
   608    635                 }
   609    636   
   610    637                 for {set i $begin_pc} {$i < $pc} {incr i} {
   611         -                set k2 [lindex $arglist [expr 2 * $i]]
   612         -                set v2 [lindex $arglist [expr 2 * $i + 1]]
          638  +                set k2 [lindex $arglist [expr {2 * $i}]]
          639  +                set v2 [lindex $arglist [expr {2 * $i + 1}]]
   613    640                   set catchupsql ""
   614    641                   switch -- $k2 {
   615         -                  -sql  {set catchupsql [lindex $v2 1]}
          642  +                  -sql  {set catchupsql [lindex $v2 2]}
   616    643                     -prep {set catchupsql $v2}
   617    644                   }
   618    645                   db eval $catchupsql
   619    646                 }
   620    647               }
   621    648           } else {
   622    649               error $msg
   623    650           }
   624    651   
   625         -        while {[lindex $arglist [expr 2 * ($pc -1)]] == "-test"} {
          652  +        # back up to the previous "-test" block.
          653  +        while {[lindex $arglist [expr {2 * ($pc - 1)}]] == "-test"} {
   626    654             incr pc -1
   627    655           }
   628    656         }
   629    657   
   630    658         -prep {
   631    659           db eval $v
   632    660           incr pc
................................................................................
   638    666         }
   639    667   
   640    668         default { error "Unknown switch: $k" }
   641    669       }
   642    670     }
   643    671   }
   644    672   
   645         -# Turn of the Tcl interface's prepared statement caching facility. Then
          673  +# Turn off the Tcl interface's prepared statement caching facility. Then
   646    674   # run the tests with "persistent" malloc failures.
   647    675   sqlite3_extended_result_codes db 1
   648    676   db cache size 0
   649    677   run_test $::run_test_script 1
   650    678   
   651    679   # Close and reopen the db.
   652    680   db close

Changes to test/minmax.test.

   295    295   ifcapable {compound && subquery} {
   296    296     do_test minmax-9.1 {
   297    297       execsql {
   298    298         SELECT max(rowid) FROM (
   299    299           SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5
   300    300         )
   301    301       }
   302         -  } {1}
          302  +  } {{}}
   303    303     do_test minmax-9.2 {
   304    304       execsql {
   305    305         SELECT max(rowid) FROM (
   306    306           SELECT max(rowid) FROM t4 EXCEPT SELECT max(rowid) FROM t5
   307    307         )
   308    308       }
   309    309     } {{}}

Changes to test/minmax2.test.

   285    285   ifcapable {compound && subquery} {
   286    286     do_test minmax2-9.1 {
   287    287       execsql {
   288    288         SELECT max(rowid) FROM (
   289    289           SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5
   290    290         )
   291    291       }
   292         -  } {1}
          292  +  } {{}}
   293    293     do_test minmax2-9.2 {
   294    294       execsql {
   295    295         SELECT max(rowid) FROM (
   296    296           SELECT max(rowid) FROM t4 EXCEPT SELECT max(rowid) FROM t5
   297    297         )
   298    298       }
   299    299     } {{}}

Changes to test/orderby1.test.

    44     44           (NULL, 2, 1, 'two-a'),
    45     45           (NULL, 3, 1, 'three-a');
    46     46       COMMIT;
    47     47     }
    48     48   } {}
    49     49   do_test 1.1a {
    50     50     db eval {
    51         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
           51  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
    52     52     }
    53     53   } {one-a one-c two-a two-b three-a three-c}
    54     54   
    55     55   # Verify that the ORDER BY clause is optimized out
    56     56   #
    57     57   do_test 1.1b {
    58     58     db eval {
    59     59       EXPLAIN QUERY PLAN
    60         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
           60  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
    61     61     }
    62     62   } {~/ORDER BY/}  ;# ORDER BY optimized out
    63     63   
    64     64   # The same query with ORDER BY clause optimization disabled via + operators
    65     65   # should give exactly the same answer.
    66     66   #
    67     67   do_test 1.2a {
    68     68     db eval {
    69         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
           69  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn
    70     70     }
    71     71   } {one-a one-c two-a two-b three-a three-c}
    72     72   
    73     73   # The output is sorted manually in this case.
    74     74   #
    75     75   do_test 1.2b {
    76     76     db eval {
    77     77       EXPLAIN QUERY PLAN
    78         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
           78  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn
    79     79     }
    80     80   } {/ORDER BY/}   ;# separate sorting pass due to "+" on ORDER BY terms
    81     81   
    82     82   # The same query with ORDER BY optimizations turned off via built-in test.
    83     83   #
    84     84   do_test 1.3a {
    85     85     optimization_control db order-by-idx-join 0
    86     86     db cache flush
    87     87     db eval {
    88         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
           88  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
    89     89     }
    90     90   } {one-a one-c two-a two-b three-a three-c}
    91     91   do_test 1.3b {
    92     92     db eval {
    93     93       EXPLAIN QUERY PLAN
    94         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
           94  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
    95     95     }
    96     96   } {/ORDER BY/}   ;# separate sorting pass due to disabled optimization
    97     97   optimization_control db all 1
    98     98   db cache flush
    99     99   
   100    100   # Reverse order sorts
   101    101   #
   102    102   do_test 1.4a {
   103    103     db eval {
   104         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
          104  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
   105    105     }
   106    106   } {three-a three-c two-a two-b one-a one-c}
   107    107   do_test 1.4b {
   108    108     db eval {
   109         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
          109  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title DESC, +tn
   110    110     }
   111    111   } {three-a three-c two-a two-b one-a one-c}  ;# verify same order after sorting
   112    112   do_test 1.4c {
   113    113     db eval {
   114    114       EXPLAIN QUERY PLAN
   115         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
          115  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
   116    116     }
   117    117   } {~/ORDER BY/}  ;# optimized out
   118    118   
   119    119   
   120    120   do_test 1.5a {
   121    121     db eval {
   122         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          122  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   123    123     }
   124    124   } {one-c one-a two-b two-a three-c three-a}
   125    125   do_test 1.5b {
   126    126     db eval {
   127         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
          127  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn DESC
   128    128     }
   129    129   } {one-c one-a two-b two-a three-c three-a}  ;# verify same order after sorting
   130    130   do_test 1.5c {
   131    131     db eval {
   132    132       EXPLAIN QUERY PLAN
   133         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          133  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   134    134     }
   135    135   } {~/ORDER BY/}  ;# optimized out
   136    136   
   137    137   do_test 1.6a {
   138    138     db eval {
   139         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
          139  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn DESC
   140    140     }
   141    141   } {three-c three-a two-b two-a one-c one-a}
   142    142   do_test 1.6b {
   143    143     db eval {
   144         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
          144  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
   145    145     }
   146    146   } {three-c three-a two-b two-a one-c one-a}  ;# verify same order after sorting
   147    147   do_test 1.6c {
   148    148     db eval {
   149    149       EXPLAIN QUERY PLAN
   150         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
          150  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn DESC
   151    151     }
   152    152   } {~/ORDER BY/}  ;# ORDER BY optimized-out
   153    153   
   154    154   
   155    155   # Reconstruct the test data to use indices rather than integer primary keys.
   156    156   #
   157    157   do_test 2.0 {
................................................................................
   179    179           (20, 1, 'two-a'),
   180    180           (3,  1, 'three-a');
   181    181       COMMIT;
   182    182     }
   183    183   } {}
   184    184   do_test 2.1a {
   185    185     db eval {
   186         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
          186  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
   187    187     }
   188    188   } {one-a one-c two-a two-b three-a three-c}
   189    189   
   190    190   # Verify that the ORDER BY clause is optimized out
   191    191   #
   192    192   do_test 2.1b {
   193    193     db eval {
   194    194       EXPLAIN QUERY PLAN
   195         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
          195  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
   196    196     }
   197    197   } {~/ORDER BY/}  ;# ORDER BY optimized out
   198    198   
   199    199   do_test 2.1c {
   200    200     db eval {
   201         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
          201  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, aid, tn
   202    202     }
   203    203   } {one-a one-c two-a two-b three-a three-c}
   204    204   do_test 2.1d {
   205    205     db eval {
   206    206       EXPLAIN QUERY PLAN
   207         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
          207  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, aid, tn
   208    208     }
   209    209   } {~/ORDER BY/}  ;# ORDER BY optimized out
   210    210   
   211    211   # The same query with ORDER BY clause optimization disabled via + operators
   212    212   # should give exactly the same answer.
   213    213   #
   214    214   do_test 2.2a {
   215    215     db eval {
   216         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
          216  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn
   217    217     }
   218    218   } {one-a one-c two-a two-b three-a three-c}
   219    219   
   220    220   # The output is sorted manually in this case.
   221    221   #
   222    222   do_test 2.2b {
   223    223     db eval {
   224    224       EXPLAIN QUERY PLAN
   225         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
          225  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn
   226    226     }
   227    227   } {/ORDER BY/}   ;# separate sorting pass due to "+" on ORDER BY terms
   228    228   
   229    229   # The same query with ORDER BY optimizations turned off via built-in test.
   230    230   #
   231    231   do_test 2.3a {
   232    232     optimization_control db order-by-idx-join 0
   233    233     db cache flush
   234    234     db eval {
   235         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
          235  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
   236    236     }
   237    237   } {one-a one-c two-a two-b three-a three-c}
   238    238   do_test 2.3b {
   239    239     db eval {
   240    240       EXPLAIN QUERY PLAN
   241         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
          241  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
   242    242     }
   243    243   } {/ORDER BY/}   ;# separate sorting pass due to disabled optimization
   244    244   optimization_control db all 1
   245    245   db cache flush
   246    246   
   247    247   # Reverse order sorts
   248    248   #
   249    249   do_test 2.4a {
   250    250     db eval {
   251         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
          251  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
   252    252     }
   253    253   } {three-a three-c two-a two-b one-a one-c}
   254    254   do_test 2.4b {
   255    255     db eval {
   256         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
          256  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title DESC, +tn
   257    257     }
   258    258   } {three-a three-c two-a two-b one-a one-c}  ;# verify same order after sorting
   259    259   do_test 2.4c {
   260    260     db eval {
   261    261       EXPLAIN QUERY PLAN
   262         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
          262  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
   263    263     }
   264    264   } {~/ORDER BY/}  ;# optimized out
   265    265   
   266    266   
   267    267   do_test 2.5a {
   268    268     db eval {
   269         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          269  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   270    270     }
   271    271   } {one-c one-a two-b two-a three-c three-a}
   272    272   do_test 2.5b {
   273    273     db eval {
   274         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
          274  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn DESC
   275    275     }
   276    276   } {one-c one-a two-b two-a three-c three-a}  ;# verify same order after sorting
   277    277   do_test 2.5c {
   278    278     db eval {
   279    279       EXPLAIN QUERY PLAN
   280         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          280  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   281    281     }
   282    282   } {~/ORDER BY/}  ;# optimized out
   283    283   
   284    284   do_test 2.6a {
   285    285     db eval {
   286         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
          286  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn DESC
   287    287     }
   288    288   } {three-c three-a two-b two-a one-c one-a}
   289    289   do_test 2.6b {
   290    290     db eval {
   291         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
          291  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
   292    292     }
   293    293   } {three-c three-a two-b two-a one-c one-a}  ;# verify same order after sorting
   294    294   do_test 2.6c {
   295    295     db eval {
   296    296       EXPLAIN QUERY PLAN
   297         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
          297  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn DESC
   298    298     }
   299    299   } {~/ORDER BY/}  ;# ORDER BY optimized out
   300    300   
   301    301   
   302    302   # Generate another test dataset, but this time using mixed ASC/DESC indices.
   303    303   #
   304    304   do_test 3.0 {
................................................................................
   326    326           (NULL, 2, 1, 'two-a'),
   327    327           (NULL, 3, 1, 'three-a');
   328    328       COMMIT;
   329    329     }
   330    330   } {}
   331    331   do_test 3.1a {
   332    332     db eval {
   333         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          333  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   334    334     }
   335    335   } {one-c one-a two-b two-a three-c three-a}
   336    336   
   337    337   # Verify that the ORDER BY clause is optimized out
   338    338   #
   339    339   do_test 3.1b {
   340    340     db eval {
   341    341       EXPLAIN QUERY PLAN
   342         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          342  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   343    343     }
   344    344   } {~/ORDER BY/}  ;# ORDER BY optimized out
   345    345   
   346    346   # The same query with ORDER BY clause optimization disabled via + operators
   347    347   # should give exactly the same answer.
   348    348   #
   349    349   do_test 3.2a {
   350    350     db eval {
   351         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
          351  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn DESC
   352    352     }
   353    353   } {one-c one-a two-b two-a three-c three-a}
   354    354   
   355    355   # The output is sorted manually in this case.
   356    356   #
   357    357   do_test 3.2b {
   358    358     db eval {
   359    359       EXPLAIN QUERY PLAN
   360         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
          360  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn DESC
   361    361     }
   362    362   } {/ORDER BY/}   ;# separate sorting pass due to "+" on ORDER BY terms
   363    363   
   364    364   # The same query with ORDER BY optimizations turned off via built-in test.
   365    365   #
   366    366   do_test 3.3a {
   367    367     optimization_control db order-by-idx-join 0
   368    368     db cache flush
   369    369     db eval {
   370         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          370  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   371    371     }
   372    372   } {one-c one-a two-b two-a three-c three-a}
   373    373   do_test 3.3b {
   374    374     db eval {
   375    375       EXPLAIN QUERY PLAN
   376         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
          376  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
   377    377     }
   378    378   } {/ORDER BY/}   ;# separate sorting pass due to disabled optimization
   379    379   optimization_control db all 1
   380    380   db cache flush
   381    381   
   382    382   # Without the mixed ASC/DESC on ORDER BY
   383    383   #
   384    384   do_test 3.4a {
   385    385     db eval {
   386         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
          386  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
   387    387     }
   388    388   } {one-a one-c two-a two-b three-a three-c}
   389    389   do_test 3.4b {
   390    390     db eval {
   391         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
          391  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title, +tn
   392    392     }
   393    393   } {one-a one-c two-a two-b three-a three-c}  ;# verify same order after sorting
   394    394   do_test 3.4c {
   395    395     db eval {
   396    396       EXPLAIN QUERY PLAN
   397         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
          397  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
   398    398     }
   399    399   } {~/ORDER BY/}  ;# optimized out
   400    400   
   401    401   
   402    402   do_test 3.5a {
   403    403     db eval {
   404         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
          404  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn DESC
   405    405     }
   406    406   } {three-c three-a two-b two-a one-c one-a}
   407    407   do_test 3.5b {
   408    408     db eval {
   409         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
          409  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
   410    410     }
   411    411   } {three-c three-a two-b two-a one-c one-a}  ;# verify same order after sorting
   412    412   do_test 3.5c {
   413    413     db eval {
   414    414       EXPLAIN QUERY PLAN
   415         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
          415  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn DESC
   416    416     }
   417    417   } {~/ORDER BY/}  ;# optimzed out
   418    418   
   419    419   
   420    420   do_test 3.6a {
   421    421     db eval {
   422         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
          422  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
   423    423     }
   424    424   } {three-a three-c two-a two-b one-a one-c}
   425    425   do_test 3.6b {
   426    426     db eval {
   427         -    SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
          427  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY +title DESC, +tn
   428    428     }
   429    429   } {three-a three-c two-a two-b one-a one-c}  ;# verify same order after sorting
   430    430   do_test 3.6c {
   431    431     db eval {
   432    432       EXPLAIN QUERY PLAN
   433         -    SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
          433  +    SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
   434    434     }
   435    435   } {~/ORDER BY/}  ;# inverted ASC/DESC is optimized out
   436    436   
   437    437   
   438    438   finish_test

Changes to test/pager1.test.

  2482   2482     }
  2483   2483     db close
  2484   2484     file size test.db
  2485   2485   } {20971520}
  2486   2486   
  2487   2487   # Cleanup 20MB file left by the previous test.
  2488   2488   forcedelete test.db
         2489  +
         2490  +#-------------------------------------------------------------------------
         2491  +# Test that if a transaction is committed in journal_mode=DELETE mode,
         2492  +# and the call to unlink() returns an ENOENT error, the COMMIT does not
         2493  +# succeed.
         2494  +#
         2495  +if {$::tcl_platform(platform)=="unix"} {
         2496  +  do_test pager1-33.1 {
         2497  +    sqlite3 db test.db
         2498  +    execsql {
         2499  +      CREATE TABLE t1(x);
         2500  +      INSERT INTO t1 VALUES('one');
         2501  +      INSERT INTO t1 VALUES('two');
         2502  +      BEGIN;
         2503  +        INSERT INTO t1 VALUES('three');
         2504  +        INSERT INTO t1 VALUES('four');
         2505  +    }
         2506  +    forcedelete bak-journal
         2507  +    file rename test.db-journal bak-journal
         2508  +
         2509  +    catchsql COMMIT
         2510  +  } {1 {disk I/O error}}
         2511  +
         2512  +  do_test pager1-33.2 {
         2513  +    file rename bak-journal test.db-journal
         2514  +    execsql { SELECT * FROM t1 }
         2515  +  } {one two}
         2516  +}
  2489   2517   
  2490   2518   finish_test

Changes to test/shared_err.test.

   397    397     } db2
   398    398     for {set i 0} {$i < 2} {incr i} {
   399    399       set a [string repeat $i 10]
   400    400       set b [string repeat $i 2000]
   401    401       execsql {INSERT INTO t1 VALUES($a, $b)} db2
   402    402     }
   403    403     execsql {COMMIT} db2
          404  +  execsql BEGIN
          405  +  execsql ROLLBACK
   404    406     set ::DB2 [sqlite3_connection_pointer db2]
   405    407     set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY]
   406    408     sqlite3_step $::STMT       ;# Cursor points at 0000000000
   407    409     sqlite3_step $::STMT       ;# Cursor points at 1111111111
   408    410   } -tclbody {
   409    411     execsql {
   410    412       BEGIN;
   411    413       INSERT INTO t1 VALUES(6, NULL);
   412         -    ROLLBACK;
   413         -  }
          414  +    ROLLBACK}
   414    415   } -cleanup {
   415    416     # UPDATE: As of [5668], if the rollback fails SQLITE_CORRUPT is returned. 
   416    417     # So these tests have been updated to expect SQLITE_CORRUPT and its
   417    418     # associated English language error message.
   418    419     #
   419    420     do_test shared_malloc-8.$::n.cleanup.1 {
   420    421       set res [catchsql {SELECT a FROM t1} db2]

Changes to test/shell1.test.

   145    145   do_test shell1-1.14.2 {
   146    146     catchcmd "-separator x test.db" "" 
   147    147   } {0 {}}
   148    148   do_test shell1-1.14.3 {
   149    149     set res [catchcmd "-separator" ""]
   150    150     set rc [lindex $res 0]
   151    151     list $rc \
   152         -       [regexp {Error: missing argument for option: -separator} $res]
          152  +       [regexp {Error: missing argument to -separator} $res]
   153    153   } {1 1}
   154    154   
   155    155   # -stats               print memory stats before each finalize
   156    156   do_test shell1-1.14b.1 {
   157    157     catchcmd "-stats test.db" "" 
   158    158   } {0 {}}
   159    159   
................................................................................
   164    164   do_test shell1-1.15.2 {
   165    165     catchcmd "-nullvalue x test.db" ""
   166    166   } {0 {}}
   167    167   do_test shell1-1.15.3 {
   168    168     set res [catchcmd "-nullvalue" ""]
   169    169     set rc [lindex $res 0]
   170    170     list $rc \
   171         -       [regexp {Error: missing argument for option: -nullvalue} $res]
          171  +       [regexp {Error: missing argument to -nullvalue} $res]
   172    172   } {1 1}
   173    173   
   174    174   # -version             show SQLite version
   175    175   do_test shell1-1.16.1 {
   176    176     set x [catchcmd "-version test.db" ""]
   177    177   } {/3.[0-9.]+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+/}
   178    178   
................................................................................
   715    715   } {0 {this is a test}}
   716    716   
   717    717   # Test the output of the ".dump" command
   718    718   #
   719    719   do_test shell1-4.1 {
   720    720     db eval {
   721    721       CREATE TABLE t1(x);
   722         -    INSERT INTO t1 VALUES(null), (1), (2.25), ('hello'), (x'807f');
          722  +    INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f');
   723    723     }
   724    724     catchcmd test.db {.dump}
   725    725   } {0 {PRAGMA foreign_keys=OFF;
   726    726   BEGIN TRANSACTION;
   727    727   CREATE TABLE t1(x);
   728    728   INSERT INTO "t1" VALUES(NULL);
          729  +INSERT INTO "t1" VALUES('');
   729    730   INSERT INTO "t1" VALUES(1);
   730    731   INSERT INTO "t1" VALUES(2.25);
   731    732   INSERT INTO "t1" VALUES('hello');
   732    733   INSERT INTO "t1" VALUES(X'807F');
   733    734   COMMIT;}}
   734    735   
   735    736   # Test the output of ".mode insert"
   736    737   #
   737    738   do_test shell1-4.2 {
   738    739     catchcmd test.db ".mode insert t1\nselect * from t1;"
   739    740   } {0 {INSERT INTO t1 VALUES(NULL);
          741  +INSERT INTO t1 VALUES('');
   740    742   INSERT INTO t1 VALUES(1);
   741    743   INSERT INTO t1 VALUES(2.25);
   742    744   INSERT INTO t1 VALUES('hello');
   743    745   INSERT INTO t1 VALUES(X'807f');}}
   744    746   
          747  +# Test the output of ".mode tcl"
          748  +#
          749  +do_test shell1-4.3 {
          750  +  catchcmd test.db ".mode tcl\nselect * from t1;"
          751  +} {0 {""
          752  +""
          753  +"1"
          754  +"2.25"
          755  +"hello"
          756  +"\200\177"}}
          757  +
          758  +# Test the output of ".mode tcl" with multiple columns
          759  +#
          760  +do_test shell1-4.4 {
          761  +  db eval {
          762  +    CREATE TABLE t2(x,y);
          763  +    INSERT INTO t2 VALUES(null, ''), (1, 2.25), ('hello', x'807f');
          764  +  }
          765  +  catchcmd test.db ".mode tcl\nselect * from t2;"
          766  +} {0 {"" ""
          767  +"1" "2.25"
          768  +"hello" "\200\177"}}
          769  +
          770  +# Test the output of ".mode tcl" with ".nullvalue"
          771  +#
          772  +do_test shell1-4.5 {
          773  +  catchcmd test.db ".mode tcl\n.nullvalue NULL\nselect * from t2;"
          774  +} {0 {"NULL" ""
          775  +"1" "2.25"
          776  +"hello" "\200\177"}}
          777  +
          778  +# Test the output of ".mode tcl" with Tcl reserved characters
          779  +#
          780  +do_test shell1-4.6 {
          781  +  db eval {
          782  +    CREATE TABLE tcl1(x);
          783  +    INSERT INTO tcl1 VALUES('"'), ('['), (']'), ('\{'), ('\}'), (';'), ('$');
          784  +  }
          785  +  foreach {x y} [catchcmd test.db ".mode tcl\nselect * from tcl1;"] break
          786  +  list $x $y [llength $y]
          787  +} {0 {"\""
          788  +"["
          789  +"]"
          790  +"\\{"
          791  +"\\}"
          792  +";"
          793  +"$"} 7}
   745    794   
   746    795   finish_test

Changes to test/subquery2.test.

    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is testing correlated subqueries
    13     13   #
    14     14   #
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
           18  +set ::testprefix subquery2
    18     19   
    19     20   ifcapable !subquery {
    20     21     finish_test
    21     22     return
    22     23   }
    23     24   
    24     25   do_test subquery2-1.1 {
................................................................................
    77     78   do_test subquery2-1.22 {
    78     79     execsql {
    79     80       SELECT a FROM t1
    80     81        WHERE b=(SELECT x+1 FROM 
    81     82                    (SELECT DISTINCT f/d AS x FROM t2 JOIN t3 ON d*a=f))
    82     83     }
    83     84   } {1 3 5 7}
           85  +
           86  +#-------------------------------------------------------------------------
           87  +# Test that ticket d6b36be38a has been fixed.
           88  +do_execsql_test 2.1 {
           89  +  CREATE TABLE t4(a, b);
           90  +  CREATE TABLE t5(a, b);
           91  +  INSERT INTO t5 VALUES(3, 5);
           92  +
           93  +  INSERT INTO t4 VALUES(1, 1);
           94  +  INSERT INTO t4 VALUES(2, 3);
           95  +  INSERT INTO t4 VALUES(3, 6);
           96  +  INSERT INTO t4 VALUES(4, 10);
           97  +  INSERT INTO t4 VALUES(5, 15);
           98  +}
           99  +
          100  +do_execsql_test 2.2 {
          101  +  SELECT * 
          102  +  FROM (SELECT * FROM t4 ORDER BY a LIMIT -1 OFFSET 1) 
          103  +  LIMIT (SELECT a FROM t5)
          104  +} {2 3   3 6   4 10}
    84    105   
    85    106   
    86    107   finish_test

Changes to test/thread001.test.

    83     83       }
    84     84     
    85     85       for {set i 0} {$i < 100} {incr i} {
    86     86         # Test that the invariant is true.
    87     87         do_test t1 {
    88     88           execsql {
    89     89             SELECT 
    90         -            (SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
           90  +            (SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
    91     91               (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
    92     92           }
    93     93         } {1}
    94     94     
    95     95         # Add another row to the database.
    96     96         execsql { INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab }
    97     97       }
................................................................................
   127    127     #
   128    128     do_test thread001.$tn.5 {
   129    129       execsql { SELECT count(*) FROM ab; }
   130    130     } [expr {1 + $::NTHREAD*100}]
   131    131     do_test thread001.$tn.6 {
   132    132       execsql {
   133    133         SELECT 
   134         -        (SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
          134  +        (SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
   135    135           (SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
   136    136       }
   137    137     } {1}
   138    138     do_test thread001.$tn.7 {
   139    139       execsql { PRAGMA integrity_check }
   140    140     } {ok}
   141    141   }
   142    142   
   143    143   sqlite3_enable_shared_cache $::enable_shared_cache
   144    144   set sqlite_open_file_count 0
   145    145   finish_test

Changes to test/tkt-31338dca7e.test.

    87     87       INSERT INTO t2 VALUES(10,-8);
    88     88       CREATE INDEX t1a ON t1(a);
    89     89       CREATE INDEX t1b ON t1(b);
    90     90       CREATE TABLE t3(g);
    91     91       INSERT INTO t3 VALUES(4);
    92     92       CREATE TABLE t4(h);
    93     93       INSERT INTO t4 VALUES(5);
    94         -    
           94  +
    95     95       SELECT * FROM t3 LEFT JOIN t1 ON d=g LEFT JOIN t4 ON c=h
    96     96        WHERE (a=1 AND h=4)
    97     97            OR (b IN (
    98     98                  SELECT x FROM (SELECT e+f AS x, e FROM t2 ORDER BY 1 LIMIT 2)
    99     99                  GROUP BY e
   100    100               ));
   101    101     }    

Changes to test/tkt3527.test.

    48     48       INSERT INTO Element VALUES(1,'Elem1');
    49     49       INSERT INTO Element VALUES(2,'Elem2');
    50     50       INSERT INTO Element VALUES(3,'Elem3');
    51     51       INSERT INTO Element VALUES(4,'Elem4');
    52     52       INSERT INTO Element VALUES(5,'Elem5');
    53     53       INSERT INTO ElemOr Values(3,4);
    54     54       INSERT INTO ElemOr Values(3,5);
    55         -    INSERT INTO ElemAnd VALUES(1,3,1,1,1);
    56         -    INSERT INTO ElemAnd VALUES(1,2,1,1,1);
           55  +    INSERT INTO ElemAnd VALUES(1,3,'a','b','c');
           56  +    INSERT INTO ElemAnd VALUES(1,2,'x','y','z');
    57     57       
    58     58       CREATE VIEW ElemView1 AS
    59     59       SELECT
    60     60         CAST(Element.Code AS VARCHAR(50)) AS ElemId,
    61     61        Element.Code AS ElemCode,
    62     62        Element.Name AS ElemName,
    63     63        ElemAnd.Code AS InnerCode,
................................................................................
   108    108       FROM ElemView1 AS Element
   109    109       JOIN ElemView1 AS InnerElem
   110    110            ON Element.Level=0 AND Element.InnerCode=InnerElem.ElemCode
   111    111       ORDER BY ElemId, InnerCode;
   112    112    
   113    113       SELECT * FROM ElemView1;
   114    114     }
   115         -} {1 1 Elem1 2 1 1 1 0 0 1 1 Elem1 3 1 1 1 0 0 3 3 Elem3 4 {} {} {} 0 1 3 3 Elem3 5 {} {} {} 0 1}
          115  +} {1 1 Elem1 2 x y z 0 0 1 1 Elem1 3 a b c 0 0 3 3 Elem3 4 {} {} {} 0 1 3 3 Elem3 5 {} {} {} 0 1}
   116    116      
   117    117   do_test tkt3527-1.2 {
   118    118     db eval {
   119    119       SELECT * FROM ElemView2;
   120    120     }
   121         -} {1 1 Elem1 2 1 1 1 0 0 1 1 Elem1 3 1 1 1 0 0 1.3 3 Elem3 4 {} {} {} 1 1 1.3 3 Elem3 5 {} {} {} 1 1 3 3 Elem3 4 {} {} {} 0 1 3 3 Elem3 5 {} {} {} 0 1}
          121  +} {1 1 Elem1 2 x y z 0 0 1 1 Elem1 3 a b c 0 0 1.3 3 Elem3 4 {} {} {} 1 1 1.3 3 Elem3 5 {} {} {} 1 1 3 3 Elem3 4 {} {} {} 0 1 3 3 Elem3 5 {} {} {} 0 1}
   122    122   
   123    123   finish_test

Changes to test/triggerC.test.

   945    945       UPDATE t12 SET a=new.a+1, b=new.b+1;
   946    946     END;
   947    947   } {}
   948    948   do_catchsql_test triggerC-13.2 {
   949    949     UPDATE t12 SET a=a+1, b=b+1;
   950    950   } {1 {too many levels of trigger recursion}}
   951    951   
          952  +#-------------------------------------------------------------------------
          953  +# The following tests seek to verify that constant values (i.e. literals)
          954  +# are not factored out of loops within trigger programs. SQLite does
          955  +# not factor constants out of loops within trigger programs as it may only
          956  +# do so in code generated before the first table or index is opened. And
          957  +# by the time a trigger program is coded, at least one table or index has
          958  +# always been opened.
          959  +#
          960  +# At one point, due to a bug allowing constant factoring within triggers,
          961  +# the following SQL would produce the wrong result.
          962  +#
          963  +set SQL {
          964  +  CREATE TABLE t1(a, b, c);
          965  +  CREATE INDEX i1 ON t1(a, c);
          966  +  CREATE INDEX i2 ON t1(b, c);
          967  +  INSERT INTO t1 VALUES(1, 2, 3);
          968  +
          969  +  CREATE TABLE t2(e, f);
          970  +  CREATE INDEX i3 ON t2(e);
          971  +  INSERT INTO t2 VALUES(1234567, 3);
          972  +
          973  +  CREATE TABLE empty(x);
          974  +  CREATE TABLE not_empty(x);
          975  +  INSERT INTO not_empty VALUES(2);
          976  +
          977  +  CREATE TABLE t4(x);
          978  +  CREATE TABLE t5(g, h, i);
          979  +
          980  +  CREATE TRIGGER trig BEFORE INSERT ON t4 BEGIN
          981  +    INSERT INTO t5 SELECT * FROM t1 WHERE 
          982  +        (a IN (SELECT x FROM empty) OR b IN (SELECT x FROM not_empty)) 
          983  +        AND c IN (SELECT f FROM t2 WHERE e=1234567);
          984  +  END;
          985  +
          986  +  INSERT INTO t4 VALUES(0);
          987  +  SELECT * FROM t5;
          988  +}
   952    989   
          990  +reset_db
          991  +do_execsql_test triggerC-14.1 $SQL {1 2 3}
          992  +reset_db
          993  +optimization_control db factor-constants 0
          994  +do_execsql_test triggerC-14.2 $SQL {1 2 3}
   953    995   
   954    996   finish_test

Changes to test/vtab1.test.

  1288   1288   } SQLITE_OK
  1289   1289   do_test 19.2 {
  1290   1290     register_echo_module [sqlite3_connection_pointer db2]
  1291   1291   } SQLITE_MISUSE
  1292   1292   do_test 19.3 {
  1293   1293     db2 close
  1294   1294   } {}
         1295  +
         1296  +#-------------------------------------------------------------------------
         1297  +# Test that the bug fixed by [b0c1ba655d69] really is fixed.
         1298  +#
         1299  +do_execsql_test 20.1 {
         1300  +  CREATE TABLE t7 (a, b);
         1301  +  CREATE TABLE t8 (c, d);
         1302  +  CREATE INDEX i2 ON t7(a);
         1303  +  CREATE INDEX i3 ON t7(b);
         1304  +  CREATE INDEX i4 ON t8(c);
         1305  +  CREATE INDEX i5 ON t8(d);
         1306  +
         1307  +  CREATE VIRTUAL TABLE t7v USING echo(t7);
         1308  +  CREATE VIRTUAL TABLE t8v USING echo(t8);
         1309  +}
         1310  +
         1311  +do_test 20.2 {
         1312  +  for {set i 0} {$i < 1000} {incr i} {
         1313  +    db eval {INSERT INTO t7 VALUES($i, $i)}
         1314  +    db eval {INSERT INTO t8 VALUES($i, $i)}
         1315  +  }
         1316  +} {}
         1317  +
         1318  +do_execsql_test 20.3 {
         1319  +  SELECT a, b FROM (
         1320  +      SELECT a, b FROM t7 WHERE a=11 OR b=12
         1321  +      UNION ALL
         1322  +      SELECT c, d FROM t8 WHERE c=5 OR d=6
         1323  +  )
         1324  +  ORDER BY 1, 2;
         1325  +} {5 5 6 6 11 11 12 12}
         1326  +
         1327  +do_execsql_test 20.4 {
         1328  +  SELECT a, b FROM (
         1329  +      SELECT a, b FROM t7v WHERE a=11 OR b=12
         1330  +      UNION ALL
         1331  +      SELECT c, d FROM t8v WHERE c=5 OR d=6
         1332  +  )
         1333  +  ORDER BY 1, 2;
         1334  +} {5 5 6 6 11 11 12 12}
  1295   1335   
  1296   1336   finish_test

Changes to test/wal9.test.

    56     56       INSERT INTO t SELECT randomblob(100) FROM t;
    57     57       INSERT INTO t SELECT randomblob(100) FROM t;
    58     58     COMMIT;
    59     59   } {}
    60     60   
    61     61   # Check file sizes are as expected. The real requirement here is that 
    62     62   # the *shm file is now more than one chunk (>32KiB).
           63  +#
           64  +# The sizes of various files are slightly different in normal and 
           65  +# auto-vacuum mode.
    63     66   do_test 1.3 { file size test.db     } {1024}
    64         -do_test 1.4 { file size test.db-wal } {15421352}
    65         -do_test 1.5 { file size test.db-shm } {131072}
    66         -
    67         -do_execsql_test 1.6 { PRAGMA wal_checkpoint } {0 14715 14715}
           67  +do_test 1.4 { expr {[file size test.db-wal]>(1500*1024)} } {1}
           68  +do_test 1.5 { expr {[file size test.db-shm]>32768} }       {1}
           69  +do_test 1.6 { 
           70  +  foreach {a b c} [db eval {PRAGMA wal_checkpoint}] break
           71  +  list [expr {$a==0}] [expr {$b>14500}] [expr {$c>14500}] [expr {$b==$c}]
           72  +} {1 1 1 1}
    68     73   
    69     74   # At this point connection [db2] has mapped the first 32KB of the *shm file
    70     75   # only. Because the entire WAL file has been checkpointed, it is not 
    71     76   # necessary to map any more of the *-shm file to read or write the database
    72     77   # (since all data will be read directly from the db file). 
    73     78   #
    74     79   # However, at one point if a transaction that had not yet written to the 
................................................................................
    83     88         INSERT INTO t VALUES('hello');
    84     89       ROLLBACK;
    85     90     } db2
    86     91   } {}
    87     92   db2 close
    88     93   
    89     94   finish_test
    90         -

Changes to test/where.test.

  1075   1075   } {1 one 4 four nosort}
  1076   1076   
  1077   1077   # Ticket #2211.
  1078   1078   #
  1079   1079   # When optimizing out ORDER BY clauses, make sure that trailing terms
  1080   1080   # of the ORDER BY clause do not reference other tables in a join.
  1081   1081   #
         1082  +if {[permutation] != "no_optimization"} {
  1082   1083   do_test where-14.1 {
  1083   1084     execsql {
  1084   1085       CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT UNIQUE);
  1085   1086       INSERT INTO t8 VALUES(1,'one');
  1086   1087       INSERT INTO t8 VALUES(4,'four');
  1087   1088     }
  1088   1089     cksort {
................................................................................
  1152   1153     } 
  1153   1154   } {4/1 4/4 1/1 1/4 sort}
  1154   1155   do_test where-14.12 {
  1155   1156     cksort {
  1156   1157       SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||x.b DESC
  1157   1158     } 
  1158   1159   } {4/4 4/1 1/4 1/1 sort}
         1160  +} ;# {permutation != "no_optimization"}
  1159   1161   
  1160   1162   # Ticket #2445.
  1161   1163   #
  1162   1164   # There was a crash that could occur when a where clause contains an
  1163   1165   # alias for an expression in the result set, and that expression retrieves
  1164   1166   # a column of the second or subsequent table in a join.
  1165   1167   #

Added test/whereE.test.

            1  +# 2012 November 9
            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 file is testing the query planner to make sure it
           13  +# is making good planning decisions.
           14  +#
           15  +
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +set ::testprefix whereE
           20  +
           21  +do_execsql_test 1.1 {
           22  +  CREATE TABLE t1(a,b);
           23  +  INSERT INTO t1 VALUES(1,10), (2,20), (3,30), (2,22), (3, 33);
           24  +  INSERT INTO t1 SELECT * FROM t1;
           25  +  INSERT INTO t1 SELECT * FROM t1;
           26  +  INSERT INTO t1 SELECT * FROM t1;
           27  +  INSERT INTO t1 SELECT * FROM t1;
           28  +  INSERT INTO t1 SELECT * FROM t1;
           29  +  INSERT INTO t1 SELECT * FROM t1;
           30  +  INSERT INTO t1 SELECT * FROM t1;
           31  +  INSERT INTO t1 SELECT * FROM t1;
           32  +  INSERT INTO t1 SELECT * FROM t1;
           33  +  INSERT INTO t1 SELECT * FROM t1;
           34  +  ALTER TABLE t1 ADD COLUMN c;
           35  +  UPDATE t1 SET c=a*rowid+10000;
           36  +  CREATE INDEX t1ab ON t1(a,b);
           37  +  
           38  +  CREATE TABLE t2(x,y);
           39  +  INSERT INTO t2 VALUES(4,44),(5,55),(6,66),(7,77);
           40  +  INSERT INTO t2 SELECT x+4, (x+4)*11 FROM t2;
           41  +  INSERT INTO t2 SELECT x+8, (x+8)*11 FROM t2;
           42  +  INSERT INTO t2 SELECT x+16, (x+16)*11 FROM t2;
           43  +  INSERT INTO t2 SELECT x+32, (x+32)*11 FROM t2;
           44  +  INSERT INTO t2 SELECT x+64, (x+32)*11 FROM t2;
           45  +  ALTER TABLE t2 ADD COLUMN z;
           46  +  UPDATE t2 SET z=2;
           47  +  CREATE UNIQUE INDEX t2zx ON t2(z,x);
           48  +
           49  +  EXPLAIN QUERY PLAN SELECT x FROM t1, t2 WHERE a=z AND c=x;
           50  +} {/.*SCAN TABLE t1 .*SEARCH TABLE t2 .*/}
           51  +do_execsql_test 1.2 {
           52  +  EXPLAIN QUERY PLAN SELECT x FROM t2, t1 WHERE a=z AND c=x;
           53  +} {/.*SCAN TABLE t1 .*SEARCH TABLE t2 .*/}
           54  +do_execsql_test 1.3 {
           55  +  ANALYZE;
           56  +  EXPLAIN QUERY PLAN SELECT x FROM t1, t2 WHERE a=z AND c=x;
           57  +} {/.*SCAN TABLE t1 .*SEARCH TABLE t2 .*/}
           58  +do_execsql_test 1.4 {
           59  +  EXPLAIN QUERY PLAN SELECT x FROM t2, t1 WHERE a=z AND c=x;
           60  +} {/.*SCAN TABLE t1 .*SEARCH TABLE t2 .*/}
           61  +
           62  +finish_test

Added test/whereF.test.

            1  +# 2012 November 9
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# 
           12  +# Test cases for query planning decisions.
           13  +
           14  +
           15  +#
           16  +# The tests in this file demonstrate the behaviour of the query planner
           17  +# in determining the order in which joined tables are scanned.
           18  +#
           19  +# Assume there are two tables being joined - t1 and t2. Each has a cost
           20  +# if it is the outer loop, and a cost if it is the inner loop. As follows:
           21  +#
           22  +#   t1(outer) - cost of scanning t1 as the outer loop.
           23  +#   t1(inner) - cost of scanning t1 as the inner loop.
           24  +#   t2(outer) - cost of scanning t2 as the outer loop.
           25  +#   t2(inner) - cost of scanning t2 as the inner loop.
           26  +#
           27  +# Depending on the order in which the planner nests the scans, the total
           28  +# cost of the join query is one of:
           29  +#
           30  +#   t1(outer) * t2(inner)
           31  +#   t2(outer) * t1(inner)
           32  +#
           33  +# The tests in this file attempt to verify that the planner nests joins in
           34  +# the correct order when the following are true:
           35  +#
           36  +#   + (t1(outer) * t2(inner)) > (t1(inner) * t2(outer)
           37  +#   +  t1(outer) < t2(outer)
           38  +#
           39  +# In other words, when the best overall query plan has t2 as the outer loop,
           40  +# but when the outer loop is considered independent of the inner, t1 is the
           41  +# most efficient choice.
           42  +#
           43  +# In order to make them more predictable, automatic indexes are turned off for
           44  +# the tests in this file.
           45  +#
           46  +
           47  +set testdir [file dirname $argv0]
           48  +source $testdir/tester.tcl
           49  +set testprefix x
           50  +
           51  +do_execsql_test 1.0 {
           52  +  PRAGMA automatic_index = 0;
           53  +  CREATE TABLE t1(a, b, c);
           54  +  CREATE TABLE t2(d, e, f);
           55  +  CREATE UNIQUE INDEX i1 ON t1(a);
           56  +  CREATE UNIQUE INDEX i2 ON t2(d);
           57  +} {}
           58  +
           59  +foreach {tn sql} {
           60  +  1 "SELECT * FROM t1,           t2 WHERE t1.a=t2.e AND t2.d<t1.b AND t1.c!=10"
           61  +  2 "SELECT * FROM t2,           t1 WHERE t1.a=t2.e AND t2.d<t1.b AND t1.c!=10"
           62  +  3 "SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=t2.e AND t2.d<t1.b AND t1.c!=10"
           63  +} {
           64  +  do_test 1.$tn {
           65  +    db eval "EXPLAIN QUERY PLAN $sql"
           66  +   } {/.*SCAN TABLE t2 .*SEARCH TABLE t1 .*/}
           67  +}
           68  +
           69  +do_execsql_test 2.0 {
           70  +  DROP TABLE t1;
           71  +  DROP TABLE t2;
           72  +  CREATE TABLE t1(a, b, c);
           73  +  CREATE TABLE t2(d, e, f);
           74  +
           75  +  CREATE UNIQUE INDEX i1 ON t1(a);
           76  +  CREATE UNIQUE INDEX i2 ON t1(b);
           77  +  CREATE UNIQUE INDEX i3 ON t2(d);
           78  +} {}
           79  +
           80  +foreach {tn sql} {
           81  +  1 "SELECT * FROM t1,           t2 WHERE t1.a>? AND t2.d>t1.c AND t1.b=t2.e"
           82  +  2 "SELECT * FROM t2,           t1 WHERE t1.a>? AND t2.d>t1.c AND t1.b=t2.e"
           83  +  3 "SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a>? AND t2.d>t1.c AND t1.b=t2.e"
           84  +} {
           85  +  do_test 2.$tn {
           86  +    db eval "EXPLAIN QUERY PLAN $sql"
           87  +   } {/.*SCAN TABLE t2 .*SEARCH TABLE t1 .*/}
           88  +}
           89  +
           90  +do_execsql_test 3.0 {
           91  +  DROP TABLE t1;
           92  +  DROP TABLE t2;
           93  +  CREATE TABLE t1(a, b, c);
           94  +  CREATE TABLE t2(d, e, f);
           95  +
           96  +  CREATE UNIQUE INDEX i1 ON t1(a, b);
           97  +  CREATE INDEX i2 ON t2(d);
           98  +} {}
           99  +
          100  +foreach {tn sql} {
          101  +  1 {SELECT t1.a, t1.b, t2.d, t2.e FROM t1, t2 
          102  +     WHERE t2.d=t1.b AND t1.a=(t2.d+1) AND t1.b = (t2.e+1)}
          103  +
          104  +  2 {SELECT t1.a, t1.b, t2.d, t2.e FROM t2, t1 
          105  +     WHERE t2.d=t1.b AND t1.a=(t2.d+1) AND t1.b = (t2.e+1)}
          106  +
          107  +  3 {SELECT t1.a, t1.b, t2.d, t2.e FROM t2 CROSS JOIN t1 
          108  +     WHERE t2.d=t1.b AND t1.a=(t2.d+1) AND t1.b = (t2.e+1)}
          109  +} {
          110  +  do_test 3.$tn {
          111  +    db eval "EXPLAIN QUERY PLAN $sql"
          112  +   } {/.*SCAN TABLE t2 .*SEARCH TABLE t1 .*/}
          113  +}
          114  +
          115  +finish_test

Changes to tool/build-all-msvc.bat.

     2      2   
     3      3   ::
     4      4   :: build-all-msvc.bat --
     5      5   ::
     6      6   :: Multi-Platform Build Tool for MSVC
     7      7   ::
     8      8   
            9  +REM
           10  +REM This batch script is used to build the SQLite DLL for multiple platforms
           11  +REM and configurations using MSVC.  The built SQLite DLLs, their associated
           12  +REM import libraries, and optionally their symbols files, are placed within
           13  +REM the directory specified on the command line, in sub-directories named for
           14  +REM their respective platforms and configurations.  This batch script must be
           15  +REM run from inside a Visual Studio Command Prompt for the desired version of
           16  +REM Visual Studio ^(the initial platform configured for the command prompt does
           17  +REM not really matter^).  Exactly one command line argument is required, the
           18  +REM name of an existing directory to be used as the final destination directory
           19  +REM for the generated output files, which will be placed in sub-directories
           20  +REM created therein.  Ideally, the directory specified should be empty.
           21  +REM
           22  +REM Example:
           23  +REM
           24  +REM                        CD /D C:\dev\sqlite\core
           25  +REM                        tool\build-all-msvc.bat C:\Temp
           26  +REM
           27  +REM In the example above, "C:\dev\sqlite\core" represents the root of the
           28  +REM source tree for SQLite and "C:\Temp" represents the final destination
           29  +REM directory for the generated output files.
           30  +REM
           31  +REM There are several environment variables that may be set to modify the
           32  +REM behavior of this batch script and its associated Makefile.  The list of
           33  +REM platforms to build may be overriden by using the PLATFORMS environment
           34  +REM variable, which should contain a list of platforms ^(e.g. x86 x86_amd64
           35  +REM x86_arm^).  All platforms must be supported by the version of Visual Studio
           36  +REM being used.  The list of configurations to build may be overridden by
           37  +REM setting the CONFIGURATIONS environment variable, which should contain a
           38  +REM list of configurations to build ^(e.g. Debug Retail^).  Neither of these
           39  +REM variable values may contain any double quotes, surrounding or embedded.
           40  +REM Finally, the NCRTLIBPATH and NSDKLIBPATH environment variables may be set
           41  +REM to specify the location of the CRT and SDK, respectively, needed to compile
           42  +REM executables native to the architecture of the build machine during any
           43  +REM cross-compilation that may be necessary, depending on the platforms to be
           44  +REM built.  These values in these two variables should be surrounded by double
           45  +REM quotes if they contain spaces.
           46  +REM
           47  +REM Please note that the SQLite build process performed by the Makefile
           48  +REM associated with this batch script requires both Gawk ^(gawk.exe^) and Tcl
           49  +REM 8.5 ^(tclsh85.exe^) to be present in a directory contained in the PATH
           50  +REM environment variable unless a pre-existing amalgamation file is used.
           51  +REM
     9     52   SETLOCAL
    10     53   
    11     54   REM SET __ECHO=ECHO
    12     55   REM SET __ECHO2=ECHO
    13     56   REM SET __ECHO3=ECHO
    14     57   IF NOT DEFINED _AECHO (SET _AECHO=REM)
    15     58   IF NOT DEFINED _CECHO (SET _CECHO=REM)
................................................................................
    89    132   REM
    90    133   IF NOT DEFINED PLATFORMS (
    91    134     SET PLATFORMS=x86 x86_amd64 x86_arm
    92    135   )
    93    136   
    94    137   %_VECHO% Platforms = '%PLATFORMS%'
    95    138   
          139  +REM
          140  +REM NOTE: If the list of configurations is not already set, use the default
          141  +REM       list.
          142  +REM
          143  +IF NOT DEFINED CONFIGURATIONS (
          144  +  SET CONFIGURATIONS=Debug Retail
          145  +)
          146  +
          147  +%_VECHO% Configurations = '%CONFIGURATIONS%'
          148  +
    96    149   REM
    97    150   REM NOTE: Setup environment variables to translate between the MSVC platform
    98    151   REM       names and the names to be used for the platform-specific binary
    99    152   REM       directories.
   100    153   REM
          154  +SET amd64_NAME=x64
          155  +SET arm_NAME=ARM
          156  +SET x64_NAME=x64
   101    157   SET x86_NAME=x86
   102    158   SET x86_amd64_NAME=x64
   103    159   SET x86_arm_NAME=ARM
          160  +SET x86_x64_NAME=x64
   104    161   
          162  +%_VECHO% amd64_Name = '%amd64_NAME%'
          163  +%_VECHO% arm_Name = '%arm_NAME%'
          164  +%_VECHO% x64_Name = '%x64_NAME%'
   105    165   %_VECHO% x86_Name = '%x86_NAME%'
   106    166   %_VECHO% x86_amd64_Name = '%x86_amd64_NAME%'
   107    167   %_VECHO% x86_arm_Name = '%x86_arm_NAME%'
          168  +%_VECHO% x86_x64_Name = '%x86_x64_NAME%'
   108    169   
   109    170   REM
   110    171   REM NOTE: Check for the external tools needed during the build process ^(i.e.
   111    172   REM       those that do not get compiled as part of the build process itself^)
   112    173   REM       along the PATH.
   113    174   REM
   114    175   FOR %%T IN (gawk.exe tclsh85.exe) DO (
   115    176     SET %%T_PATH=%%~dp$PATH:T
   116    177   )
          178  +
          179  +REM
          180  +REM NOTE: The Gawk executable "gawk.exe" is required during the SQLite build
          181  +REM       process unless a pre-existing amalgamation file is used.
          182  +REM
          183  +IF NOT DEFINED gawk.exe_PATH (
          184  +  ECHO The Gawk executable "gawk.exe" is required to be in the PATH.
          185  +  GOTO errors
          186  +)
          187  +
          188  +REM
          189  +REM NOTE: The Tcl 8.5 executable "tclsh85.exe" is required during the SQLite
          190  +REM       build process unless a pre-existing amalgamation file is used.
          191  +REM
          192  +IF NOT DEFINED tclsh85.exe_PATH (
          193  +  ECHO The Tcl 8.5 executable "tclsh85.exe" is required to be in the PATH.
          194  +  GOTO errors
          195  +)
   117    196   
   118    197   REM
   119    198   REM NOTE: Set the TOOLPATH variable to contain all the directories where the
   120    199   REM       external tools were found in the search above.
   121    200   REM
   122    201   SET TOOLPATH=%gawk.exe_PATH%;%tclsh85.exe_PATH%
   123    202   
................................................................................
   124    203   %_VECHO% ToolPath = '%TOOLPATH%'
   125    204   
   126    205   REM
   127    206   REM NOTE: Check for MSVC 2012 because the Windows SDK directory handling is
   128    207   REM       slightly different for that version.
   129    208   REM
   130    209   IF "%VisualStudioVersion%" == "11.0" (
   131         -  SET SET_NSDKLIBPATH=1
          210  +  REM
          211  +  REM NOTE: If the Windows SDK library path has already been set, do not set
          212  +  REM       it to something else later on.
          213  +  REM
          214  +  IF NOT DEFINED NSDKLIBPATH (
          215  +    SET SET_NSDKLIBPATH=1
          216  +  )
   132    217   ) ELSE (
   133    218     CALL :fn_UnsetVariable SET_NSDKLIBPATH
   134    219   )
   135    220   
          221  +REM
          222  +REM NOTE: Check if this is the Windows Phone SDK.  If so, a different batch
          223  +REM       file is necessary to setup the build environment.  Since the variable
          224  +REM       values involved here may contain parenthesis, using GOTO instead of
          225  +REM       an IF block is required.
          226  +REM
          227  +IF DEFINED WindowsPhoneKitDir GOTO set_vcvarsall_phone
          228  +SET VCVARSALL=%VCINSTALLDIR%\vcvarsall.bat
          229  +GOTO set_vcvarsall_done
          230  +:set_vcvarsall_phone
          231  +SET VCVARSALL=%VCINSTALLDIR%\WPSDK\WP80\vcvarsphoneall.bat
          232  +:set_vcvarsall_done
          233  +
   136    234   REM
   137    235   REM NOTE: This is the outer loop.  There should be exactly one iteration per
   138    236   REM       platform.
   139    237   REM
   140    238   FOR %%P IN (%PLATFORMS%) DO (
   141    239     REM
   142    240     REM NOTE: Using the MSVC platform name, lookup the simpler platform name to
................................................................................
   169    267       CALL :fn_UnsetVariable FSHARPINSTALLDIR
   170    268       CALL :fn_UnsetVariable INCLUDE
   171    269       CALL :fn_UnsetVariable LIB
   172    270       CALL :fn_UnsetVariable LIBPATH
   173    271       CALL :fn_UnsetVariable Platform
   174    272       REM CALL :fn_UnsetVariable VCINSTALLDIR
   175    273       CALL :fn_UnsetVariable VSINSTALLDIR
          274  +    CALL :fn_UnsetVariable WindowsPhoneKitDir
   176    275       CALL :fn_UnsetVariable WindowsSdkDir
   177    276       CALL :fn_UnsetVariable WindowsSdkDir_35
   178    277       CALL :fn_UnsetVariable WindowsSdkDir_old
   179    278   
   180    279       REM
   181    280       REM NOTE: Reset the PATH here to the absolute bare minimum required.
   182    281       REM
   183    282       SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
   184    283   
   185         -    FOR %%B IN (Debug Retail) DO (
          284  +    FOR %%B IN (%CONFIGURATIONS%) DO (
   186    285         REM
   187    286         REM NOTE: When preparing the debug build, set the DEBUG and MEMDEBUG
   188    287         REM       environment variables to be picked up by the MSVC makefile
   189    288         REM       itself.
   190    289         REM
   191    290         IF /I "%%B" == "Debug" (
   192    291           SET DEBUG=2
................................................................................
   211    310         REM          platform to the platform-specific directory beneath the
   212    311         REM          binary directory.
   213    312         REM
   214    313         "%ComSpec%" /C (
   215    314           REM
   216    315           REM NOTE: Attempt to setup the MSVC environment for this platform.
   217    316           REM
   218         -        %__ECHO3% CALL "%VCINSTALLDIR%\vcvarsall.bat" %%P
          317  +        %__ECHO3% CALL "%VCVARSALL%" %%P
   219    318   
   220    319           IF ERRORLEVEL 1 (
   221         -          ECHO Failed to call "%VCINSTALLDIR%\vcvarsall.bat" for platform %%P.
          320  +          ECHO Failed to call "%VCVARSALL%" for platform %%P.
   222    321             GOTO errors
   223    322           )
   224    323   
   225    324           REM
   226    325           REM NOTE: If this batch file is not running in "what-if" mode, check to
   227    326           REM       be sure we were actually able to setup the MSVC environment
   228    327           REM       as current versions of their official batch file do not set
   229    328           REM       the exit code upon failure.
   230    329           REM
   231         -        IF NOT DEFINED __ECHO (
   232         -          IF NOT DEFINED WindowsSdkDir (
   233         -            ECHO Cannot build, Windows SDK not found for platform %%P.
   234         -            GOTO errors
          330  +        IF NOT DEFINED __ECHO3 (
          331  +          IF NOT DEFINED WindowsPhoneKitDir (
          332  +            IF NOT DEFINED WindowsSdkDir (
          333  +              ECHO Cannot build, Windows SDK not found for platform %%P.
          334  +              GOTO errors
          335  +            )
   235    336             )
   236    337           )
   237    338   
   238    339           REM
   239    340           REM NOTE: When using MSVC 2012, the native SDK path cannot simply use
   240    341           REM       the "lib" sub-directory beneath the location specified in the
   241    342           REM       WindowsSdkDir environment variable because that location does
   242    343           REM       not actually contain the necessary library files for x86.
   243    344           REM       This must be done for each iteration because it relies upon
   244    345           REM       the WindowsSdkDir environment variable being set by the batch
   245    346           REM       file used to setup the MSVC environment.
   246    347           REM
   247    348           IF DEFINED SET_NSDKLIBPATH (
   248         -          CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
   249         -          CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
          349  +          IF DEFINED WindowsPhoneKitDir (
          350  +            CALL :fn_CopyVariable WindowsPhoneKitDir NSDKLIBPATH
          351  +            CALL :fn_AppendVariable NSDKLIBPATH \lib\x86
          352  +          ) ELSE IF DEFINED WindowsSdkDir (
          353  +            CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
          354  +            CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
          355  +          )
   250    356           )
   251    357   
   252    358           REM
   253    359           REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
   254    360           REM       makefile to clean any stale build output from previous
   255    361           REM       iterations of this loop and/or previous runs of this batch
   256    362           REM       file, etc.

Changes to tool/mkvsix.tcl.

     1      1   #!/usr/bin/tclsh
     2      2   #
     3      3   # This script is used to generate a VSIX (Visual Studio Extension) file for
     4      4   # SQLite usable by Visual Studio.
     5         -
            5  +#
            6  +# PREREQUISITES
            7  +#
            8  +# 1. Tcl 8.4 and later are supported, earlier versions have not been tested.
            9  +#
           10  +# 2. The "sqlite3.h" file is assumed to exist in the parent directory of the
           11  +#    directory containing this script.  The [optional] second command line
           12  +#    argument to this script may be used to specify an alternate location.
           13  +#    This script also assumes that the "sqlite3.h" file corresponds with the
           14  +#    version of the binaries to be packaged.  This assumption is not verified
           15  +#    by this script.
           16  +#
           17  +# 3. The temporary directory specified in the TEMP or TMP environment variables
           18  +#    must refer to an existing directory writable by the current user.
           19  +#
           20  +# 4. The "zip" and "unzip" command line tools must be located either in a
           21  +#    directory contained in the PATH environment variable or specified as the
           22  +#    exact file names to execute in the "ZipTool" and "UnZipTool" environment
           23  +#    variables, respectively.
           24  +#
           25  +# 5. The template VSIX file (which is basically a zip file) must be located in
           26  +#    a "win" directory inside the directory containing this script.  It should
           27  +#    not contain any executable binaries.  It should only contain dynamic
           28  +#    textual content files to be processed using [subst] and/or static content
           29  +#    files to be copied verbatim.
           30  +#
           31  +# 6. The executable and other compiled binary files to be packaged into the
           32  +#    final VSIX file (e.g. DLLs, LIBs, and PDBs) must be located in a single
           33  +#    directory tree.  The top-level directory of the tree must be specified as
           34  +#    the first command line argument to this script.  The second level
           35  +#    sub-directory names must match those of the build configuration (e.g.
           36  +#    "Debug" or "Retail").  The third level sub-directory names must match
           37  +#    those of the platform (e.g. "x86", "x64", and "ARM").  For example, the
           38  +#    binary files to be packaged would need to be organized as follows when
           39  +#    packaging the "Debug" and "Retail" build configurations for the "x86" and
           40  +#    "x64" platforms (in this example, "C:\temp" is the top-level directory as
           41  +#    specified in the first command line argument):
           42  +#
           43  +#                         C:\Temp\Debug\x86\sqlite3.lib
           44  +#                         C:\Temp\Debug\x86\sqlite3.dll
           45  +#                         C:\Temp\Debug\x86\sqlite3.pdb
           46  +#                         C:\Temp\Debug\x64\sqlite3.lib
           47  +#                         C:\Temp\Debug\x64\sqlite3.dll
           48  +#                         C:\Temp\Debug\x64\sqlite3.pdb
           49  +#                         C:\Temp\Retail\x86\sqlite3.lib
           50  +#                         C:\Temp\Retail\x86\sqlite3.dll
           51  +#                         C:\Temp\Retail\x86\sqlite3.pdb
           52  +#                         C:\Temp\Retail\x64\sqlite3.lib
           53  +#                         C:\Temp\Retail\x64\sqlite3.dll
           54  +#                         C:\Temp\Retail\x64\sqlite3.pdb
           55  +#
           56  +#    The above directory tree organization is performed automatically if the
           57  +#    "tool\build-all-msvc.bat" batch script is used to build the binary files
           58  +#    to be packaged.
           59  +#
           60  +# USAGE
           61  +#
           62  +# The first argument to this script is required and must be the name of the
           63  +# top-level directory containing the directories and files organized into a
           64  +# tree as described in item 6 of the PREREQUISITES section, above.  The second
           65  +# argument is optional and if present must contain the name of the directory
           66  +# containing the root of the source tree for SQLite.  The third argument is
           67  +# optional and if present must contain the flavor the VSIX package to build.
           68  +# Currently, the only supported package flavors are "WinRT" and "WP80".  The
           69  +# fourth argument is optional and if present must be a string containing a list
           70  +# of platforms to include in the VSIX package.  The format of the platform list
           71  +# string is "platform1,platform2,platform3".  Typically, when on Windows, this
           72  +# script is executed using commands similar to the following from a normal
           73  +# Windows command prompt:
           74  +#
           75  +#                         CD /D C:\dev\sqlite\core
           76  +#                         tclsh85 tool\mkvsix.tcl C:\Temp
           77  +#
           78  +# In the example above, "C:\dev\sqlite\core" represents the root of the source
           79  +# tree for SQLite and "C:\Temp" represents the top-level directory containing
           80  +# the executable and other compiled binary files, organized into a directory
           81  +# tree as described in item 6 of the PREREQUISITES section, above.
           82  +#
           83  +# This script should work on non-Windows platforms as well, provided that all
           84  +# the requirements listed in the PREREQUISITES section are met.
           85  +#
           86  +# NOTES
           87  +#
           88  +# The temporary directory is used as a staging area for the final VSIX file.
           89  +# The template VSIX file is extracted, its contents processed, and then the
           90  +# resulting files are packaged into the final VSIX file.
           91  +#
           92  +package require Tcl 8.4
           93  +
     6     94   proc fail { {error ""} {usage false} } {
     7     95     if {[string length $error] > 0} then {
     8     96       puts stdout $error
     9     97       if {!$usage} then {exit 1}
    10     98     }
    11     99   
    12    100     puts stdout "usage:\
    13    101   [file tail [info nameofexecutable]]\
    14         -[file tail [info script]] <binaryDirectory> \[sourceDirectory\]"
          102  +[file tail [info script]] <binaryDirectory> \[sourceDirectory\]\
          103  +\[packageFlavor\] \[platformNames\]"
    15    104   
    16    105     exit 1
    17    106   }
    18    107   
    19    108   proc getEnvironmentVariable { name } {
    20    109     #
    21    110     # NOTE: Returns the value of the specified environment variable or an empty
................................................................................
    80    169     close $file_id
    81    170     return ""
    82    171   }
    83    172   
    84    173   proc substFile { fileName } {
    85    174     #
    86    175     # NOTE: Performs all Tcl command, variable, and backslash substitutions in
    87         -  #       the specified file and then re-writes the contents of that same file
          176  +  #       the specified file and then rewrites the contents of that same file
    88    177     #       with the substituted data.
    89    178     #
    90    179     return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
    91    180   }
    92    181   
    93         -proc replaceBuildAndPlatform { fileName buildName platformName } {
          182  +proc replaceFileNameTokens { fileName name buildName platformName } {
    94    183     #
    95    184     # NOTE: Returns the specified file name containing the platform name instead
    96    185     #       of platform placeholder tokens.
    97    186     #
    98         -  return [string map [list <build> $buildName <platform> $platformName] \
    99         -      $fileName]
          187  +  return [string map [list <build> $buildName <platform> $platformName \
          188  +      <name> $name] $fileName]
   100    189   }
   101    190   
          191  +#
          192  +# NOTE: This is the entry point for this script.
          193  +#
   102    194   set script [file normalize [info script]]
   103    195   
   104    196   if {[string length $script] == 0} then {
   105    197     fail "script file currently being evaluated is unknown" true
   106    198   }
   107    199   
   108    200   set path [file dirname $script]
................................................................................
   110    202   
   111    203   ###############################################################################
   112    204   
   113    205   #
   114    206   # NOTE: Process and verify all the command line arguments.
   115    207   #
   116    208   set argc [llength $argv]
   117         -if {$argc != 1 && $argc != 2} then {fail}
          209  +if {$argc < 1 || $argc > 4} then {fail}
   118    210   
   119    211   set binaryDirectory [lindex $argv 0]
   120    212   
   121    213   if {[string length $binaryDirectory] == 0} then {
   122    214     fail "invalid binary directory"
   123    215   }
   124    216   
   125    217   if {![file exists $binaryDirectory] || \
   126    218       ![file isdirectory $binaryDirectory]} then {
   127    219     fail "binary directory does not exist"
   128    220   }
   129    221   
   130         -if {$argc == 2} then {
          222  +if {$argc >= 2} then {
   131    223     set sourceDirectory [lindex $argv 1]
   132    224   } else {
   133    225     #
   134    226     # NOTE: Assume that the source directory is the parent directory of the one
   135    227     #       that contains this script file.
   136    228     #
   137    229     set sourceDirectory [file dirname $path]
................................................................................
   141    233     fail "invalid source directory"
   142    234   }
   143    235   
   144    236   if {![file exists $sourceDirectory] || \
   145    237       ![file isdirectory $sourceDirectory]} then {
   146    238     fail "source directory does not exist"
   147    239   }
          240  +
          241  +if {$argc >= 3} then {
          242  +  set packageFlavor [lindex $argv 2]
          243  +} else {
          244  +  #
          245  +  # NOTE: Assume the package flavor is WinRT.
          246  +  #
          247  +  set packageFlavor WinRT
          248  +}
          249  +
          250  +if {[string length $packageFlavor] == 0} then {
          251  +  fail "invalid package flavor"
          252  +}
          253  +
          254  +if {[string equal -nocase $packageFlavor WinRT]} then {
          255  +  set shortName SQLite.WinRT
          256  +  set displayName "SQLite for Windows Runtime"
          257  +  set targetPlatformIdentifier Windows
          258  +  set extraSdkPath ""
          259  +  set extraFileListAttributes [appendArgs \
          260  +      "\r\n    " {AppliesTo="WindowsAppContainer"} \
          261  +      "\r\n    " {DependsOn="Microsoft.VCLibs, version=11.0"}]
          262  +} elseif {[string equal -nocase $packageFlavor WP80]} then {
          263  +  set shortName SQLite.WP80
          264  +  set displayName "SQLite for Windows Phone"
          265  +  set targetPlatformIdentifier "Windows Phone"
          266  +  set extraSdkPath "\\..\\$targetPlatformIdentifier"
          267  +  set extraFileListAttributes ""
          268  +} else {
          269  +  fail "unsupported package flavor, must be \"WinRT\" or \"WP80\""
          270  +}
          271  +
          272  +if {$argc >= 4} then {
          273  +  set platformNames [list]
          274  +
          275  +  foreach platformName [split [lindex $argv 3] ", "] {
          276  +    if {[string length $platformName] > 0} then {
          277  +      lappend platformNames $platformName
          278  +    }
          279  +  }
          280  +}
   148    281   
   149    282   ###############################################################################
   150    283   
   151    284   #
   152    285   # NOTE: Evaluate the user-specific customizations file, if it exists.
   153    286   #
   154    287   set userFile [file join $path [appendArgs \
................................................................................
   165    298   
   166    299   if {![file exists $templateFile] || \
   167    300       ![file isfile $templateFile]} then {
   168    301     fail [appendArgs "template file \"" $templateFile "\" does not exist"]
   169    302   }
   170    303   
   171    304   set currentDirectory [pwd]
   172         -set outputFile [file join $currentDirectory sqlite-output.vsix]
          305  +set outputFile [file join $currentDirectory [appendArgs sqlite- \
          306  +    $packageFlavor -output.vsix]]
   173    307   
   174    308   if {[file exists $outputFile]} then {
   175    309     fail [appendArgs "output file \"" $outputFile "\" already exists"]
   176    310   }
   177    311   
   178    312   ###############################################################################
   179    313   
................................................................................
   241    375     fail [appendArgs "cannot locate SQLITE_VERSION value in \"" \
   242    376         [file join $sourceDirectory sqlite3.h] \"]
   243    377   }
   244    378   
   245    379   ###############################################################################
   246    380   
   247    381   #
   248         -# NOTE: Setup the master file list data, including the necessary flags.
          382  +# NOTE: Setup all the master file list data.  This includes the source file
          383  +#       names, the destination file names, and the file processing flags.  The
          384  +#       possible file processing flags are:
          385  +#
          386  +#       "buildNeutral" -- This flag indicates the file location and content do
          387  +#                         not depend on the build configuration.
          388  +#
          389  +#       "platformNeutral" -- This flag indicates the file location and content
          390  +#                            do not depend on the build platform.
          391  +#
          392  +#       "subst" -- This flag indicates that the file contains dynamic textual
          393  +#                  content that needs to be processed using [subst] prior to
          394  +#                  packaging the file into the final VSIX package.  The primary
          395  +#                  use of this flag is to insert the name of the VSIX package,
          396  +#                  some package flavor-specific value, or the SQLite version
          397  +#                  into a file.
          398  +#
          399  +#       "noDebug" -- This flag indicates that the file should be skipped when
          400  +#                    processing the debug build.
          401  +#
          402  +#       "noRetail" -- This flag indicates that the file should be skipped when
          403  +#                     processing the retail build.
          404  +#
          405  +#       "move" -- This flag indicates that the file should be moved from the
          406  +#                 source to the destination instead of being copied.
          407  +#
          408  +#       This file metadata may be overridden, either in whole or in part, via
          409  +#       the user-specific customizations file.
   249    410   #
   250    411   if {![info exists fileNames(source)]} then {
   251         -  set fileNames(source) [list "" "" "" \
   252         -      [file join $sourceDirectory sqlite3.h] \
   253         -      [file join $binaryDirectory <build> <platform> sqlite3.lib] \
   254         -      [file join $binaryDirectory <build> <platform> sqlite3.dll]]
          412  +  set fileNames(source) [list "" "" \
          413  +    [file join $stagingDirectory DesignTime <build> <platform> sqlite3.props] \
          414  +    [file join $sourceDirectory sqlite3.h] \
          415  +    [file join $binaryDirectory <build> <platform> sqlite3.lib] \
          416  +    [file join $binaryDirectory <build> <platform> sqlite3.dll]]
   255    417   
   256    418     if {![info exists no(symbols)]} then {
   257    419       lappend fileNames(source) \
   258    420           [file join $binaryDirectory <build> <platform> sqlite3.pdb]
   259    421     }
   260    422   }
   261    423   
   262    424   if {![info exists fileNames(destination)]} then {
   263    425     set fileNames(destination) [list \
   264         -      [file join $stagingDirectory extension.vsixmanifest] \
   265         -      [file join $stagingDirectory SDKManifest.xml] \
   266         -      [file join $stagingDirectory DesignTime <build> <platform> \
   267         -          SQLite.WinRT.props] \
   268         -      [file join $stagingDirectory DesignTime <build> <platform> sqlite3.h] \
   269         -      [file join $stagingDirectory DesignTime <build> <platform> sqlite3.lib] \
   270         -      [file join $stagingDirectory Redist <build> <platform> sqlite3.dll]]
          426  +    [file join $stagingDirectory extension.vsixmanifest] \
          427  +    [file join $stagingDirectory SDKManifest.xml] \
          428  +    [file join $stagingDirectory DesignTime <build> <platform> <name>.props] \
          429  +    [file join $stagingDirectory DesignTime <build> <platform> sqlite3.h] \
          430  +    [file join $stagingDirectory DesignTime <build> <platform> sqlite3.lib] \
          431  +    [file join $stagingDirectory Redist <build> <platform> sqlite3.dll]]
   271    432   
   272    433     if {![info exists no(symbols)]} then {
   273    434       lappend fileNames(destination) \
   274    435           [file join $stagingDirectory Redist <build> <platform> sqlite3.pdb]
   275    436     }
   276    437   }
   277    438   
   278         -if {![info exists fileNames(buildNeutral)]} then {
   279         -  set fileNames(buildNeutral) [list 1 1 1 1 0 0]
   280         -
   281         -  if {![info exists no(symbols)]} then {
   282         -    lappend fileNames(buildNeutral) 0
   283         -  }
   284         -}
   285         -
   286         -if {![info exists fileNames(platformNeutral)]} then {
   287         -  set fileNames(platformNeutral) [list 1 1 1 1 0 0]
          439  +if {![info exists fileNames(flags)]} then {
          440  +  set fileNames(flags) [list \
          441  +      [list buildNeutral platformNeutral subst] \
          442  +      [list buildNeutral platformNeutral subst] \
          443  +      [list buildNeutral platformNeutral subst move] \
          444  +      [list buildNeutral platformNeutral] \
          445  +      [list] [list] [list noRetail]]
   288    446   
   289    447     if {![info exists no(symbols)]} then {
   290         -    lappend fileNames(platformNeutral) 0
   291         -  }
   292         -}
   293         -
   294         -if {![info exists fileNames(subst)]} then {
   295         -  set fileNames(subst) [list 1 1 1 0 0 0]
   296         -
   297         -  if {![info exists no(symbols)]} then {
   298         -    lappend fileNames(subst) 0
   299         -  }
   300         -}
   301         -
   302         -if {![info exists fileNames(noDebug)]} then {
   303         -  set fileNames(noDebug) [list 0 0 0 0 0 0]
   304         -
   305         -  if {![info exists no(symbols)]} then {
   306         -    lappend fileNames(noDebug) 0
   307         -  }
   308         -}
   309         -
   310         -if {![info exists fileNames(noRetail)]} then {
   311         -  set fileNames(noRetail) [list 0 0 0 0 0 0]
   312         -
   313         -  if {![info exists no(symbols)]} then {
   314         -    lappend fileNames(noRetail) 1
          448  +    lappend fileNames(flags) [list noRetail]
   315    449     }
   316    450   }
   317    451   
   318    452   ###############################################################################
   319    453   
   320    454   #
   321         -# NOTE: Setup the list of builds supported by this script.
          455  +# NOTE: Setup the list of builds supported by this script.  These may be
          456  +#       overridden via the user-specific customizations file.
   322    457   #
   323    458   if {![info exists buildNames]} then {
   324    459     set buildNames [list Debug Retail]
   325    460   }
   326    461   
   327    462   ###############################################################################
   328    463   
   329    464   #
   330         -# NOTE: Setup the list of platforms supported by this script.
          465  +# NOTE: Setup the list of platforms supported by this script.  These may be
          466  +#       overridden via the command line or the user-specific customizations
          467  +#       file.
   331    468   #
   332    469   if {![info exists platformNames]} then {
   333    470     set platformNames [list x86 x64 ARM]
   334    471   }
   335    472   
   336    473   ###############################################################################
   337    474   
   338    475   #
   339    476   # NOTE: Make sure the staging directory exists, creating it if necessary.
   340    477   #
   341    478   file mkdir $stagingDirectory
   342    479   
   343    480   #
   344         -# NOTE: Build the Tcl command used to extract the template package to the
   345         -#       staging directory.
          481  +# NOTE: Build the Tcl command used to extract the template VSIX package to
          482  +#       the staging directory.
   346    483   #
   347    484   set extractCommand [list exec -- $unzip $templateFile -d $stagingDirectory]
   348    485   
   349    486   #
   350         -# NOTE: Extract the template package to the staging directory.
          487  +# NOTE: Extract the template VSIX package to the staging directory.
   351    488   #
   352    489   eval $extractCommand
   353    490   
   354    491   ###############################################################################
   355    492   
   356    493   #
   357         -# NOTE: Process each file in the master file list.  There are actually seven
          494  +# NOTE: Process each file in the master file list.  There are actually three
   358    495   #       parallel lists that contain the source file names, the destination file
   359         -#       names, the build-neutral flags, the platform-neutral flags, the
   360         -#       use-subst flags, the no-debug flags, and the no-retail flags.  If the
   361         -#       platform-neutral flag is non-zero, the file is not platform-specific.
   362         -#       If the build-neutral flag is non-zero, the file is not build-specific.
   363         -#       If the use-subst flag is non-zero, the file is considered to be a text
   364         -#       file that may contain Tcl variable and/or command replacements, to be
   365         -#       dynamically replaced during processing.  If the no-debug flag is
   366         -#       non-zero, the file will be skipped when processing for the debug build.
   367         -#       If the no-retail flag is non-zero, the file will be skipped when
   368         -#       processing for the retail build.  If the source file name is an empty
   369         -#       string, then the destination file name will be assumed to already exist
   370         -#       in the staging directory and will not be copied; however, dynamic
   371         -#       replacements may still be performed on the destination file prior to
   372         -#       the package being re-zipped.
          496  +#       names, and the file processing flags. If the "buildNeutral" flag is
          497  +#       present, the file location and content do not depend on the build
          498  +#       configuration and "CommonConfiguration" will be used in place of the
          499  +#       build configuration name.  If the "platformNeutral" flag is present,
          500  +#       the file location and content do not depend on the build platform and
          501  +#       "neutral" will be used in place of the build platform name.  If the
          502  +#       "subst" flag is present, the file is assumed to be a text file that may
          503  +#       contain Tcl variable, command, and backslash replacements, to be
          504  +#       dynamically replaced during processing using the Tcl [subst] command.
          505  +#       If the "noDebug" flag is present, the file will be skipped when
          506  +#       processing for the debug build.  If the "noRetail" flag is present, the
          507  +#       file will be skipped when processing for the retail build.  If the
          508  +#       "move" flag is present, the source file will be deleted after it is
          509  +#       copied to the destination file.  If the source file name is an empty
          510  +#       string, the destination file name will be assumed to already exist in
          511  +#       the staging directory and will not be copied; however, Tcl variable,
          512  +#       command, and backslash replacements may still be performed on the
          513  +#       destination file prior to the final VSIX package being built if the
          514  +#       "subst" flag is present.
   373    515   #
   374    516   foreach sourceFileName      $fileNames(source) \
   375    517           destinationFileName $fileNames(destination) \
   376         -        buildNeutral        $fileNames(buildNeutral) \
   377         -        platformNeutral     $fileNames(platformNeutral) \
   378         -        useSubst            $fileNames(subst) \
   379         -        noDebug             $fileNames(noDebug) \
   380         -        noRetail            $fileNames(noRetail) {
          518  +        fileFlags           $fileNames(flags) {
          519  +  #
          520  +  # NOTE: Process the file flags into separate boolean variables that may be
          521  +  #       used within the loop.
          522  +  #
          523  +  set isBuildNeutral [expr {[lsearch $fileFlags buildNeutral] != -1}]
          524  +  set isPlatformNeutral [expr {[lsearch $fileFlags platformNeutral] != -1}]
          525  +  set isMove [expr {[lsearch $fileFlags move] != -1}]
          526  +  set useSubst [expr {[lsearch $fileFlags subst] != -1}]
          527  +
   381    528     #
   382    529     # NOTE: If the current file is build-neutral, then only one build will
   383    530     #       be processed for it, namely "CommonConfiguration"; otherwise, each
   384    531     #       supported build will be processed for it individually.
   385    532     #
   386    533     foreach buildName \
   387         -      [expr {$buildNeutral ? [list CommonConfiguration] : $buildNames}] {
          534  +      [expr {$isBuildNeutral ? [list CommonConfiguration] : $buildNames}] {
   388    535       #
   389    536       # NOTE: Should the current file be skipped for this build?
   390    537       #
   391         -    if {[info exists no${buildName}] && [set no${buildName}]} then {
          538  +    if {[lsearch $fileFlags no${buildName}] != -1} then {
   392    539         continue
   393    540       }
   394    541   
   395    542       #
   396    543       # NOTE: If the current file is platform-neutral, then only one platform
   397    544       #       will be processed for it, namely "neutral"; otherwise, each
   398    545       #       supported platform will be processed for it individually.
   399    546       #
   400    547       foreach platformName \
   401         -        [expr {$platformNeutral ? [list neutral] : $platformNames}] {
          548  +        [expr {$isPlatformNeutral ? [list neutral] : $platformNames}] {
   402    549         #
   403    550         # NOTE: Use the actual platform name in the destination file name.
   404    551         #
   405         -      set newDestinationFileName [replaceBuildAndPlatform \
   406         -          $destinationFileName $buildName $platformName]
          552  +      set newDestinationFileName [replaceFileNameTokens $destinationFileName \
          553  +          $shortName $buildName $platformName]
   407    554   
   408    555         #
   409    556         # NOTE: Does the source file need to be copied to the destination file?
   410    557         #
   411    558         if {[string length $sourceFileName] > 0} then {
   412    559           #
   413    560           # NOTE: First, make sure the destination directory exists.
   414    561           #
   415    562           file mkdir [file dirname $newDestinationFileName]
   416    563   
   417    564           #
   418    565           # NOTE: Then, copy the source file to the destination file verbatim.
   419    566           #
   420         -        file copy [replaceBuildAndPlatform $sourceFileName $buildName \
   421         -            $platformName] $newDestinationFileName
          567  +        set newSourceFileName [replaceFileNameTokens $sourceFileName \
          568  +            $shortName $buildName $platformName]
          569  +
          570  +        file copy $newSourceFileName $newDestinationFileName
          571  +
          572  +        #
          573  +        # NOTE: If this is a move instead of a copy, delete the source file
          574  +        #       now.
          575  +        #
          576  +        if {$isMove} then {
          577  +          file delete $newSourceFileName
          578  +        }
   422    579         }
   423    580   
   424    581         #
   425    582         # NOTE: Does the destination file contain dynamic replacements that must
   426    583         #       be processed now?
   427    584         #
   428    585         if {$useSubst} then {
................................................................................
   442    599   # NOTE: Change the current directory to the staging directory so that the
   443    600   #       external archive building tool can pickup the necessary files using
   444    601   #       relative paths.
   445    602   #
   446    603   cd $stagingDirectory
   447    604   
   448    605   #
   449         -# NOTE: Build the Tcl command used to archive the final package in the
          606  +# NOTE: Build the Tcl command used to archive the final VSIX package in the
   450    607   #       output directory.
   451    608   #
   452    609   set archiveCommand [list exec -- $zip -r $outputFile *]
   453    610   
   454    611   #
   455         -# NOTE: Build the final package archive in the output directory.
          612  +# NOTE: Build the final VSIX package archive in the output directory.
   456    613   #
   457    614   eval $archiveCommand
   458    615   
   459    616   #
   460    617   # NOTE: Change back to the previously saved current directory.
   461    618   #
   462    619   cd $currentDirectory

Changes to tool/win/sqlite.vsix.

cannot compute difference between binary files