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

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

Overview
Comment:Pull all the latest trunk enhancements into the sessions branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: fce667f2d93a4ba65ccf1e748469576a3cd7ffcc
User & Date: drh 2012-10-30 21:03:48
Context
2012-11-10
01:27
Merge the latest changes from trunk: chiefly the outer/inner loop query optimizer scoring enhancement and the INSTR() function. check-in: 2993ca20 user: drh tags: sessions
2012-10-30
21:03
Pull all the latest trunk enhancements into the sessions branch. check-in: fce667f2 user: drh tags: sessions
18:09
Enable the use of coroutines as an alternative to manifesting views used in a FROM clause. check-in: 9dca18f5 user: drh tags: trunk
2012-10-15
14:25
Merge all the latest core changes into the sessions branch. check-in: 76767d65 user: drh tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   940    940   	rm -rf quota2a quota2b quota2c
   941    941   	rm -rf tsrc .target_source
   942    942   	rm -f tclsqlite3$(TEXE)
   943    943   	rm -f testfixture$(TEXE) test.db
   944    944   	rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
   945    945   	rm -f sqlite3.c
   946    946   	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
   947         -	rm -f sqlite-output.vsix
          947  +	rm -f sqlite-*-output.vsix
   948    948   
   949    949   distclean:	clean
   950    950   	rm -f config.log config.status libtool Makefile sqlite3.pc
   951    951   
   952    952   #
   953    953   # Windows section
   954    954   #

Changes to Makefile.msc.

  1259   1259   	del /Q .target_source
  1260   1260   	del /Q tclsqlite3.exe tclsqlite3.exp
  1261   1261   	del /Q testfixture.exe testfixture.exp test.db
  1262   1262   	del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
  1263   1263   	del /Q sqlite3.c
  1264   1264   	del /Q sqlite3rc.h
  1265   1265   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
  1266         -	del /Q sqlite-output.vsix
         1266  +	del /Q sqlite-*-output.vsix
  1267   1267   
  1268   1268   # Dynamic link library section.
  1269   1269   #
  1270   1270   dll: sqlite3.dll
  1271   1271   
  1272   1272   sqlite3.def: libsqlite3.lib
  1273   1273   	echo EXPORTS > sqlite3.def
  1274   1274   	dumpbin /all libsqlite3.lib \
  1275   1275   		| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
  1276   1276   		| sort >> sqlite3.def
  1277   1277   
  1278   1278   sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) sqlite3.def
  1279   1279   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)

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.

   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    779     u32 *pnWord                     /* OUT: Number of 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   
................................................................................
  4930   4930           const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
  4931   4931           int nText = sqlite3_column_bytes(pStmt, iCol+1);
  4932   4932           sqlite3_tokenizer_cursor *pT = 0;
  4933   4933   
  4934   4934           rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
  4935   4935           while( rc==SQLITE_OK ){
  4936   4936             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 */
         4937  +          int nToken = 0;           /* Number of bytes in token */
         4938  +          int iDum1 = 0, iDum2 = 0; /* Dummy variables */
         4939  +          int iPos = 0;             /* Position of token in zText */
  4940   4940   
  4941   4941             rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
  4942   4942             if( rc==SQLITE_OK ){
  4943   4943               int i;
  4944   4944               cksum2 = cksum2 ^ fts3ChecksumEntry(
  4945   4945                   zToken, nToken, iLang, 0, iDocid, iCol, iPos
  4946   4946               );
................................................................................
  5099   5099       for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){
  5100   5100         const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
  5101   5101         sqlite3_tokenizer_cursor *pTC = 0;
  5102   5102     
  5103   5103         rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
  5104   5104         while( rc==SQLITE_OK ){
  5105   5105           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 */
         5106  +        int nToken = 0;           /* Number of bytes in token */
         5107  +        int iDum1 = 0, iDum2 = 0; /* Dummy variables */
         5108  +        int iPos = 0;             /* Position of token in zText */
  5109   5109     
  5110   5110           rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
  5111   5111           for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
  5112   5112             Fts3PhraseToken *pPT = pDef->pToken;
  5113   5113             if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
  5114   5114              && (pPT->bFirst==0 || iPos==0)
  5115   5115              && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))

Changes to main.mk.

   545    545   #
   546    546   TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
   547    547   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
   548    548   
   549    549   testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
   550    550   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   551    551   		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   552         -		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
          552  +		-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
   553    553   
   554    554   amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   555    555   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   556    556   		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                  \
   557    557   		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   558    558   
   559    559   fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
................................................................................
   618    618   	rm -f testloadext.dll libtestloadext.so
   619    619   	rm -f amalgamation-testfixture amalgamation-testfixture.exe
   620    620   	rm -f fts3-testfixture fts3-testfixture.exe
   621    621   	rm -f testfixture testfixture.exe
   622    622   	rm -f threadtest3 threadtest3.exe
   623    623   	rm -f sqlite3.c fts?amal.c tclsqlite3.c
   624    624   	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
   625         -	rm -f sqlite-output.vsix
          625  +	rm -f sqlite-*-output.vsix

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/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       }

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/main.c.

  3036   3036       ** operation N should be 0.  The idea is that a test program (like the
  3037   3037       ** SQL Logic Test or SLT test module) can run the same SQL multiple times
  3038   3038       ** with various optimizations disabled to verify that the same answer
  3039   3039       ** is obtained in every case.
  3040   3040       */
  3041   3041       case SQLITE_TESTCTRL_OPTIMIZATIONS: {
  3042   3042         sqlite3 *db = va_arg(ap, sqlite3*);
  3043         -      db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff);
         3043  +      db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
  3044   3044         break;
  3045   3045       }
  3046   3046   
  3047   3047   #ifdef SQLITE_N_KEYWORD
  3048   3048       /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
  3049   3049       **
  3050   3050       ** If zWord is a keyword recognized by the parser, then return the

Changes to src/os_unix.c.

   214    214     unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
   215    215     int lastErrno;                      /* The unix errno from last I/O error */
   216    216     void *lockingContext;               /* Locking style specific state */
   217    217     UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
   218    218     const char *zPath;                  /* Name of the file */
   219    219     unixShm *pShm;                      /* Shared memory segment information */
   220    220     int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
          221  +#ifdef __QNXNTO__
          222  +  int sectorSize;                     /* Device sector size */
          223  +  int deviceCharacteristics;          /* Precomputed device characteristics */
          224  +#endif
   221    225   #if SQLITE_ENABLE_LOCKING_STYLE
   222    226     int openFlags;                      /* The flags specified at open() */
   223    227   #endif
   224    228   #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
   225    229     unsigned fsFlags;                   /* cached details from statfs() */
   226    230   #endif
   227    231   #if OS_VXWORKS
................................................................................
  3634   3638   ** larger for some devices.
  3635   3639   **
  3636   3640   ** SQLite code assumes this function cannot fail. It also assumes that
  3637   3641   ** if two files are created in the same file-system directory (i.e.
  3638   3642   ** a database and its journal file) that the sector size will be the
  3639   3643   ** same for both.
  3640   3644   */
  3641         -static int unixSectorSize(sqlite3_file *pFile){
  3642         -  (void)pFile;
         3645  +#ifndef __QNXNTO__ 
         3646  +static int unixSectorSize(sqlite3_file *NotUsed){
         3647  +  UNUSED_PARAMETER(NotUsed);
  3643   3648     return SQLITE_DEFAULT_SECTOR_SIZE;
  3644   3649   }
         3650  +#endif
         3651  +
         3652  +/*
         3653  +** The following version of unixSectorSize() is optimized for QNX.
         3654  +*/
         3655  +#ifdef __QNXNTO__
         3656  +#include <sys/dcmd_blk.h>
         3657  +#include <sys/statvfs.h>
         3658  +static int unixSectorSize(sqlite3_file *id){
         3659  +  unixFile *pFile = (unixFile*)id;
         3660  +  if( pFile->sectorSize == 0 ){
         3661  +    struct statvfs fsInfo;
         3662  +       
         3663  +    /* Set defaults for non-supported filesystems */
         3664  +    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
         3665  +    pFile->deviceCharacteristics = 0;
         3666  +    if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
         3667  +      return pFile->sectorSize;
         3668  +    }
         3669  +
         3670  +    if( !strcmp(fsInfo.f_basetype, "tmp") ) {
         3671  +      pFile->sectorSize = fsInfo.f_bsize;
         3672  +      pFile->deviceCharacteristics =
         3673  +        SQLITE_IOCAP_ATOMIC4K |       /* All ram filesystem writes are atomic */
         3674  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3675  +                                      ** the write succeeds */
         3676  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3677  +                                      ** so it is ordered */
         3678  +        0;
         3679  +    }else if( strstr(fsInfo.f_basetype, "etfs") ){
         3680  +      pFile->sectorSize = fsInfo.f_bsize;
         3681  +      pFile->deviceCharacteristics =
         3682  +        /* etfs cluster size writes are atomic */
         3683  +        (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) |
         3684  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3685  +                                      ** the write succeeds */
         3686  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3687  +                                      ** so it is ordered */
         3688  +        0;
         3689  +    }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){
         3690  +      pFile->sectorSize = fsInfo.f_bsize;
         3691  +      pFile->deviceCharacteristics =
         3692  +        SQLITE_IOCAP_ATOMIC |         /* All filesystem writes are atomic */
         3693  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3694  +                                      ** the write succeeds */
         3695  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3696  +                                      ** so it is ordered */
         3697  +        0;
         3698  +    }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){
         3699  +      pFile->sectorSize = fsInfo.f_bsize;
         3700  +      pFile->deviceCharacteristics =
         3701  +        /* full bitset of atomics from max sector size and smaller */
         3702  +        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
         3703  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3704  +                                      ** so it is ordered */
         3705  +        0;
         3706  +    }else if( strstr(fsInfo.f_basetype, "dos") ){
         3707  +      pFile->sectorSize = fsInfo.f_bsize;
         3708  +      pFile->deviceCharacteristics =
         3709  +        /* full bitset of atomics from max sector size and smaller */
         3710  +        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
         3711  +        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
         3712  +                                      ** so it is ordered */
         3713  +        0;
         3714  +    }else{
         3715  +      pFile->deviceCharacteristics =
         3716  +        SQLITE_IOCAP_ATOMIC512 |      /* blocks are atomic */
         3717  +        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
         3718  +                                      ** the write succeeds */
         3719  +        0;
         3720  +    }
         3721  +  }
         3722  +  /* Last chance verification.  If the sector size isn't a multiple of 512
         3723  +  ** then it isn't valid.*/
         3724  +  if( pFile->sectorSize % 512 != 0 ){
         3725  +    pFile->deviceCharacteristics = 0;
         3726  +    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
         3727  +  }
         3728  +  return pFile->sectorSize;
         3729  +}
         3730  +#endif /* __QNXNTO__ */
  3645   3731   
  3646   3732   /*
  3647   3733   ** Return the device characteristics for the file.
  3648   3734   **
  3649   3735   ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
  3650   3736   ** However, that choice is contraversial since technically the underlying
  3651   3737   ** file system does not always provide powersafe overwrites.  (In other
................................................................................
  3654   3740   ** very rare.  And asserting PSOW makes a large reduction in the amount
  3655   3741   ** of required I/O for journaling, since a lot of padding is eliminated.
  3656   3742   **  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
  3657   3743   ** available to turn it off and URI query parameter available to turn it off.
  3658   3744   */
  3659   3745   static int unixDeviceCharacteristics(sqlite3_file *id){
  3660   3746     unixFile *p = (unixFile*)id;
         3747  +  int rc = 0;
         3748  +#ifdef __QNXNTO__
         3749  +  if( p->sectorSize==0 ) unixSectorSize(id);
         3750  +  rc = p->deviceCharacteristics;
         3751  +#endif
  3661   3752     if( p->ctrlFlags & UNIXFILE_PSOW ){
  3662         -    return SQLITE_IOCAP_POWERSAFE_OVERWRITE;
  3663         -  }else{
  3664         -    return 0;
         3753  +    rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
  3665   3754     }
         3755  +  return rc;
  3666   3756   }
  3667   3757   
  3668   3758   #ifndef SQLITE_OMIT_WAL
  3669   3759   
  3670   3760   
  3671   3761   /*
  3672   3762   ** Object used to represent an shared memory buffer.  

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);

Changes to src/pager.c.

  5881   5881     #else
  5882   5882         rc = pager_incr_changecounter(pPager, 0);
  5883   5883     #endif
  5884   5884         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  5885   5885     
  5886   5886         /* If this transaction has made the database smaller, then all pages
  5887   5887         ** being discarded by the truncation must be written to the journal
  5888         -      ** file. This can only happen in auto-vacuum mode.
         5888  +      ** file.
  5889   5889         **
  5890   5890         ** Before reading the pages with page numbers larger than the 
  5891   5891         ** current value of Pager.dbSize, set dbSize back to the value
  5892   5892         ** that it took at the start of the transaction. Otherwise, the
  5893   5893         ** calls to sqlite3PagerGet() return zeroed pages instead of 
  5894   5894         ** reading data from the database file.
  5895   5895         */
  5896         -  #ifndef SQLITE_OMIT_AUTOVACUUM
  5897   5896         if( pPager->dbSize<pPager->dbOrigSize 
  5898   5897          && pPager->journalMode!=PAGER_JOURNALMODE_OFF
  5899   5898         ){
  5900   5899           Pgno i;                                   /* Iterator variable */
  5901   5900           const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
  5902   5901           const Pgno dbSize = pPager->dbSize;       /* Database image size */ 
  5903   5902           pPager->dbSize = pPager->dbOrigSize;
................................................................................
  5909   5908               rc = sqlite3PagerWrite(pPage);
  5910   5909               sqlite3PagerUnref(pPage);
  5911   5910               if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  5912   5911             }
  5913   5912           }
  5914   5913           pPager->dbSize = dbSize;
  5915   5914         } 
  5916         -  #endif
  5917   5915     
  5918   5916         /* Write the master journal name into the journal file. If a master 
  5919   5917         ** journal file name has already been written to the journal file, 
  5920   5918         ** or if zMaster is NULL (no master journal), then this call is a no-op.
  5921   5919         */
  5922   5920         rc = writeMasterJournal(pPager, zMaster);
  5923   5921         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;

Changes to src/select.c.

  3094   3094       **
  3095   3095       ** We look at every expression in the outer query and every place we see
  3096   3096       ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
  3097   3097       */
  3098   3098       pList = pParent->pEList;
  3099   3099       for(i=0; i<pList->nExpr; i++){
  3100   3100         if( pList->a[i].zName==0 ){
  3101         -        const char *zSpan = pList->a[i].zSpan;
  3102         -        if( ALWAYS(zSpan) ){
  3103         -          pList->a[i].zName = sqlite3DbStrDup(db, zSpan);
  3104         -        }
         3101  +        char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
         3102  +        sqlite3Dequote(zName);
         3103  +        pList->a[i].zName = zName;
  3105   3104         }
  3106   3105       }
  3107   3106       substExprList(db, pParent->pEList, iParent, pSub->pEList);
  3108   3107       if( isAgg ){
  3109   3108         substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
  3110   3109         pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
  3111   3110       }
................................................................................
  3906   3905     for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
  3907   3906       struct SrcList_item *pItem = &pTabList->a[i];
  3908   3907       SelectDest dest;
  3909   3908       Select *pSub = pItem->pSelect;
  3910   3909       int isAggSub;
  3911   3910   
  3912   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. */
  3913   3919       if( pItem->addrFillSub ){
  3914         -      sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
         3920  +      if( pItem->viaCoroutine==0 ){
         3921  +        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
         3922  +      }
  3915   3923         continue;
  3916   3924       }
  3917   3925   
  3918   3926       /* Increment Parse.nHeight by the height of the largest expression
  3919   3927       ** tree refered to by this, the parent select. The child select
  3920   3928       ** may contain expression trees of at most
  3921   3929       ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
................................................................................
  3928   3936       if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
  3929   3937         /* This subquery can be absorbed into its parent. */
  3930   3938         if( isAggSub ){
  3931   3939           isAgg = 1;
  3932   3940           p->selFlags |= SF_Aggregate;
  3933   3941         }
  3934   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  +      sqlite3VdbeAddOp0(v, OP_Goto);
         3954  +      addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
         3955  +      sqlite3VdbeChangeP5(v, 1);
         3956  +      VdbeComment((v, "coroutine for %s", pItem->pTab->zName));
         3957  +      pItem->addrFillSub = addrTop;
         3958  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof);
         3959  +      sqlite3VdbeChangeP5(v, 1);
         3960  +      sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
         3961  +      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
         3962  +      sqlite3Select(pParse, pSub, &dest);
         3963  +      pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
         3964  +      pItem->viaCoroutine = 1;
         3965  +      sqlite3VdbeChangeP2(v, addrTop, dest.iSdst);
         3966  +      sqlite3VdbeChangeP3(v, addrTop, dest.nSdst);
         3967  +      sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof);
         3968  +      sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn);
         3969  +      VdbeComment((v, "end %s", pItem->pTab->zName));
         3970  +      sqlite3VdbeJumpHere(v, addrTop-1);
         3971  +      sqlite3ClearTempRegCache(pParse);
  3935   3972       }else{
  3936   3973         /* Generate a subroutine that will fill an ephemeral table with
  3937   3974         ** the content of this subquery.  pItem->addrFillSub will point
  3938   3975         ** to the address of the generated subroutine.  pItem->regReturn
  3939   3976         ** is a register allocated to hold the subroutine return address
  3940   3977         */
  3941   3978         int topAddr;

Changes to src/shell.c.

  2820   2820   /*
  2821   2821   ** Show available command line options
  2822   2822   */
  2823   2823   static const char zOptions[] = 
  2824   2824     "   -bail                stop after hitting an error\n"
  2825   2825     "   -batch               force batch I/O\n"
  2826   2826     "   -column              set output mode to 'column'\n"
  2827         -  "   -cmd command         run \"command\" before reading stdin\n"
         2827  +  "   -cmd COMMAND         run \"COMMAND\" before reading stdin\n"
  2828   2828     "   -csv                 set output mode to 'csv'\n"
  2829   2829     "   -echo                print commands before execution\n"
  2830         -  "   -init filename       read/process named file\n"
         2830  +  "   -init FILENAME       read/process named file\n"
  2831   2831     "   -[no]header          turn headers on or off\n"
         2832  +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
         2833  +  "   -heap SIZE           Size of heap for memsys3 or memsys5\n"
         2834  +#endif
  2832   2835     "   -help                show this message\n"
  2833   2836     "   -html                set output mode to HTML\n"
  2834   2837     "   -interactive         force interactive I/O\n"
  2835   2838     "   -line                set output mode to 'line'\n"
  2836   2839     "   -list                set output mode to 'list'\n"
  2837   2840   #ifdef SQLITE_ENABLE_MULTIPLEX
  2838   2841     "   -multiplex           enable the multiplexor VFS\n"
  2839   2842   #endif
  2840         -  "   -nullvalue 'text'    set text string for NULL values\n"
  2841         -  "   -separator 'x'       set output field separator (|)\n"
         2843  +  "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
         2844  +  "   -separator SEP       set output field separator. Default: '|'\n"
  2842   2845     "   -stats               print memory stats before each finalize\n"
  2843   2846     "   -version             show SQLite version\n"
  2844   2847     "   -vfs NAME            use NAME as the default VFS\n"
  2845   2848   #ifdef SQLITE_ENABLE_VFSTRACE
  2846   2849     "   -vfstrace            enable tracing of all VFS calls\n"
  2847   2850   #endif
  2848   2851   ;
................................................................................
  2869   2872     data->showHeader = 0;
  2870   2873     sqlite3_config(SQLITE_CONFIG_URI, 1);
  2871   2874     sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
  2872   2875     sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
  2873   2876     sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
  2874   2877     sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
  2875   2878   }
         2879  +
         2880  +/*
         2881  +** Get the argument to an --option.  Throw an error and die if no argument
         2882  +** is available.
         2883  +*/
         2884  +static char *cmdline_option_value(int argc, char **argv, int i){
         2885  +  if( i==argc ){
         2886  +    fprintf(stderr, "%s: Error: missing argument to %s\n",
         2887  +            argv[0], argv[argc-1]);
         2888  +    exit(1);
         2889  +  }
         2890  +  return argv[i];
         2891  +}
  2876   2892   
  2877   2893   int main(int argc, char **argv){
  2878   2894     char *zErrMsg = 0;
  2879   2895     struct callback_data data;
  2880   2896     const char *zInitFile = 0;
  2881   2897     char *zFirstCmd = 0;
  2882   2898     int i;
................................................................................
  2899   2915   #endif
  2900   2916   
  2901   2917     /* Do an initial pass through the command-line argument to locate
  2902   2918     ** the name of the database file, the name of the initialization file,
  2903   2919     ** the size of the alternative malloc heap,
  2904   2920     ** and the first command to execute.
  2905   2921     */
  2906         -  for(i=1; i<argc-1; i++){
         2922  +  for(i=1; i<argc; i++){
  2907   2923       char *z;
  2908         -    if( argv[i][0]!='-' ) break;
  2909   2924       z = argv[i];
         2925  +    if( z[0]!='-' ){
         2926  +      if( data.zDbFilename==0 ){
         2927  +        data.zDbFilename = z;
         2928  +        continue;
         2929  +      }
         2930  +      if( zFirstCmd==0 ){
         2931  +        zFirstCmd = z;
         2932  +        continue;
         2933  +      }
         2934  +      fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
         2935  +      fprintf(stderr,"Use -help for a list of options.\n");
         2936  +      return 1;
         2937  +    }
  2910   2938       if( z[1]=='-' ) z++;
  2911   2939       if( strcmp(z,"-separator")==0
  2912   2940        || strcmp(z,"-nullvalue")==0
  2913   2941        || strcmp(z,"-cmd")==0
  2914   2942       ){
  2915         -      i++;
         2943  +      (void)cmdline_option_value(argc, argv, ++i);
  2916   2944       }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         -    */
         2945  +      zInitFile = cmdline_option_value(argc, argv, ++i);
  2923   2946       }else if( strcmp(z,"-batch")==0 ){
         2947  +      /* Need to check for batch mode here to so we can avoid printing
         2948  +      ** informational messages (like from process_sqliterc) before 
         2949  +      ** we do the actual processing of arguments later in a second pass.
         2950  +      */
  2924   2951         stdin_is_interactive = 0;
  2925   2952       }else if( strcmp(z,"-heap")==0 ){
  2926   2953   #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  2927   2954         int j, c;
  2928   2955         const char *zSize;
  2929   2956         sqlite3_int64 szHeap;
  2930   2957   
  2931         -      zSize = argv[++i];
         2958  +      zSize = cmdline_option_value(argc, argv, ++i);
  2932   2959         szHeap = atoi(zSize);
  2933   2960         for(j=0; (c = zSize[j])!=0; j++){
  2934   2961           if( c=='M' ){ szHeap *= 1000000; break; }
  2935   2962           if( c=='K' ){ szHeap *= 1000; break; }
  2936   2963           if( c=='G' ){ szHeap *= 1000000000; break; }
  2937   2964         }
  2938   2965         if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
................................................................................
  2951   2978   #endif
  2952   2979   #ifdef SQLITE_ENABLE_MULTIPLEX
  2953   2980       }else if( strcmp(z,"-multiplex")==0 ){
  2954   2981         extern int sqlite3_multiple_initialize(const char*,int);
  2955   2982         sqlite3_multiplex_initialize(0, 1);
  2956   2983   #endif
  2957   2984       }else if( strcmp(z,"-vfs")==0 ){
  2958         -      sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
         2985  +      sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
  2959   2986         if( pVfs ){
  2960   2987           sqlite3_vfs_register(pVfs, 1);
  2961   2988         }else{
  2962   2989           fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
  2963   2990           exit(1);
  2964   2991         }
  2965   2992       }
  2966   2993     }
  2967         -  if( i<argc ){
  2968         -    data.zDbFilename = argv[i++];
  2969         -  }else{
         2994  +  if( data.zDbFilename==0 ){
  2970   2995   #ifndef SQLITE_OMIT_MEMORYDB
  2971   2996       data.zDbFilename = ":memory:";
  2972   2997   #else
  2973         -    data.zDbFilename = 0;
         2998  +    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
         2999  +    return 1;
  2974   3000   #endif
  2975   3001     }
  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   3002     data.out = stdout;
  2985   3003   
  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   3004     /* Go ahead and open the database file if it already exists.  If the
  2994   3005     ** file does not exist, delay opening it.  This prevents empty database
  2995   3006     ** files from being created if a user mistypes the database name argument
  2996   3007     ** to the sqlite command-line tool.
  2997   3008     */
  2998   3009     if( access(data.zDbFilename, 0)==0 ){
  2999   3010       open_db(&data);
................................................................................
  3009   3020     }
  3010   3021   
  3011   3022     /* Make a second pass through the command-line argument and set
  3012   3023     ** options.  This second pass is delayed until after the initialization
  3013   3024     ** file is processed so that the command-line arguments will override
  3014   3025     ** settings in the initialization file.
  3015   3026     */
  3016         -  for(i=1; i<argc && argv[i][0]=='-'; i++){
         3027  +  for(i=1; i<argc; i++){
  3017   3028       char *z = argv[i];
         3029  +    if( z[0]!='-' ) continue;
  3018   3030       if( z[1]=='-' ){ z++; }
  3019   3031       if( strcmp(z,"-init")==0 ){
  3020   3032         i++;
  3021   3033       }else if( strcmp(z,"-html")==0 ){
  3022   3034         data.mode = MODE_Html;
  3023   3035       }else if( strcmp(z,"-list")==0 ){
  3024   3036         data.mode = MODE_List;
................................................................................
  3026   3038         data.mode = MODE_Line;
  3027   3039       }else if( strcmp(z,"-column")==0 ){
  3028   3040         data.mode = MODE_Column;
  3029   3041       }else if( strcmp(z,"-csv")==0 ){
  3030   3042         data.mode = MODE_Csv;
  3031   3043         memcpy(data.separator,",",2);
  3032   3044       }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   3045         sqlite3_snprintf(sizeof(data.separator), data.separator,
  3041         -                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);
         3046  +                       "%s",cmdline_option_value(argc,argv,++i));
  3042   3047       }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   3048         sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
  3051         -                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
         3049  +                       "%s",cmdline_option_value(argc,argv,++i));
  3052   3050       }else if( strcmp(z,"-header")==0 ){
  3053   3051         data.showHeader = 1;
  3054   3052       }else if( strcmp(z,"-noheader")==0 ){
  3055   3053         data.showHeader = 0;
  3056   3054       }else if( strcmp(z,"-echo")==0 ){
  3057   3055         data.echoOn = 1;
  3058   3056       }else if( strcmp(z,"-stats")==0 ){
................................................................................
  3078   3076       }else if( strcmp(z,"-multiplex")==0 ){
  3079   3077         i++;
  3080   3078   #endif
  3081   3079       }else if( strcmp(z,"-help")==0 ){
  3082   3080         usage(1);
  3083   3081       }else if( strcmp(z,"-cmd")==0 ){
  3084   3082         if( i==argc-1 ) break;
  3085         -      i++;
  3086         -      z = argv[i];
         3083  +      z = cmdline_option_value(argc,argv,++i);
  3087   3084         if( z[0]=='.' ){
  3088   3085           rc = do_meta_command(z, &data);
  3089   3086           if( rc && bail_on_error ) return rc;
  3090   3087         }else{
  3091   3088           open_db(&data);
  3092   3089           rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
  3093   3090           if( zErrMsg!=0 ){

Changes to src/sqliteInt.h.

   824    824     Db *aDb;                      /* All backends */
   825    825     int nDb;                      /* Number of backends currently in use */
   826    826     int flags;                    /* Miscellaneous flags. See below */
   827    827     i64 lastRowid;                /* ROWID of most recent insert (see above) */
   828    828     unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
   829    829     int errCode;                  /* Most recent error code (SQLITE_*) */
   830    830     int errMask;                  /* & result codes with this before returning */
   831         -  u8 dbOptFlags;                /* Flags to enable/disable optimizations */
          831  +  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
   832    832     u8 autoCommit;                /* The auto-commit flag. */
   833    833     u8 temp_store;                /* 1: file 2: memory 0: default */
   834    834     u8 mallocFailed;              /* True if we have seen a malloc failure */
   835    835     u8 dfltLockMode;              /* Default locking-mode for attached dbs */
   836    836     signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
   837    837     u8 suppressErr;               /* Do not issue error messages if true */
   838    838     u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
................................................................................
   976    976   #define SQLITE_ColumnCache    0x0002   /* Column cache */
   977    977   #define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
   978    978   #define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
   979    979   #define SQLITE_IdxRealAsInt   0x0010   /* Store REAL as INT in indices */
   980    980   #define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
   981    981   #define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
   982    982   #define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
   983         -#define SQLITE_AllOpts        0x00ff   /* All optimizations */
          983  +#define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
          984  +#define SQLITE_AllOpts        0xffff   /* All optimizations */
   984    985   
   985    986   /*
   986    987   ** Macros for testing whether or not optimizations are enabled or disabled.
   987    988   */
   988    989   #ifndef SQLITE_OMIT_BUILTIN_TEST
   989    990   #define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
   990    991   #define OptimizationEnabled(db, mask)   (((db)->dbOptFlags&(mask))==0)
................................................................................
  1882   1883       char *zName;      /* Name of the table */
  1883   1884       char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
  1884   1885       Table *pTab;      /* An SQL table corresponding to zName */
  1885   1886       Select *pSelect;  /* A SELECT statement used in place of a table name */
  1886   1887       int addrFillSub;  /* Address of subroutine to manifest a subquery */
  1887   1888       int regReturn;    /* Register holding return address of addrFillSub */
  1888   1889       u8 jointype;      /* Type of join between this able and the previous */
  1889         -    u8 notIndexed;    /* True if there is a NOT INDEXED clause */
  1890         -    u8 isCorrelated;  /* True if sub-query is correlated */
         1890  +    unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
         1891  +    unsigned isCorrelated :1;  /* True if sub-query is correlated */
         1892  +    unsigned viaCoroutine :1;  /* Implemented as a co-routine */
  1891   1893   #ifndef SQLITE_OMIT_EXPLAIN
  1892   1894       u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
  1893   1895   #endif
  1894   1896       int iCursor;      /* The VDBE cursor number used to access this table */
  1895   1897       Expr *pOn;        /* The ON clause of a join */
  1896   1898       IdList *pUsing;   /* The USING clause of a join */
  1897   1899       Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
................................................................................
  2107   2109     Expr *pOffset;         /* OFFSET expression. NULL means not used. */
  2108   2110   };
  2109   2111   
  2110   2112   /*
  2111   2113   ** Allowed values for Select.selFlags.  The "SF" prefix stands for
  2112   2114   ** "Select Flag".
  2113   2115   */
  2114         -#define SF_Distinct        0x01  /* Output should be DISTINCT */
  2115         -#define SF_Resolved        0x02  /* Identifiers have been resolved */
  2116         -#define SF_Aggregate       0x04  /* Contains aggregate functions */
  2117         -#define SF_UsesEphemeral   0x08  /* Uses the OpenEphemeral opcode */
  2118         -#define SF_Expanded        0x10  /* sqlite3SelectExpand() called on this */
  2119         -#define SF_HasTypeInfo     0x20  /* FROM subqueries have Table metadata */
  2120         -#define SF_UseSorter       0x40  /* Sort using a sorter */
  2121         -#define SF_Values          0x80  /* Synthesized from VALUES clause */
         2116  +#define SF_Distinct        0x0001  /* Output should be DISTINCT */
         2117  +#define SF_Resolved        0x0002  /* Identifiers have been resolved */
         2118  +#define SF_Aggregate       0x0004  /* Contains aggregate functions */
         2119  +#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
         2120  +#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
         2121  +#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
         2122  +#define SF_UseSorter       0x0040  /* Sort using a sorter */
         2123  +#define SF_Values          0x0080  /* Synthesized from VALUES clause */
         2124  +#define SF_Materialize     0x0100  /* Force materialization of views */
  2122   2125   
  2123   2126   
  2124   2127   /*
  2125   2128   ** The results of a select can be distributed in several ways.  The
  2126   2129   ** "SRT" prefix means "SELECT Result Type".
  2127   2130   */
  2128   2131   #define SRT_Union        1  /* Store result as keys in an index */

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    212         }
   213    213         db->pnBytesFreed = 0;
   214    214   
   215    215         *pHighwater = 0;
   216    216         *pCurrent = nByte;
   217    217   
   218    218         break;

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_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/vacuum.c.

    81     81   ** with 2.0.0, SQLite no longer uses GDBM so this command has
    82     82   ** become a no-op.
    83     83   */
    84     84   void sqlite3Vacuum(Parse *pParse){
    85     85     Vdbe *v = sqlite3GetVdbe(pParse);
    86     86     if( v ){
    87     87       sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
           88  +    sqlite3VdbeUsesBtree(v, 0);
    88     89     }
    89     90     return;
    90     91   }
    91     92   
    92     93   /*
    93     94   ** This routine implements the OP_Vacuum opcode of the VDBE.
    94     95   */

Changes to src/vdbe.c.

  2243   2243       }else{
  2244   2244         assert( sqlite3BtreeCursorIsValid(pCrsr) );
  2245   2245         VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &payloadSize);
  2246   2246         assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
  2247   2247       }
  2248   2248     }else if( ALWAYS(pC->pseudoTableReg>0) ){
  2249   2249       pReg = &aMem[pC->pseudoTableReg];
         2250  +    if( pC->multiPseudo ){
         2251  +      sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem);
         2252  +      Deephemeralize(pDest);
         2253  +      goto op_column_out;
         2254  +    }
  2250   2255       assert( pReg->flags & MEM_Blob );
  2251   2256       assert( memIsValid(pReg) );
  2252   2257       payloadSize = pReg->n;
  2253   2258       zRec = pReg->z;
  2254   2259       pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
  2255   2260       assert( payloadSize==0 || zRec!=0 );
  2256   2261     }else{
................................................................................
  3324   3329   #else
  3325   3330     pOp->opcode = OP_OpenEphemeral;
  3326   3331     pc--;
  3327   3332   #endif
  3328   3333     break;
  3329   3334   }
  3330   3335   
  3331         -/* Opcode: OpenPseudo P1 P2 P3 * *
         3336  +/* Opcode: OpenPseudo P1 P2 P3 * P5
  3332   3337   **
  3333   3338   ** Open a new cursor that points to a fake table that contains a single
  3334   3339   ** row of data.  The content of that one row in the content of memory
  3335         -** register P2.  In other words, cursor P1 becomes an alias for the 
  3336         -** MEM_Blob content contained in register P2.
         3340  +** register P2 when P5==0.  In other words, cursor P1 becomes an alias for the 
         3341  +** MEM_Blob content contained in register P2.  When P5==1, then the
         3342  +** row is represented by P3 consecutive registers beginning with P2.
  3337   3343   **
  3338   3344   ** A pseudo-table created by this opcode is used to hold a single
  3339   3345   ** row output from the sorter so that the row can be decomposed into
  3340   3346   ** individual columns using the OP_Column opcode.  The OP_Column opcode
  3341   3347   ** is the only cursor opcode that works with a pseudo-table.
  3342   3348   **
  3343   3349   ** P3 is the number of fields in the records that will be stored by
................................................................................
  3349   3355     assert( pOp->p1>=0 );
  3350   3356     pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
  3351   3357     if( pCx==0 ) goto no_mem;
  3352   3358     pCx->nullRow = 1;
  3353   3359     pCx->pseudoTableReg = pOp->p2;
  3354   3360     pCx->isTable = 1;
  3355   3361     pCx->isIndex = 0;
         3362  +  pCx->multiPseudo = pOp->p5;
  3356   3363     break;
  3357   3364   }
  3358   3365   
  3359   3366   /* Opcode: Close P1 * * * *
  3360   3367   **
  3361   3368   ** Close a cursor previously opened as P1.  If P1 is not
  3362   3369   ** currently open, this instruction is a no-op.
................................................................................
  4355   4362     i64 v;
  4356   4363     sqlite3_vtab *pVtab;
  4357   4364     const sqlite3_module *pModule;
  4358   4365   
  4359   4366     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4360   4367     pC = p->apCsr[pOp->p1];
  4361   4368     assert( pC!=0 );
  4362         -  assert( pC->pseudoTableReg==0 );
         4369  +  assert( pC->pseudoTableReg==0 || pC->nullRow );
  4363   4370     if( pC->nullRow ){
  4364   4371       pOut->flags = MEM_Null;
  4365   4372       break;
  4366   4373     }else if( pC->deferredMoveto ){
  4367   4374       v = pC->movetoTarget;
  4368   4375   #ifndef SQLITE_OMIT_VIRTUALTABLE
  4369   4376     }else if( pC->pVtabCursor ){

Changes to src/vdbe.h.

   186    186   void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
   187    187   void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
   188    188   void sqlite3VdbeUsesBtree(Vdbe*, int);
   189    189   VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
   190    190   int sqlite3VdbeMakeLabel(Vdbe*);
   191    191   void sqlite3VdbeRunOnlyOnce(Vdbe*);
   192    192   void sqlite3VdbeDelete(Vdbe*);
   193         -void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*);
          193  +void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
   194    194   void sqlite3VdbeMakeReady(Vdbe*,Parse*);
   195    195   int sqlite3VdbeFinalize(Vdbe*);
   196    196   void sqlite3VdbeResolveLabel(Vdbe*, int);
   197    197   int sqlite3VdbeCurrentAddr(Vdbe*);
   198    198   #ifdef SQLITE_DEBUG
   199    199     int sqlite3VdbeAssertMayAbort(Vdbe *, int);
   200    200     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.

  2431   2431         }
  2432   2432         pAux->pAux = 0;
  2433   2433       }
  2434   2434     }
  2435   2435   }
  2436   2436   
  2437   2437   /*
  2438         -** Free all memory associated with the Vdbe passed as the second argument.
         2438  +** Free all memory associated with the Vdbe passed as the second argument,
         2439  +** except for object itself, which is preserved.
         2440  +**
  2439   2441   ** The difference between this function and sqlite3VdbeDelete() is that
  2440   2442   ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
  2441         -** the database connection.
         2443  +** the database connection and frees the object itself.
  2442   2444   */
  2443         -void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
         2445  +void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
  2444   2446     SubProgram *pSub, *pNext;
  2445   2447     int i;
  2446   2448     assert( p->db==0 || p->db==db );
  2447   2449     releaseMemArray(p->aVar, p->nVar);
  2448   2450     releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  2449   2451     for(pSub=p->pProgram; pSub; pSub=pNext){
  2450   2452       pNext = pSub->pNext;
................................................................................
  2457   2459     sqlite3DbFree(db, p->aColName);
  2458   2460     sqlite3DbFree(db, p->zSql);
  2459   2461     sqlite3DbFree(db, p->pFree);
  2460   2462   #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
  2461   2463     sqlite3DbFree(db, p->zExplain);
  2462   2464     sqlite3DbFree(db, p->pExplain);
  2463   2465   #endif
  2464         -  sqlite3DbFree(db, p);
  2465   2466   }
  2466   2467   
  2467   2468   /*
  2468   2469   ** Delete an entire VDBE.
  2469   2470   */
  2470   2471   void sqlite3VdbeDelete(Vdbe *p){
  2471   2472     sqlite3 *db;
  2472   2473   
  2473   2474     if( NEVER(p==0) ) return;
  2474   2475     db = p->db;
  2475   2476     assert( sqlite3_mutex_held(db->mutex) );
         2477  +  sqlite3VdbeClearObject(db, p);
  2476   2478     if( p->pPrev ){
  2477   2479       p->pPrev->pNext = p->pNext;
  2478   2480     }else{
  2479   2481       assert( db->pVdbe==p );
  2480   2482       db->pVdbe = p->pNext;
  2481   2483     }
  2482   2484     if( p->pNext ){
  2483   2485       p->pNext->pPrev = p->pPrev;
  2484   2486     }
  2485   2487     p->magic = VDBE_MAGIC_DEAD;
  2486   2488     p->db = 0;
  2487         -  sqlite3VdbeDeleteObject(db, p);
         2489  +  sqlite3DbFree(db, p);
  2488   2490   }
  2489   2491   
  2490   2492   /*
  2491   2493   ** Make sure the cursor p is ready to read or write the row to which it
  2492   2494   ** was last positioned.  Return an error code if an OOM fault or I/O error
  2493   2495   ** prevents us from positioning the cursor to its correct position.
  2494   2496   **

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 */

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/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   

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/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   

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 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 four
   358         -#       parallel lists that contain the source file names, destination file
   359         -#       names, the platform-neutral flags, and the use-subst flags.  When the
   360         -#       platform-neutral flag is non-zero, the file is not platform-specific.
   361         -#       When the use-subst flag is non-zero, the file is considered to be a
   362         -#       text file that may contain Tcl variable and/or command replacements,
   363         -#       to be dynamically replaced during processing.  If the source file name
   364         -#       is an empty string, then the destination file name will be assumed to
   365         -#       already exist in the staging directory and will not be copied; however,
   366         -#       dynamic replacements may still be performed on the destination file
   367         -#       prior to the package being re-zipped.
   368         -#
   369         -foreach sourceFileName $fileNames(source) \
   370         -    destinationFileName $fileNames(destination) \
   371         -    buildNeutral $fileNames(buildNeutral) platformNeutral \
   372         -    $fileNames(platformNeutral) useSubst $fileNames(subst) \
   373         -    noDebug $fileNames(noDebug) noRetail $fileNames(noRetail) {
          494  +# NOTE: Process each file in the master file list.  There are actually three
          495  +#       parallel lists that contain the source file names, the destination file
          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.
          515  +#
          516  +foreach sourceFileName      $fileNames(source) \
          517  +        destinationFileName $fileNames(destination) \
          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  +
   374    528     #
   375    529     # NOTE: If the current file is build-neutral, then only one build will
   376    530     #       be processed for it, namely "CommonConfiguration"; otherwise, each
   377    531     #       supported build will be processed for it individually.
   378    532     #
   379    533     foreach buildName \
   380         -      [expr {$buildNeutral ? [list CommonConfiguration] : $buildNames}] {
          534  +      [expr {$isBuildNeutral ? [list CommonConfiguration] : $buildNames}] {
   381    535       #
   382    536       # NOTE: Should the current file be skipped for this build?
   383    537       #
   384         -    if {[info exists no${buildName}] && [set no${buildName}]} then {
          538  +    if {[lsearch $fileFlags no${buildName}] != -1} then {
   385    539         continue
   386    540       }
   387    541   
   388    542       #
   389    543       # NOTE: If the current file is platform-neutral, then only one platform
   390    544       #       will be processed for it, namely "neutral"; otherwise, each
   391    545       #       supported platform will be processed for it individually.
   392    546       #
   393    547       foreach platformName \
   394         -        [expr {$platformNeutral ? [list neutral] : $platformNames}] {
          548  +        [expr {$isPlatformNeutral ? [list neutral] : $platformNames}] {
   395    549         #
   396    550         # NOTE: Use the actual platform name in the destination file name.
   397    551         #
   398         -      set newDestinationFileName [replaceBuildAndPlatform \
   399         -          $destinationFileName $buildName $platformName]
          552  +      set newDestinationFileName [replaceFileNameTokens $destinationFileName \
          553  +          $shortName $buildName $platformName]
   400    554   
   401    555         #
   402    556         # NOTE: Does the source file need to be copied to the destination file?
   403    557         #
   404    558         if {[string length $sourceFileName] > 0} then {
   405    559           #
   406    560           # NOTE: First, make sure the destination directory exists.
   407    561           #
   408    562           file mkdir [file dirname $newDestinationFileName]
   409    563   
   410    564           #
   411    565           # NOTE: Then, copy the source file to the destination file verbatim.
   412    566           #
   413         -        file copy [replaceBuildAndPlatform $sourceFileName $buildName \
   414         -            $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  +        }
   415    579         }
   416    580   
   417    581         #
   418    582         # NOTE: Does the destination file contain dynamic replacements that must
   419    583         #       be processed now?
   420    584         #
   421    585         if {$useSubst} then {
................................................................................
   435    599   # NOTE: Change the current directory to the staging directory so that the
   436    600   #       external archive building tool can pickup the necessary files using
   437    601   #       relative paths.
   438    602   #
   439    603   cd $stagingDirectory
   440    604   
   441    605   #
   442         -# 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
   443    607   #       output directory.
   444    608   #
   445    609   set archiveCommand [list exec -- $zip -r $outputFile *]
   446    610   
   447    611   #
   448         -# NOTE: Build the final package archive in the output directory.
          612  +# NOTE: Build the final VSIX package archive in the output directory.
   449    613   #
   450    614   eval $archiveCommand
   451    615   
   452    616   #
   453    617   # NOTE: Change back to the previously saved current directory.
   454    618   #
   455    619   cd $currentDirectory

Changes to tool/win/sqlite.vsix.

cannot compute difference between binary files