diff --git a/Makefile.in b/Makefile.in index f374aa451c..f078cb68b4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -944,7 +944,7 @@ clean: rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def rm -f sqlite3.c rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c - rm -f sqlite-output.vsix + rm -f sqlite-*-output.vsix distclean: clean rm -f config.log config.status libtool Makefile sqlite3.pc diff --git a/Makefile.msc b/Makefile.msc index 2c4d13b9f8..3df86de05e 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1263,7 +1263,7 @@ clean: del /Q sqlite3.c del /Q sqlite3rc.h del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c - del /Q sqlite-output.vsix + del /Q sqlite-*-output.vsix # Dynamic link library section. # diff --git a/ext/fts2/fts2_icu.c b/ext/fts2/fts2_icu.c index de8e116bb9..2670301f51 100644 --- a/ext/fts2/fts2_icu.c +++ b/ext/fts2/fts2_icu.c @@ -118,7 +118,7 @@ static int icuOpen( nChar = nInput+1; pCsr = (IcuCursor *)sqlite3_malloc( sizeof(IcuCursor) + /* IcuCursor */ - nChar * sizeof(UChar) + /* IcuCursor.aChar[] */ + ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ ); if( !pCsr ){ @@ -126,7 +126,7 @@ static int icuOpen( } memset(pCsr, 0, sizeof(IcuCursor)); pCsr->aChar = (UChar *)&pCsr[1]; - pCsr->aOffset = (int *)&pCsr->aChar[nChar]; + pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3]; pCsr->aOffset[iOut] = iInput; U8_NEXT(zInput, iInput, nInput, c); diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 58414f65db..7a53ac37a3 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -4743,35 +4743,39 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ nTmp += p->pRight->pPhrase->doclist.nList; } nTmp += p->pPhrase->doclist.nList; - aTmp = sqlite3_malloc(nTmp*2); - if( !aTmp ){ - *pRc = SQLITE_NOMEM; + if( nTmp==0 ){ res = 0; }else{ - char *aPoslist = p->pPhrase->doclist.pList; - int nToken = p->pPhrase->nToken; + aTmp = sqlite3_malloc(nTmp*2); + if( !aTmp ){ + *pRc = SQLITE_NOMEM; + res = 0; + }else{ + char *aPoslist = p->pPhrase->doclist.pList; + int nToken = p->pPhrase->nToken; - for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ - Fts3Phrase *pPhrase = p->pRight->pPhrase; - int nNear = p->nNear; - res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); - } - - aPoslist = pExpr->pRight->pPhrase->doclist.pList; - nToken = pExpr->pRight->pPhrase->nToken; - for(p=pExpr->pLeft; p && res; p=p->pLeft){ - int nNear; - Fts3Phrase *pPhrase; - assert( p->pParent && p->pParent->pLeft==p ); - nNear = p->pParent->nNear; - pPhrase = ( - p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase - ); - res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ + Fts3Phrase *pPhrase = p->pRight->pPhrase; + int nNear = p->nNear; + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + + aPoslist = pExpr->pRight->pPhrase->doclist.pList; + nToken = pExpr->pRight->pPhrase->nToken; + for(p=pExpr->pLeft; p && res; p=p->pLeft){ + int nNear; + Fts3Phrase *pPhrase; + assert( p->pParent && p->pParent->pLeft==p ); + nNear = p->pParent->nNear; + pPhrase = ( + p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase + ); + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } } + + sqlite3_free(aTmp); } - - sqlite3_free(aTmp); } return res; diff --git a/ext/fts3/fts3_expr.c b/ext/fts3/fts3_expr.c index a6e3492242..7612789de5 100644 --- a/ext/fts3/fts3_expr.c +++ b/ext/fts3/fts3_expr.c @@ -185,7 +185,7 @@ static int getNextToken( rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); if( rc==SQLITE_OK ){ const char *zToken; - int nToken, iStart, iEnd, iPosition; + int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; int nByte; /* total space to allocate */ rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); @@ -300,7 +300,7 @@ static int getNextString( int ii; for(ii=0; rc==SQLITE_OK; ii++){ const char *zByte; - int nByte, iBegin, iEnd, iPos; + int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0; rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); if( rc==SQLITE_OK ){ Fts3PhraseToken *pToken; diff --git a/ext/fts3/fts3_icu.c b/ext/fts3/fts3_icu.c index 18b7948c32..52df8c7d81 100644 --- a/ext/fts3/fts3_icu.c +++ b/ext/fts3/fts3_icu.c @@ -119,7 +119,7 @@ static int icuOpen( nChar = nInput+1; pCsr = (IcuCursor *)sqlite3_malloc( sizeof(IcuCursor) + /* IcuCursor */ - nChar * sizeof(UChar) + /* IcuCursor.aChar[] */ + ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ ); if( !pCsr ){ @@ -127,7 +127,7 @@ static int icuOpen( } memset(pCsr, 0, sizeof(IcuCursor)); pCsr->aChar = (UChar *)&pCsr[1]; - pCsr->aOffset = (int *)&pCsr->aChar[nChar]; + pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3]; pCsr->aOffset[iOut] = iInput; U8_NEXT(zInput, iInput, nInput, c); diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index 6fce3d0a69..4bee014dcc 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -576,7 +576,7 @@ static int fts3SnippetShift( return rc; } while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){ - const char *ZDUMMY; int DUMMY1, DUMMY2, DUMMY3; + const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0; rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent); } pMod->xClose(pC); @@ -620,8 +620,6 @@ static int fts3SnippetText( int iCol = pFragment->iCol+1; /* Query column to extract text from */ sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ - const char *ZDUMMY; /* Dummy argument used with tokenizer */ - int DUMMY1; /* Dummy argument used with tokenizer */ zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); if( zDoc==0 ){ @@ -640,10 +638,23 @@ static int fts3SnippetText( } while( rc==SQLITE_OK ){ - int iBegin; /* Offset in zDoc of start of token */ - int iFin; /* Offset in zDoc of end of token */ - int isHighlight; /* True for highlighted terms */ + const char *ZDUMMY; /* Dummy argument used with tokenizer */ + int DUMMY1 = -1; /* Dummy argument used with tokenizer */ + int iBegin = 0; /* Offset in zDoc of start of token */ + int iFin = 0; /* Offset in zDoc of end of token */ + int isHighlight = 0; /* True for highlighted terms */ + /* Variable DUMMY1 is initialized to a negative value above. Elsewhere + ** in the FTS code the variable that the third argument to xNext points to + ** is initialized to zero before the first (*but not necessarily + ** subsequent*) call to xNext(). This is done for a particular application + ** that needs to know whether or not the tokenizer is being used for + ** snippet generation or for some other purpose. + ** + ** Extreme care is required when writing code to depend on this + ** initialization. It is not a documented part of the tokenizer interface. + ** If a tokenizer is used directly by any code outside of FTS, this + ** convention might not be respected. */ rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent); if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ @@ -1333,8 +1344,6 @@ void sqlite3Fts3Offsets( ){ Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; - const char *ZDUMMY; /* Dummy argument used with xNext() */ - int NDUMMY; /* Dummy argument used with xNext() */ int rc; /* Return Code */ int nToken; /* Number of tokens in query */ int iCol; /* Column currently being processed */ @@ -1367,9 +1376,11 @@ void sqlite3Fts3Offsets( */ for(iCol=0; iColnColumn; iCol++){ sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ - int iStart; - int iEnd; - int iCurrent; + const char *ZDUMMY; /* Dummy argument used with xNext() */ + int NDUMMY = 0; /* Dummy argument used with xNext() */ + int iStart = 0; + int iEnd = 0; + int iCurrent = 0; const char *zDoc; int nDoc; diff --git a/ext/fts3/fts3_tokenizer.c b/ext/fts3/fts3_tokenizer.c index 4a7a17567a..8241be81fc 100644 --- a/ext/fts3/fts3_tokenizer.c +++ b/ext/fts3/fts3_tokenizer.c @@ -251,10 +251,10 @@ static void testFunc( const char *azArg[64]; const char *zToken; - int nToken; - int iStart; - int iEnd; - int iPos; + int nToken = 0; + int iStart = 0; + int iEnd = 0; + int iPos = 0; int i; Tcl_Obj *pRet; diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index c9f1743210..7869e638c5 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -779,13 +779,13 @@ static int fts3PendingTermsAdd( u32 *pnWord /* OUT: Number of tokens inserted */ ){ int rc; - int iStart; - int iEnd; - int iPos; + int iStart = 0; + int iEnd = 0; + int iPos = 0; int nWord = 0; char const *zToken; - int nToken; + int nToken = 0; sqlite3_tokenizer *pTokenizer = p->pTokenizer; sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; @@ -4934,9 +4934,9 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT); while( rc==SQLITE_OK ){ char const *zToken; /* Buffer containing token */ - int nToken; /* Number of bytes in token */ - int iDum1, iDum2; /* Dummy variables */ - int iPos; /* Position of token in zText */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos); if( rc==SQLITE_OK ){ @@ -5103,9 +5103,9 @@ int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); while( rc==SQLITE_OK ){ char const *zToken; /* Buffer containing token */ - int nToken; /* Number of bytes in token */ - int iDum1, iDum2; /* Dummy variables */ - int iPos; /* Position of token in zText */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ diff --git a/main.mk b/main.mk index 39dbd5c16e..a48999e6d8 100644 --- a/main.mk +++ b/main.mk @@ -549,7 +549,7 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c $(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \ $(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \ - -o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a + -o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB) amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c $(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \ @@ -622,4 +622,4 @@ clean: rm -f threadtest3 threadtest3.exe rm -f sqlite3.c fts?amal.c tclsqlite3.c rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c - rm -f sqlite-output.vsix + rm -f sqlite-*-output.vsix diff --git a/manifest b/manifest index dd60773dd1..e5ba609ecb 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\sall\sthe\slatest\score\schanges\sinto\sthe\ssessions\sbranch. -D 2012-10-15T14:25:16.488 +C Pull\sall\sthe\slatest\strunk\senhancements\sinto\sthe\ssessions\sbranch. +D 2012-10-30T21:03:48.529 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb +F Makefile.in 82c41c0ed4cc94dd3cc7d498575b84c57c2c2384 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc eeacc62cbb02aa3ef6a5c8bdb5d4e6a70f5ca5b2 +F Makefile.msc 1aba45c2d159c2beb62486e4eaa6e2c96c56dd46 F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d @@ -45,7 +45,7 @@ F ext/fts2/fts2.c 4ef7d7ecf590da0dd416ac54612c53a7d4175790 F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa F ext/fts2/fts2_hash.c 2689e42e1107ea67207f725cf69cf8972d00cf93 F ext/fts2/fts2_hash.h 9a5b1be94664139f93217a0770d7144425cffb3a -F ext/fts2/fts2_icu.c 1ea9993a39c9783c2e2d7446d055e9d64411dda0 +F ext/fts2/fts2_icu.c 51c5cd3c04954badd329fa738c95fcdb717b5188 F ext/fts2/fts2_porter.c 747056987951f743e955c8479f1df21a565720fe F ext/fts2/fts2_tokenizer.c 26e993a00b2bd5b6e73c155597361710b12ffe25 F ext/fts2/fts2_tokenizer.h a7e46462d935a314b2682287f12f27530a3ee08e @@ -55,24 +55,24 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c ab90126ee0163539d21d0618d22afa2eb645f7e2 +F ext/fts3/fts3.c a867cafae0235324df64c5775cbf352a3f712cb9 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 1e58825246b56259267382d2f9902774c049460a F ext/fts3/fts3_aux.c 5205182bd8f372782597888156404766edf5781e -F ext/fts3/fts3_expr.c dbc7ba4c3a6061adde0f38ed8e9b349568299551 +F ext/fts3/fts3_expr.c ceefcaf91344abbf6ceb3cadf404eef5be6924e6 F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec -F ext/fts3/fts3_icu.c b85eca4a52e5ec11b94392de5167974c11906d4a +F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5 F ext/fts3/fts3_porter.c a465b49fcb8249a755792f87516eff182efa42b3 -F ext/fts3/fts3_snippet.c bf67520ae9d2352a65368ed101729ff701c08808 +F ext/fts3/fts3_snippet.c f6ebb3536069ceaa27e9f178f4a59379db44ac10 F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763 F ext/fts3/fts3_test.c 348f7d08cae05285794e23dc4fe8b8fdf66e264a -F ext/fts3/fts3_tokenizer.c e94a8b901066031437ccfe4769fc76370257cede +F ext/fts3/fts3_tokenizer.c 3664bb8836ab7633cf9da786c9d6fd366be5ae2c F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559 F ext/fts3/fts3_unicode2.c a863f05f758af36777dffc2facc898bc73fec896 -F ext/fts3/fts3_write.c c30c49f3debb9497a07f15cc4c042815e35474ef +F ext/fts3/fts3_write.c ba0bb0a91ca792fba5101bd82fa14d8a00a96365 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197 @@ -115,7 +115,7 @@ F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk 9c55b39d4887aa834ca2e827b7361d95703887bc +F main.mk faf97ab7bd203e56b5d93975c80abd32c814ddec F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -133,7 +133,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c cab40f2c1fe79d6eb93d3b4086c78c41ad2fa5d0 F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 299377f0793038ad3ea322907fbda7fbea615094 +F src/btree.c eccee944cb2221e919d7a855e5928d8643194b14 F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621 F src/build.c f35dac52924a6e8e6346a90f0c195a84e28b6f21 @@ -141,13 +141,13 @@ F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 -F src/delete.c e44a1b66cd3dc1e9e2c74147ee4991214e6e6978 -F src/expr.c 57fb8e7a05d4147e40b9f4c439e37ed2abab9332 +F src/delete.c 9bc9463952bdc9fc43111b1f9c83a0af9b8e2239 +F src/expr.c 152ba793a8747061c0c332857d0e4d4fd52d4397 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898 F src/global.c fb44b11e02e06c995e6ed6642509edd23599d584 -F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 +F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 6273647b67e27e3f81b7d1fd144307ea726841d0 @@ -155,7 +155,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c 5cee8048dde78b2b47f5c2090cbb31b10d190673 +F src/main.c febaf66b42c36433b170e4704fef5b8b073a6d61 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -172,9 +172,9 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c 0d3a39dd576c9f384fd7772a2dadc67b144c6ce7 -F src/os_win.c 28bd027791252a4012dffd4d64355a1eb84d761c -F src/pager.c 36642c0955c19840b5445e7e9da7b5b0d8235346 +F src/os_unix.c 603d020fe6c58047794cc72c05c7c8f4a82a0579 +F src/os_win.c 43ec1285357e5d5d919cb0492eac775c58ad7d12 +F src/pager.c ee59fef31673d5124413c5a801cfd9ef3e6766d3 F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0 F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -186,14 +186,14 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 7b986a715ac281643309c29257bb58cfae7aa810 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 2a82736faeca1fe93315eda20c691d68ec13bb6c -F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7 +F src/select.c 3a8baf4719f9723b4e0b43f2baa60692d0d921f8 +F src/shell.c 24cd0aa74aff73ea08594629faead564c4c2a286 F src/sqlite.h.in d460ae07ecdd1c820272d9c217547c7b572cb4b7 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h c00feec4f6debb1cb4bad802d2c7fe5050e744ca +F src/sqliteInt.h 205fa7fd18a7e6e0ed2ff9cfbccf36fb51304ee4 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d -F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 +F src/status.c 53463144deb5dfac0a66b3be4dd7844b8f8a4c98 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 289be7b639406314813219ee7bc043d21f36ab12 F src/test1.c 936afc02766403e5debca49a1817a780e116df7e @@ -201,7 +201,7 @@ F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013 -F src/test6.c 417e1e214734393c24a8ee80b41485a9c4169123 +F src/test6.c 938794c970ed6810036c8d28450ca28166524bf7 F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843 F src/test8.c 8bcce65e5ee027fbfd7da41d28371aabbfd369ff F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -217,12 +217,12 @@ F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a F src/test_intarray.c 07ddcebe4097d400ffca362770f1d883c112387a -F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 +F src/test_intarray.h b999bb18d090b8d9d9c49d36ec37ef8f341fe169 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_malloc.c 01cd65ae7ae93de9fbf8214d1ee6b4eba4850700 F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d -F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d +F src/test_multiplex.h 9b63b95f07acedee425fdfe49a47197c9bf5f9d8 F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25 F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba @@ -247,21 +247,21 @@ F src/trigger.c 3f258307040173aff383eb23fb74c44fe829078c F src/update.c abb0fcabe551dae0a133fd2a4370b5a8c23b1831 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 -F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd -F src/vdbe.c e8e2e34c23a474c38f494d572a0d8accaabd0b4a -F src/vdbe.h 87b8ff40de3f55dbcdc33029416862f517c37a2f -F src/vdbeInt.h 39acf85fa83f98e27e728722a0f53daf7d174b61 +F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3 +F src/vdbe.c 640a7e140c7dc0465eff7e515252e434ca77286e +F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683 +F src/vdbeInt.h 2de43968dc47f1961d5bc76aa3cb68eacf433a7c F src/vdbeapi.c 58fdcd56109c05876f69c25d47a138ef370d3647 -F src/vdbeaux.c 1005a2ea2cbbe5d2841367eebae67ce848a6247a +F src/vdbeaux.c 5f53f96cda10e467ae308876157cad42572d9299 F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381 F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 -F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b +F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9 F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835 -F src/vtab.c 9c64ae18af78c740610df841c6f49fc2d240a279 +F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 3e6c1f9efe4c6a029b0a750e0f6a63964f43bcce +F src/where.c 6a753aa008de6494e64dd265a27afbb0ad80ccf5 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00 @@ -370,7 +370,7 @@ F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418 F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc F test/crash5.test 13b9ca94e048194bca070e26160ce76b406c56be F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba -F test/crash7.test 6c6a369af266af2ef50ab34df8f94d719065e2c1 +F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df F test/crash8.test 38767cb504bbe491de6be4a7006b154973a2309f F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 @@ -498,7 +498,7 @@ F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660 F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 F test/fts3malloc.test b86ea33db9e8c58c0c2f8027a9fcadaf6a1568be -F test/fts3matchinfo.test 15edde2c4d373d60449658176af7164d622a62f0 +F test/fts3matchinfo.test ecb08f586d027eb03941bcfcded6cb9d8ccb3a66 F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844 F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1 F test/fts3prefix2.test 477ca96e67f60745b7ac931cfa6e9b080c562da5 @@ -623,8 +623,8 @@ F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memsubsys1.test a8f9e37567453a5d1d9d37ec102d4d88ab6be33f F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 -F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d -F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 +F test/minmax.test c61518429e66e228efc79661fbd2dc3e4924ec44 +F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 536a3360470633a177e42fbc19660d146b51daef F test/misc1.test 889b40722442380a2f6575f30831b32b2372d70e @@ -719,7 +719,7 @@ F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared9.test 614a3ca431adc73c857632deb4eff75bcaee40ec F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf -F test/shell1.test 272384163432c0efd2c6817396beb0d119565d53 +F test/shell1.test 340125225cc96c7f48d59a869aaf82866e481007 F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 @@ -773,7 +773,7 @@ F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 F test/tkt-2a5629202f.test 1ab32e084e9fc3d36be6dee2617530846a0eb0b6 F test/tkt-2d1a5c67d.test b028a811049eb472cb2d3a43fc8ce4f6894eebda F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 -F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9 +F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58 F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac F test/tkt-385a5b56b9.test 7782a382912a51f09f1d1a1442bca1e75f9c549b F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678 @@ -864,7 +864,7 @@ F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19 F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218 F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d F test/tkt3522.test 22ce2ebbcb04a6be56c0977d405c207967318fd6 -F test/tkt3527.test 9e8f28a706c772d5a7cd1020c946fab6c74e3ae0 +F test/tkt3527.test 1a6a48441b560bdc53aec581a868eb576234874d F test/tkt3541.test 5dc257bde9bc833ab9cc6844bf170b998dbb950a F test/tkt3554.test f599967f279077bace39220cbe76085c7b423725 F test/tkt3581.test 1966b7193f1e3f14951cce8c66907ae69454e9a3 @@ -990,7 +990,7 @@ F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c -F tool/build-all-msvc.bat 76b835e0ab91e30f22d8aa48db9dea4d2dc59e9f x +F tool/build-all-msvc.bat 74fb6e5cca66ebdb6c9bbafb2f8b802f08146d38 x F tool/build-shell.sh b64a481901fc9ffe5ca8812a2a9255b6cfb77381 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b @@ -1008,7 +1008,7 @@ F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 F tool/mksqlite3c.tcl 589c7f44e990be1b8443cfe4808dce392b0327fa F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8 F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795 -F tool/mkvsix.tcl a27951f30bb39c3504196610f17f687fc0b1c94d +F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 F tool/omittest.tcl 4665982e95a6e5c1bd806cf7bc3dea95be422d77 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c @@ -1033,8 +1033,8 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P f1fbb8c5bfa84e84e0b8e2872d83b06a0c0d5acc 8745530b9a877db77fe2ca3ea9c6bc99ce033055 -R 2fad70ce160d67d476b8ae23c3ce13a3 +F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac +P 76767d651fe733614b1719aef9ad5ed4568234e4 9dca18f5fea84afbecb314ee1cdfb98430656af3 +R 44966c032a1121fa311efd7f4c01d9a9 U drh -Z 004a84637f514b12189e7dcddda1b18b +Z f9e45ab7bfa5d5b4a8fa6d0808ba86fd diff --git a/manifest.uuid b/manifest.uuid index 669e24dd0d..5b8cae9332 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -76767d651fe733614b1719aef9ad5ed4568234e4 \ No newline at end of file +fce667f2d93a4ba65ccf1e748469576a3cd7ffcc \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c0cda1281b..246843b79e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5744,7 +5744,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ assert( pPage->nOverflow==1 ); /* This error condition is now caught prior to reaching this function */ - if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT; + if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* Allocate a new page. This page will become the right-sibling of ** pPage. Make the parent page writable, so that the new divider cell diff --git a/src/delete.c b/src/delete.c index 1411b7c61f..8bca679510 100644 --- a/src/delete.c +++ b/src/delete.c @@ -112,6 +112,7 @@ void sqlite3MaterializeView( sqlite3SelectDelete(db, pDup); } pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); + if( pDup ) pDup->selFlags |= SF_Materialize; } sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pDup, &dest); diff --git a/src/expr.c b/src/expr.c index 04216b1711..3eee3c6d69 100644 --- a/src/expr.c +++ b/src/expr.c @@ -939,6 +939,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ pNewItem->addrFillSub = pOldItem->addrFillSub; pNewItem->regReturn = pOldItem->regReturn; pNewItem->isCorrelated = pOldItem->isCorrelated; + pNewItem->viaCoroutine = pOldItem->viaCoroutine; pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex); pNewItem->notIndexed = pOldItem->notIndexed; pNewItem->pIndex = pOldItem->pIndex; diff --git a/src/hash.c b/src/hash.c index d7625d3913..e81dcf95e4 100644 --- a/src/hash.c +++ b/src/hash.c @@ -193,7 +193,7 @@ static void removeElementGivenHash( } sqlite3_free( elem ); pH->count--; - if( pH->count<=0 ){ + if( pH->count==0 ){ assert( pH->first==0 ); assert( pH->count==0 ); sqlite3HashClear(pH); diff --git a/src/main.c b/src/main.c index 0d1e092c52..5778f8780a 100644 --- a/src/main.c +++ b/src/main.c @@ -3040,7 +3040,7 @@ int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { sqlite3 *db = va_arg(ap, sqlite3*); - db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff); + db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); break; } diff --git a/src/os_unix.c b/src/os_unix.c index 5fbac00713..9b6c9401a1 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -218,6 +218,10 @@ struct unixFile { const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ +#ifdef __QNXNTO__ + int sectorSize; /* Device sector size */ + int deviceCharacteristics; /* Precomputed device characteristics */ +#endif #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif @@ -3638,10 +3642,92 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ ** a database and its journal file) that the sector size will be the ** same for both. */ -static int unixSectorSize(sqlite3_file *pFile){ - (void)pFile; +#ifndef __QNXNTO__ +static int unixSectorSize(sqlite3_file *NotUsed){ + UNUSED_PARAMETER(NotUsed); return SQLITE_DEFAULT_SECTOR_SIZE; } +#endif + +/* +** The following version of unixSectorSize() is optimized for QNX. +*/ +#ifdef __QNXNTO__ +#include +#include +static int unixSectorSize(sqlite3_file *id){ + unixFile *pFile = (unixFile*)id; + if( pFile->sectorSize == 0 ){ + struct statvfs fsInfo; + + /* Set defaults for non-supported filesystems */ + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + pFile->deviceCharacteristics = 0; + if( fstatvfs(pFile->h, &fsInfo) == -1 ) { + return pFile->sectorSize; + } + + if( !strcmp(fsInfo.f_basetype, "tmp") ) { + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "etfs") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* etfs cluster size writes are atomic */ + (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "dos") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else{ + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + 0; + } + } + /* Last chance verification. If the sector size isn't a multiple of 512 + ** then it isn't valid.*/ + if( pFile->sectorSize % 512 != 0 ){ + pFile->deviceCharacteristics = 0; + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + } + return pFile->sectorSize; +} +#endif /* __QNXNTO__ */ /* ** Return the device characteristics for the file. @@ -3658,11 +3744,15 @@ static int unixSectorSize(sqlite3_file *pFile){ */ static int unixDeviceCharacteristics(sqlite3_file *id){ unixFile *p = (unixFile*)id; + int rc = 0; +#ifdef __QNXNTO__ + if( p->sectorSize==0 ) unixSectorSize(id); + rc = p->deviceCharacteristics; +#endif if( p->ctrlFlags & UNIXFILE_PSOW ){ - return SQLITE_IOCAP_POWERSAFE_OVERWRITE; - }else{ - return 0; + rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; } + return rc; } #ifndef SQLITE_OMIT_WAL diff --git a/src/os_win.c b/src/os_win.c index 2d4c74af9a..3c92b43d4e 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2192,7 +2192,8 @@ static int winWrite( if( retryIoerr(&nRetry, &lastErrno) ) continue; break; } - if( nWrite<=0 ){ + assert( nWrite==0 || nWrite<=(DWORD)nRem ); + if( nWrite==0 || nWrite>(DWORD)nRem ){ lastErrno = osGetLastError(); break; } diff --git a/src/pager.c b/src/pager.c index cec0c8ff8e..a96dc45b82 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5885,7 +5885,7 @@ int sqlite3PagerCommitPhaseOne( /* If this transaction has made the database smaller, then all pages ** being discarded by the truncation must be written to the journal - ** file. This can only happen in auto-vacuum mode. + ** file. ** ** Before reading the pages with page numbers larger than the ** current value of Pager.dbSize, set dbSize back to the value @@ -5893,7 +5893,6 @@ int sqlite3PagerCommitPhaseOne( ** calls to sqlite3PagerGet() return zeroed pages instead of ** reading data from the database file. */ - #ifndef SQLITE_OMIT_AUTOVACUUM if( pPager->dbSizedbOrigSize && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ @@ -5913,7 +5912,6 @@ int sqlite3PagerCommitPhaseOne( } pPager->dbSize = dbSize; } - #endif /* Write the master journal name into the journal file. If a master ** journal file name has already been written to the journal file, diff --git a/src/select.c b/src/select.c index 51847ffbdb..cba766f99d 100644 --- a/src/select.c +++ b/src/select.c @@ -3098,10 +3098,9 @@ static int flattenSubquery( pList = pParent->pEList; for(i=0; inExpr; i++){ if( pList->a[i].zName==0 ){ - const char *zSpan = pList->a[i].zSpan; - if( ALWAYS(zSpan) ){ - pList->a[i].zName = sqlite3DbStrDup(db, zSpan); - } + char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan); + sqlite3Dequote(zName); + pList->a[i].zName = zName; } } substExprList(db, pParent->pEList, iParent, pSub->pEList); @@ -3910,8 +3909,17 @@ int sqlite3Select( int isAggSub; if( pSub==0 ) continue; + + /* Sometimes the code for a subquery will be generated more than + ** once, if the subquery is part of the WHERE clause in a LEFT JOIN, + ** for example. In that case, do not regenerate the code to manifest + ** a view or the co-routine to implement a view. The first instance + ** is sufficient, though the subroutine to manifest the view does need + ** to be invoked again. */ if( pItem->addrFillSub ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); + if( pItem->viaCoroutine==0 ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); + } continue; } @@ -3932,6 +3940,35 @@ int sqlite3Select( p->selFlags |= SF_Aggregate; } i = -1; + }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0 + && OptimizationEnabled(db, SQLITE_SubqCoroutine) + ){ + /* Implement a co-routine that will return a single row of the result + ** set on each invocation. + */ + int addrTop; + int addrEof; + pItem->regReturn = ++pParse->nMem; + addrEof = ++pParse->nMem; + sqlite3VdbeAddOp0(v, OP_Goto); + addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); + sqlite3VdbeChangeP5(v, 1); + VdbeComment((v, "coroutine for %s", pItem->pTab->zName)); + pItem->addrFillSub = addrTop; + sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof); + sqlite3VdbeChangeP5(v, 1); + sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); + explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); + sqlite3Select(pParse, pSub, &dest); + pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; + pItem->viaCoroutine = 1; + sqlite3VdbeChangeP2(v, addrTop, dest.iSdst); + sqlite3VdbeChangeP3(v, addrTop, dest.nSdst); + sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof); + sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn); + VdbeComment((v, "end %s", pItem->pTab->zName)); + sqlite3VdbeJumpHere(v, addrTop-1); + sqlite3ClearTempRegCache(pParse); }else{ /* Generate a subroutine that will fill an ephemeral table with ** the content of this subquery. pItem->addrFillSub will point diff --git a/src/shell.c b/src/shell.c index 7ad60c505b..adb8165434 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2824,11 +2824,14 @@ static const char zOptions[] = " -bail stop after hitting an error\n" " -batch force batch I/O\n" " -column set output mode to 'column'\n" - " -cmd command run \"command\" before reading stdin\n" + " -cmd COMMAND run \"COMMAND\" before reading stdin\n" " -csv set output mode to 'csv'\n" " -echo print commands before execution\n" - " -init filename read/process named file\n" + " -init FILENAME read/process named file\n" " -[no]header turn headers on or off\n" +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) + " -heap SIZE Size of heap for memsys3 or memsys5\n" +#endif " -help show this message\n" " -html set output mode to HTML\n" " -interactive force interactive I/O\n" @@ -2837,8 +2840,8 @@ static const char zOptions[] = #ifdef SQLITE_ENABLE_MULTIPLEX " -multiplex enable the multiplexor VFS\n" #endif - " -nullvalue 'text' set text string for NULL values\n" - " -separator 'x' set output field separator (|)\n" + " -nullvalue TEXT set text string for NULL values. Default ''\n" + " -separator SEP set output field separator. Default: '|'\n" " -stats print memory stats before each finalize\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" @@ -2874,6 +2877,19 @@ static void main_init(struct callback_data *data) { sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); } +/* +** Get the argument to an --option. Throw an error and die if no argument +** is available. +*/ +static char *cmdline_option_value(int argc, char **argv, int i){ + if( i==argc ){ + fprintf(stderr, "%s: Error: missing argument to %s\n", + argv[0], argv[argc-1]); + exit(1); + } + return argv[i]; +} + int main(int argc, char **argv){ char *zErrMsg = 0; struct callback_data data; @@ -2903,24 +2919,35 @@ int main(int argc, char **argv){ ** the size of the alternative malloc heap, ** and the first command to execute. */ - for(i=1; i=argc){ - fprintf(stderr,"%s: Error: missing argument for option: %s\n", - Argv0, z); - fprintf(stderr,"Use -help for a list of options.\n"); - return 1; - } sqlite3_snprintf(sizeof(data.separator), data.separator, - "%.*s",(int)sizeof(data.separator)-1,argv[i]); + "%s",cmdline_option_value(argc,argv,++i)); }else if( strcmp(z,"-nullvalue")==0 ){ - i++; - if(i>=argc){ - fprintf(stderr,"%s: Error: missing argument for option: %s\n", - Argv0, z); - fprintf(stderr,"Use -help for a list of options.\n"); - return 1; - } sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, - "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]); + "%s",cmdline_option_value(argc,argv,++i)); }else if( strcmp(z,"-header")==0 ){ data.showHeader = 1; }else if( strcmp(z,"-noheader")==0 ){ @@ -3082,8 +3080,7 @@ int main(int argc, char **argv){ usage(1); }else if( strcmp(z,"-cmd")==0 ){ if( i==argc-1 ) break; - i++; - z = argv[i]; + z = cmdline_option_value(argc,argv,++i); if( z[0]=='.' ){ rc = do_meta_command(z, &data); if( rc && bail_on_error ) return rc; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9a34ec5fbe..d7857e5668 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -828,7 +828,7 @@ struct sqlite3 { unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ - u8 dbOptFlags; /* Flags to enable/disable optimizations */ + u16 dbOptFlags; /* Flags to enable/disable optimizations */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ @@ -980,7 +980,8 @@ struct sqlite3 { #define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ #define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ #define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ -#define SQLITE_AllOpts 0x00ff /* All optimizations */ +#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ +#define SQLITE_AllOpts 0xffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. @@ -1886,8 +1887,9 @@ struct SrcList { int addrFillSub; /* Address of subroutine to manifest a subquery */ int regReturn; /* Register holding return address of addrFillSub */ u8 jointype; /* Type of join between this able and the previous */ - u8 notIndexed; /* True if there is a NOT INDEXED clause */ - u8 isCorrelated; /* True if sub-query is correlated */ + unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ + unsigned isCorrelated :1; /* True if sub-query is correlated */ + unsigned viaCoroutine :1; /* Implemented as a co-routine */ #ifndef SQLITE_OMIT_EXPLAIN u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ #endif @@ -2111,14 +2113,15 @@ struct Select { ** Allowed values for Select.selFlags. The "SF" prefix stands for ** "Select Flag". */ -#define SF_Distinct 0x01 /* Output should be DISTINCT */ -#define SF_Resolved 0x02 /* Identifiers have been resolved */ -#define SF_Aggregate 0x04 /* Contains aggregate functions */ -#define SF_UsesEphemeral 0x08 /* Uses the OpenEphemeral opcode */ -#define SF_Expanded 0x10 /* sqlite3SelectExpand() called on this */ -#define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */ -#define SF_UseSorter 0x40 /* Sort using a sorter */ -#define SF_Values 0x80 /* Synthesized from VALUES clause */ +#define SF_Distinct 0x0001 /* Output should be DISTINCT */ +#define SF_Resolved 0x0002 /* Identifiers have been resolved */ +#define SF_Aggregate 0x0004 /* Contains aggregate functions */ +#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ +#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ +#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ +#define SF_UseSorter 0x0040 /* Sort using a sorter */ +#define SF_Values 0x0080 /* Synthesized from VALUES clause */ +#define SF_Materialize 0x0100 /* Force materialization of views */ /* diff --git a/src/status.c b/src/status.c index 04b7656afe..9b0df8001c 100644 --- a/src/status.c +++ b/src/status.c @@ -208,7 +208,7 @@ int sqlite3_db_status( db->pnBytesFreed = &nByte; for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ - sqlite3VdbeDeleteObject(db, pVdbe); + sqlite3VdbeClearObject(db, pVdbe); } db->pnBytesFreed = 0; diff --git a/src/test6.c b/src/test6.c index bae6b65dc2..f511be9def 100644 --- a/src/test6.c +++ b/src/test6.c @@ -312,8 +312,8 @@ static int writeListSync(CrashFile *pFile, int isCrash){ assert(pWrite->zBuf); #ifdef TRACE_CRASHTEST - printf("Trashing %d sectors @ sector %d (%s)\n", - 1+iLast-iFirst, iFirst, pWrite->pFile->zName + printf("Trashing %d sectors @ %lld (sector %d) (%s)\n", + 1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName ); #endif @@ -628,18 +628,19 @@ static int cfOpen( ** to read data from the 512-byte locking region of a file opened ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file ** never contains valid data anyhow. So avoid doing such a read here. + ** + ** UPDATE: It also contains an assert() verifying that each call + ** to the xRead() method reads less than 128KB of data. */ const int isDb = (flags&SQLITE_OPEN_MAIN_DB); - i64 iChunk = pWrapper->iSize; - if( iChunk>PENDING_BYTE && isDb ){ - iChunk = PENDING_BYTE; - } + i64 iOff; + memset(pWrapper->zData, 0, pWrapper->nData); - rc = sqlite3OsRead(pReal, pWrapper->zData, (int)iChunk, 0); - if( SQLITE_OK==rc && pWrapper->iSize>(PENDING_BYTE+512) && isDb ){ - i64 iOff = PENDING_BYTE+512; - iChunk = pWrapper->iSize - iOff; - rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], (int)iChunk, iOff); + for(iOff=0; iOffiSize; iOff += 512){ + int nRead = pWrapper->iSize - (int)iOff; + if( nRead>512 ) nRead = 512; + if( isDb && iOff==PENDING_BYTE ) continue; + rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff); } }else{ rc = SQLITE_NOMEM; diff --git a/src/test_intarray.h b/src/test_intarray.h index e994367c09..691337d1ae 100644 --- a/src/test_intarray.h +++ b/src/test_intarray.h @@ -76,6 +76,13 @@ */ #include "sqlite3.h" +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + /* ** An sqlite3_intarray is an abstract type to stores an instance of ** an integer array. @@ -112,3 +119,7 @@ int sqlite3_intarray_bind( sqlite3_int64 *aElements, /* Content of the intarray */ void (*xFree)(void*) /* How to dispose of the intarray when done */ ); + +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif diff --git a/src/test_multiplex.h b/src/test_multiplex.h index ec1ba9bb21..b7e1afea5f 100644 --- a/src/test_multiplex.h +++ b/src/test_multiplex.h @@ -46,6 +46,10 @@ #define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015 #define MULTIPLEX_CTRL_SET_MAX_CHUNKS 214016 +#ifdef __cplusplus +extern "C" { +#endif + /* ** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize() ** @@ -88,4 +92,8 @@ extern int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefaul */ extern int sqlite3_multiplex_shutdown(void); +#ifdef __cplusplus +} /* End of the 'extern "C"' block */ +#endif + #endif diff --git a/src/vacuum.c b/src/vacuum.c index 401d41dfb7..7ed2478326 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -85,6 +85,7 @@ void sqlite3Vacuum(Parse *pParse){ Vdbe *v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); + sqlite3VdbeUsesBtree(v, 0); } return; } diff --git a/src/vdbe.c b/src/vdbe.c index effea8530c..497564b55c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2247,6 +2247,11 @@ case OP_Column: { } }else if( ALWAYS(pC->pseudoTableReg>0) ){ pReg = &aMem[pC->pseudoTableReg]; + if( pC->multiPseudo ){ + sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); + Deephemeralize(pDest); + goto op_column_out; + } assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); payloadSize = pReg->n; @@ -3328,12 +3333,13 @@ case OP_SorterOpen: { break; } -/* Opcode: OpenPseudo P1 P2 P3 * * +/* Opcode: OpenPseudo P1 P2 P3 * P5 ** ** Open a new cursor that points to a fake table that contains a single ** row of data. The content of that one row in the content of memory -** register P2. In other words, cursor P1 becomes an alias for the -** MEM_Blob content contained in register P2. +** register P2 when P5==0. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. When P5==1, then the +** row is represented by P3 consecutive registers beginning with P2. ** ** A pseudo-table created by this opcode is used to hold a single ** row output from the sorter so that the row can be decomposed into @@ -3353,6 +3359,7 @@ case OP_OpenPseudo: { pCx->pseudoTableReg = pOp->p2; pCx->isTable = 1; pCx->isIndex = 0; + pCx->multiPseudo = pOp->p5; break; } @@ -4359,7 +4366,7 @@ case OP_Rowid: { /* out2-prerelease */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pseudoTableReg==0 ); + assert( pC->pseudoTableReg==0 || pC->nullRow ); if( pC->nullRow ){ pOut->flags = MEM_Null; break; diff --git a/src/vdbe.h b/src/vdbe.h index d62879e292..50ab1d30e7 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -190,7 +190,7 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); int sqlite3VdbeMakeLabel(Vdbe*); void sqlite3VdbeRunOnlyOnce(Vdbe*); void sqlite3VdbeDelete(Vdbe*); -void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); +void sqlite3VdbeClearObject(sqlite3*,Vdbe*); void sqlite3VdbeMakeReady(Vdbe*,Parse*); int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 5b42d394ef..bdae034fc0 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -63,6 +63,7 @@ struct VdbeCursor { Bool isIndex; /* True if an index containing keys only - no data */ Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ Bool isSorter; /* True if a new-style sorter */ + Bool multiPseudo; /* Multi-register pseudo-cursor */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ i64 seqCount; /* Sequence counter */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c10e26a7f2..c37a0c5664 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2435,12 +2435,14 @@ void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ } /* -** Free all memory associated with the Vdbe passed as the second argument. +** Free all memory associated with the Vdbe passed as the second argument, +** except for object itself, which is preserved. +** ** The difference between this function and sqlite3VdbeDelete() is that ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with -** the database connection. +** the database connection and frees the object itself. */ -void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ +void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; int i; assert( p->db==0 || p->db==db ); @@ -2461,7 +2463,6 @@ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, p->zExplain); sqlite3DbFree(db, p->pExplain); #endif - sqlite3DbFree(db, p); } /* @@ -2473,6 +2474,7 @@ void sqlite3VdbeDelete(Vdbe *p){ if( NEVER(p==0) ) return; db = p->db; assert( sqlite3_mutex_held(db->mutex) ); + sqlite3VdbeClearObject(db, p); if( p->pPrev ){ p->pPrev->pNext = p->pNext; }else{ @@ -2484,7 +2486,7 @@ void sqlite3VdbeDelete(Vdbe *p){ } p->magic = VDBE_MAGIC_DEAD; p->db = 0; - sqlite3VdbeDeleteObject(db, p); + sqlite3DbFree(db, p); } /* diff --git a/src/vdbesort.c b/src/vdbesort.c index ba1e9f0f23..d51bbf54a3 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -195,8 +195,11 @@ static int vdbeSorterIterRead( int rc; /* sqlite3OsRead() return code */ /* Determine how many bytes of data to read. */ - nRead = (int)(p->iEof - p->iReadOff); - if( nRead>p->nBuffer ) nRead = p->nBuffer; + if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){ + nRead = p->nBuffer; + }else{ + nRead = (int)(p->iEof - p->iReadOff); + } assert( nRead>0 ); /* Read data from the file. Return early if an error occurs. */ diff --git a/src/vtab.c b/src/vtab.c index 39fbacacbc..958202c31e 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -495,7 +495,6 @@ static int vtabCallConstructor( pVTable->db = db; pVTable->pMod = pMod; - assert( pTab->azModuleArg[1]==0 ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTab->azModuleArg[1] = db->aDb[iDb].zName; @@ -509,7 +508,6 @@ static int vtabCallConstructor( rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = pPriorCtx; if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; - pTab->azModuleArg[1] = 0; if( SQLITE_OK!=rc ){ if( zErr==0 ){ diff --git a/src/where.c b/src/where.c index b7663386ac..38f6f1436f 100644 --- a/src/where.c +++ b/src/where.c @@ -1815,10 +1815,16 @@ static void bestAutomaticIndex(WhereBestIdx *p){ /* Automatic indices are disabled at run-time */ return; } - if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ + if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 + && (p->cost.plan.wsFlags & WHERE_COVER_SCAN)==0 + ){ /* We already have some kind of index in use for this query. */ return; } + if( pSrc->viaCoroutine ){ + /* Cannot index a co-routine */ + return; + } if( pSrc->notIndexed ){ /* The NOT INDEXED clause appears in the SQL. */ return; @@ -2996,7 +3002,7 @@ static int isSortingIndex( ** SQLITE_BIG_DBL. If a plan is found that uses the named index, ** then the cost is calculated in the usual way. ** -** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table +** If a NOT INDEXED clause was attached to the table ** in the SELECT statement, then no indexes are considered. However, the ** selected plan may still take advantage of the built-in rowid primary key ** index. @@ -4024,6 +4030,16 @@ static Bitmask codeOneLoopStart( VdbeComment((v, "init LEFT JOIN no-match flag")); } + /* Special case of a FROM clause subquery implemented as a co-routine */ + if( pTabItem->viaCoroutine ){ + int regYield = pTabItem->regReturn; + sqlite3VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield); + pLevel->p2 = sqlite3VdbeAddOp1(v, OP_Yield, regYield); + VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName)); + sqlite3VdbeAddOp2(v, OP_If, regYield+1, addrBrk); + pLevel->op = OP_Goto; + }else + #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){ /* Case 0: The table is a virtual-table. Use the VFilter and VNext diff --git a/test/crash7.test b/test/crash7.test index 4554a2ac58..482999cbfd 100644 --- a/test/crash7.test +++ b/test/crash7.test @@ -13,6 +13,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix crash7 ifcapable !crashtest { finish_test @@ -79,4 +80,37 @@ foreach f [list test.db test.db-journal] { } } +db close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 2.0 { + CREATE TABLE t1(a, b, UNIQUE(a, b)); + INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1; + DELETE FROM t1 WHERE rowid%2; +} +db_save_and_close + +for {set i 0} {$i < 20} {incr i} { + db_restore_and_reopen + do_test 2.[expr $i+1].1 { + crashsql -file test.db -seed $i {VACUUM} + } {1 {child process exited abnormally}} + do_execsql_test 2.[expr $i+1].2 { PRAGMA integrity_check } {ok} +} + + finish_test diff --git a/test/fts3matchinfo.test b/test/fts3matchinfo.test index 924db9c8a1..3998c9a40c 100644 --- a/test/fts3matchinfo.test +++ b/test/fts3matchinfo.test @@ -407,5 +407,24 @@ do_catchsql_test 8.5.3.2 { SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*' } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +do_execsql_test 8.1 { + CREATE VIRTUAL TABLE t12 USING fts4; + INSERT INTO t12 VALUES('a b c d'); + SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a'; +} {{0 0 0 0 0 0 1 1 1}} +do_execsql_test 8.2 { + INSERT INTO t12 VALUES('a d c d'); + SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a'; +} { + {0 1 1 0 1 1 1 2 2} {1 1 1 1 1 1 1 2 2} +} +do_execsql_test 8.3 { + INSERT INTO t12 VALUES('a d d a'); + SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a'; +} { + {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} +} + finish_test diff --git a/test/minmax.test b/test/minmax.test index 599024508c..3621375ee7 100644 --- a/test/minmax.test +++ b/test/minmax.test @@ -299,7 +299,7 @@ ifcapable {compound && subquery} { SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5 ) } - } {1} + } {{}} do_test minmax-9.2 { execsql { SELECT max(rowid) FROM ( diff --git a/test/minmax2.test b/test/minmax2.test index 2f504d4999..da8fec30ce 100644 --- a/test/minmax2.test +++ b/test/minmax2.test @@ -289,7 +289,7 @@ ifcapable {compound && subquery} { SELECT max(rowid) FROM t4 UNION SELECT max(rowid) FROM t5 ) } - } {1} + } {{}} do_test minmax2-9.2 { execsql { SELECT max(rowid) FROM ( diff --git a/test/shell1.test b/test/shell1.test index 5c49d90532..e826b95e44 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -149,7 +149,7 @@ do_test shell1-1.14.3 { set res [catchcmd "-separator" ""] set rc [lindex $res 0] list $rc \ - [regexp {Error: missing argument for option: -separator} $res] + [regexp {Error: missing argument to -separator} $res] } {1 1} # -stats print memory stats before each finalize @@ -168,7 +168,7 @@ do_test shell1-1.15.3 { set res [catchcmd "-nullvalue" ""] set rc [lindex $res 0] list $rc \ - [regexp {Error: missing argument for option: -nullvalue} $res] + [regexp {Error: missing argument to -nullvalue} $res] } {1 1} # -version show SQLite version diff --git a/test/tkt-31338dca7e.test b/test/tkt-31338dca7e.test index 9423c684e9..41dd9d3bf8 100644 --- a/test/tkt-31338dca7e.test +++ b/test/tkt-31338dca7e.test @@ -91,7 +91,7 @@ do_test tkt-31338-3.1 { INSERT INTO t3 VALUES(4); CREATE TABLE t4(h); INSERT INTO t4 VALUES(5); - + SELECT * FROM t3 LEFT JOIN t1 ON d=g LEFT JOIN t4 ON c=h WHERE (a=1 AND h=4) OR (b IN ( diff --git a/test/tkt3527.test b/test/tkt3527.test index d9b1dadfdc..da3d05ac46 100644 --- a/test/tkt3527.test +++ b/test/tkt3527.test @@ -52,8 +52,8 @@ do_test tkt3527-1.1 { INSERT INTO Element VALUES(5,'Elem5'); INSERT INTO ElemOr Values(3,4); INSERT INTO ElemOr Values(3,5); - INSERT INTO ElemAnd VALUES(1,3,1,1,1); - INSERT INTO ElemAnd VALUES(1,2,1,1,1); + INSERT INTO ElemAnd VALUES(1,3,'a','b','c'); + INSERT INTO ElemAnd VALUES(1,2,'x','y','z'); CREATE VIEW ElemView1 AS SELECT @@ -112,12 +112,12 @@ do_test tkt3527-1.1 { SELECT * FROM ElemView1; } -} {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} +} {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} do_test tkt3527-1.2 { db eval { SELECT * FROM ElemView2; } -} {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} +} {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} finish_test diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index 989a2af795..758036fb75 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -6,6 +6,49 @@ :: Multi-Platform Build Tool for MSVC :: +REM +REM This batch script is used to build the SQLite DLL for multiple platforms +REM and configurations using MSVC. The built SQLite DLLs, their associated +REM import libraries, and optionally their symbols files, are placed within +REM the directory specified on the command line, in sub-directories named for +REM their respective platforms and configurations. This batch script must be +REM run from inside a Visual Studio Command Prompt for the desired version of +REM Visual Studio ^(the initial platform configured for the command prompt does +REM not really matter^). Exactly one command line argument is required, the +REM name of an existing directory to be used as the final destination directory +REM for the generated output files, which will be placed in sub-directories +REM created therein. Ideally, the directory specified should be empty. +REM +REM Example: +REM +REM CD /D C:\dev\sqlite\core +REM tool\build-all-msvc.bat C:\Temp +REM +REM In the example above, "C:\dev\sqlite\core" represents the root of the +REM source tree for SQLite and "C:\Temp" represents the final destination +REM directory for the generated output files. +REM +REM There are several environment variables that may be set to modify the +REM behavior of this batch script and its associated Makefile. The list of +REM platforms to build may be overriden by using the PLATFORMS environment +REM variable, which should contain a list of platforms ^(e.g. x86 x86_amd64 +REM x86_arm^). All platforms must be supported by the version of Visual Studio +REM being used. The list of configurations to build may be overridden by +REM setting the CONFIGURATIONS environment variable, which should contain a +REM list of configurations to build ^(e.g. Debug Retail^). Neither of these +REM variable values may contain any double quotes, surrounding or embedded. +REM Finally, the NCRTLIBPATH and NSDKLIBPATH environment variables may be set +REM to specify the location of the CRT and SDK, respectively, needed to compile +REM executables native to the architecture of the build machine during any +REM cross-compilation that may be necessary, depending on the platforms to be +REM built. These values in these two variables should be surrounded by double +REM quotes if they contain spaces. +REM +REM Please note that the SQLite build process performed by the Makefile +REM associated with this batch script requires both Gawk ^(gawk.exe^) and Tcl +REM 8.5 ^(tclsh85.exe^) to be present in a directory contained in the PATH +REM environment variable unless a pre-existing amalgamation file is used. +REM SETLOCAL REM SET __ECHO=ECHO @@ -93,18 +136,36 @@ IF NOT DEFINED PLATFORMS ( %_VECHO% Platforms = '%PLATFORMS%' +REM +REM NOTE: If the list of configurations is not already set, use the default +REM list. +REM +IF NOT DEFINED CONFIGURATIONS ( + SET CONFIGURATIONS=Debug Retail +) + +%_VECHO% Configurations = '%CONFIGURATIONS%' + REM REM NOTE: Setup environment variables to translate between the MSVC platform REM names and the names to be used for the platform-specific binary REM directories. REM +SET amd64_NAME=x64 +SET arm_NAME=ARM +SET x64_NAME=x64 SET x86_NAME=x86 SET x86_amd64_NAME=x64 SET x86_arm_NAME=ARM +SET x86_x64_NAME=x64 +%_VECHO% amd64_Name = '%amd64_NAME%' +%_VECHO% arm_Name = '%arm_NAME%' +%_VECHO% x64_Name = '%x64_NAME%' %_VECHO% x86_Name = '%x86_NAME%' %_VECHO% x86_amd64_Name = '%x86_amd64_NAME%' %_VECHO% x86_arm_Name = '%x86_arm_NAME%' +%_VECHO% x86_x64_Name = '%x86_x64_NAME%' REM REM NOTE: Check for the external tools needed during the build process ^(i.e. @@ -115,6 +176,24 @@ FOR %%T IN (gawk.exe tclsh85.exe) DO ( SET %%T_PATH=%%~dp$PATH:T ) +REM +REM NOTE: The Gawk executable "gawk.exe" is required during the SQLite build +REM process unless a pre-existing amalgamation file is used. +REM +IF NOT DEFINED gawk.exe_PATH ( + ECHO The Gawk executable "gawk.exe" is required to be in the PATH. + GOTO errors +) + +REM +REM NOTE: The Tcl 8.5 executable "tclsh85.exe" is required during the SQLite +REM build process unless a pre-existing amalgamation file is used. +REM +IF NOT DEFINED tclsh85.exe_PATH ( + ECHO The Tcl 8.5 executable "tclsh85.exe" is required to be in the PATH. + GOTO errors +) + REM REM NOTE: Set the TOOLPATH variable to contain all the directories where the REM external tools were found in the search above. @@ -128,11 +207,30 @@ REM NOTE: Check for MSVC 2012 because the Windows SDK directory handling is REM slightly different for that version. REM IF "%VisualStudioVersion%" == "11.0" ( - SET SET_NSDKLIBPATH=1 + REM + REM NOTE: If the Windows SDK library path has already been set, do not set + REM it to something else later on. + REM + IF NOT DEFINED NSDKLIBPATH ( + SET SET_NSDKLIBPATH=1 + ) ) ELSE ( CALL :fn_UnsetVariable SET_NSDKLIBPATH ) +REM +REM NOTE: Check if this is the Windows Phone SDK. If so, a different batch +REM file is necessary to setup the build environment. Since the variable +REM values involved here may contain parenthesis, using GOTO instead of +REM an IF block is required. +REM +IF DEFINED WindowsPhoneKitDir GOTO set_vcvarsall_phone +SET VCVARSALL=%VCINSTALLDIR%\vcvarsall.bat +GOTO set_vcvarsall_done +:set_vcvarsall_phone +SET VCVARSALL=%VCINSTALLDIR%\WPSDK\WP80\vcvarsphoneall.bat +:set_vcvarsall_done + REM REM NOTE: This is the outer loop. There should be exactly one iteration per REM platform. @@ -173,6 +271,7 @@ FOR %%P IN (%PLATFORMS%) DO ( CALL :fn_UnsetVariable Platform REM CALL :fn_UnsetVariable VCINSTALLDIR CALL :fn_UnsetVariable VSINSTALLDIR + CALL :fn_UnsetVariable WindowsPhoneKitDir CALL :fn_UnsetVariable WindowsSdkDir CALL :fn_UnsetVariable WindowsSdkDir_35 CALL :fn_UnsetVariable WindowsSdkDir_old @@ -182,7 +281,7 @@ FOR %%P IN (%PLATFORMS%) DO ( REM SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot% - FOR %%B IN (Debug Retail) DO ( + FOR %%B IN (%CONFIGURATIONS%) DO ( REM REM NOTE: When preparing the debug build, set the DEBUG and MEMDEBUG REM environment variables to be picked up by the MSVC makefile @@ -215,10 +314,10 @@ FOR %%P IN (%PLATFORMS%) DO ( REM REM NOTE: Attempt to setup the MSVC environment for this platform. REM - %__ECHO3% CALL "%VCINSTALLDIR%\vcvarsall.bat" %%P + %__ECHO3% CALL "%VCVARSALL%" %%P IF ERRORLEVEL 1 ( - ECHO Failed to call "%VCINSTALLDIR%\vcvarsall.bat" for platform %%P. + ECHO Failed to call "%VCVARSALL%" for platform %%P. GOTO errors ) @@ -228,10 +327,12 @@ FOR %%P IN (%PLATFORMS%) DO ( REM as current versions of their official batch file do not set REM the exit code upon failure. REM - IF NOT DEFINED __ECHO ( - IF NOT DEFINED WindowsSdkDir ( - ECHO Cannot build, Windows SDK not found for platform %%P. - GOTO errors + IF NOT DEFINED __ECHO3 ( + IF NOT DEFINED WindowsPhoneKitDir ( + IF NOT DEFINED WindowsSdkDir ( + ECHO Cannot build, Windows SDK not found for platform %%P. + GOTO errors + ) ) ) @@ -245,8 +346,13 @@ FOR %%P IN (%PLATFORMS%) DO ( REM file used to setup the MSVC environment. REM IF DEFINED SET_NSDKLIBPATH ( - CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH - CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86 + IF DEFINED WindowsPhoneKitDir ( + CALL :fn_CopyVariable WindowsPhoneKitDir NSDKLIBPATH + CALL :fn_AppendVariable NSDKLIBPATH \lib\x86 + ) ELSE IF DEFINED WindowsSdkDir ( + CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH + CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86 + ) ) REM diff --git a/tool/mkvsix.tcl b/tool/mkvsix.tcl index 6a84758cc8..e9f1f818da 100644 --- a/tool/mkvsix.tcl +++ b/tool/mkvsix.tcl @@ -2,7 +2,95 @@ # # This script is used to generate a VSIX (Visual Studio Extension) file for # SQLite usable by Visual Studio. - +# +# PREREQUISITES +# +# 1. Tcl 8.4 and later are supported, earlier versions have not been tested. +# +# 2. The "sqlite3.h" file is assumed to exist in the parent directory of the +# directory containing this script. The [optional] second command line +# argument to this script may be used to specify an alternate location. +# This script also assumes that the "sqlite3.h" file corresponds with the +# version of the binaries to be packaged. This assumption is not verified +# by this script. +# +# 3. The temporary directory specified in the TEMP or TMP environment variables +# must refer to an existing directory writable by the current user. +# +# 4. The "zip" and "unzip" command line tools must be located either in a +# directory contained in the PATH environment variable or specified as the +# exact file names to execute in the "ZipTool" and "UnZipTool" environment +# variables, respectively. +# +# 5. The template VSIX file (which is basically a zip file) must be located in +# a "win" directory inside the directory containing this script. It should +# not contain any executable binaries. It should only contain dynamic +# textual content files to be processed using [subst] and/or static content +# files to be copied verbatim. +# +# 6. The executable and other compiled binary files to be packaged into the +# final VSIX file (e.g. DLLs, LIBs, and PDBs) must be located in a single +# directory tree. The top-level directory of the tree must be specified as +# the first command line argument to this script. The second level +# sub-directory names must match those of the build configuration (e.g. +# "Debug" or "Retail"). The third level sub-directory names must match +# those of the platform (e.g. "x86", "x64", and "ARM"). For example, the +# binary files to be packaged would need to be organized as follows when +# packaging the "Debug" and "Retail" build configurations for the "x86" and +# "x64" platforms (in this example, "C:\temp" is the top-level directory as +# specified in the first command line argument): +# +# C:\Temp\Debug\x86\sqlite3.lib +# C:\Temp\Debug\x86\sqlite3.dll +# C:\Temp\Debug\x86\sqlite3.pdb +# C:\Temp\Debug\x64\sqlite3.lib +# C:\Temp\Debug\x64\sqlite3.dll +# C:\Temp\Debug\x64\sqlite3.pdb +# C:\Temp\Retail\x86\sqlite3.lib +# C:\Temp\Retail\x86\sqlite3.dll +# C:\Temp\Retail\x86\sqlite3.pdb +# C:\Temp\Retail\x64\sqlite3.lib +# C:\Temp\Retail\x64\sqlite3.dll +# C:\Temp\Retail\x64\sqlite3.pdb +# +# The above directory tree organization is performed automatically if the +# "tool\build-all-msvc.bat" batch script is used to build the binary files +# to be packaged. +# +# USAGE +# +# The first argument to this script is required and must be the name of the +# top-level directory containing the directories and files organized into a +# tree as described in item 6 of the PREREQUISITES section, above. The second +# argument is optional and if present must contain the name of the directory +# containing the root of the source tree for SQLite. The third argument is +# optional and if present must contain the flavor the VSIX package to build. +# Currently, the only supported package flavors are "WinRT" and "WP80". The +# fourth argument is optional and if present must be a string containing a list +# of platforms to include in the VSIX package. The format of the platform list +# string is "platform1,platform2,platform3". Typically, when on Windows, this +# script is executed using commands similar to the following from a normal +# Windows command prompt: +# +# CD /D C:\dev\sqlite\core +# tclsh85 tool\mkvsix.tcl C:\Temp +# +# In the example above, "C:\dev\sqlite\core" represents the root of the source +# tree for SQLite and "C:\Temp" represents the top-level directory containing +# the executable and other compiled binary files, organized into a directory +# tree as described in item 6 of the PREREQUISITES section, above. +# +# This script should work on non-Windows platforms as well, provided that all +# the requirements listed in the PREREQUISITES section are met. +# +# NOTES +# +# The temporary directory is used as a staging area for the final VSIX file. +# The template VSIX file is extracted, its contents processed, and then the +# resulting files are packaged into the final VSIX file. +# +package require Tcl 8.4 + proc fail { {error ""} {usage false} } { if {[string length $error] > 0} then { puts stdout $error @@ -11,7 +99,8 @@ proc fail { {error ""} {usage false} } { puts stdout "usage:\ [file tail [info nameofexecutable]]\ -[file tail [info script]] \[sourceDirectory\]" +[file tail [info script]] \[sourceDirectory\]\ +\[packageFlavor\] \[platformNames\]" exit 1 } @@ -84,21 +173,24 @@ proc writeFile { fileName data } { proc substFile { fileName } { # # NOTE: Performs all Tcl command, variable, and backslash substitutions in - # the specified file and then re-writes the contents of that same file + # the specified file and then rewrites the contents of that same file # with the substituted data. # return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]] } -proc replaceBuildAndPlatform { fileName buildName platformName } { +proc replaceFileNameTokens { fileName name buildName platformName } { # # NOTE: Returns the specified file name containing the platform name instead # of platform placeholder tokens. # - return [string map [list $buildName $platformName] \ - $fileName] + return [string map [list $buildName $platformName \ + $name] $fileName] } +# +# NOTE: This is the entry point for this script. +# set script [file normalize [info script]] if {[string length $script] == 0} then { @@ -114,7 +206,7 @@ set rootName [file rootname [file tail $script]] # NOTE: Process and verify all the command line arguments. # set argc [llength $argv] -if {$argc != 1 && $argc != 2} then {fail} +if {$argc < 1 || $argc > 4} then {fail} set binaryDirectory [lindex $argv 0] @@ -127,7 +219,7 @@ if {![file exists $binaryDirectory] || \ fail "binary directory does not exist" } -if {$argc == 2} then { +if {$argc >= 2} then { set sourceDirectory [lindex $argv 1] } else { # @@ -146,6 +238,47 @@ if {![file exists $sourceDirectory] || \ fail "source directory does not exist" } +if {$argc >= 3} then { + set packageFlavor [lindex $argv 2] +} else { + # + # NOTE: Assume the package flavor is WinRT. + # + set packageFlavor WinRT +} + +if {[string length $packageFlavor] == 0} then { + fail "invalid package flavor" +} + +if {[string equal -nocase $packageFlavor WinRT]} then { + set shortName SQLite.WinRT + set displayName "SQLite for Windows Runtime" + set targetPlatformIdentifier Windows + set extraSdkPath "" + set extraFileListAttributes [appendArgs \ + "\r\n " {AppliesTo="WindowsAppContainer"} \ + "\r\n " {DependsOn="Microsoft.VCLibs, version=11.0"}] +} elseif {[string equal -nocase $packageFlavor WP80]} then { + set shortName SQLite.WP80 + set displayName "SQLite for Windows Phone" + set targetPlatformIdentifier "Windows Phone" + set extraSdkPath "\\..\\$targetPlatformIdentifier" + set extraFileListAttributes "" +} else { + fail "unsupported package flavor, must be \"WinRT\" or \"WP80\"" +} + +if {$argc >= 4} then { + set platformNames [list] + + foreach platformName [split [lindex $argv 3] ", "] { + if {[string length $platformName] > 0} then { + lappend platformNames $platformName + } + } +} + ############################################################################### # @@ -169,7 +302,8 @@ if {![file exists $templateFile] || \ } set currentDirectory [pwd] -set outputFile [file join $currentDirectory sqlite-output.vsix] +set outputFile [file join $currentDirectory [appendArgs sqlite- \ + $packageFlavor -output.vsix]] if {[file exists $outputFile]} then { fail [appendArgs "output file \"" $outputFile "\" already exists"] @@ -245,13 +379,41 @@ if {![regexp -line -- $pattern $data dummy version]} then { ############################################################################### # -# NOTE: Setup the master file list data, including the necessary flags. +# NOTE: Setup all the master file list data. This includes the source file +# names, the destination file names, and the file processing flags. The +# possible file processing flags are: +# +# "buildNeutral" -- This flag indicates the file location and content do +# not depend on the build configuration. +# +# "platformNeutral" -- This flag indicates the file location and content +# do not depend on the build platform. +# +# "subst" -- This flag indicates that the file contains dynamic textual +# content that needs to be processed using [subst] prior to +# packaging the file into the final VSIX package. The primary +# use of this flag is to insert the name of the VSIX package, +# some package flavor-specific value, or the SQLite version +# into a file. +# +# "noDebug" -- This flag indicates that the file should be skipped when +# processing the debug build. +# +# "noRetail" -- This flag indicates that the file should be skipped when +# processing the retail build. +# +# "move" -- This flag indicates that the file should be moved from the +# source to the destination instead of being copied. +# +# This file metadata may be overridden, either in whole or in part, via +# the user-specific customizations file. # if {![info exists fileNames(source)]} then { - set fileNames(source) [list "" "" "" \ - [file join $sourceDirectory sqlite3.h] \ - [file join $binaryDirectory sqlite3.lib] \ - [file join $binaryDirectory sqlite3.dll]] + set fileNames(source) [list "" "" \ + [file join $stagingDirectory DesignTime sqlite3.props] \ + [file join $sourceDirectory sqlite3.h] \ + [file join $binaryDirectory sqlite3.lib] \ + [file join $binaryDirectory sqlite3.dll]] if {![info exists no(symbols)]} then { lappend fileNames(source) \ @@ -261,13 +423,12 @@ if {![info exists fileNames(source)]} then { if {![info exists fileNames(destination)]} then { set fileNames(destination) [list \ - [file join $stagingDirectory extension.vsixmanifest] \ - [file join $stagingDirectory SDKManifest.xml] \ - [file join $stagingDirectory DesignTime \ - SQLite.WinRT.props] \ - [file join $stagingDirectory DesignTime sqlite3.h] \ - [file join $stagingDirectory DesignTime sqlite3.lib] \ - [file join $stagingDirectory Redist sqlite3.dll]] + [file join $stagingDirectory extension.vsixmanifest] \ + [file join $stagingDirectory SDKManifest.xml] \ + [file join $stagingDirectory DesignTime .props] \ + [file join $stagingDirectory DesignTime sqlite3.h] \ + [file join $stagingDirectory DesignTime sqlite3.lib] \ + [file join $stagingDirectory Redist sqlite3.dll]] if {![info exists no(symbols)]} then { lappend fileNames(destination) \ @@ -275,50 +436,24 @@ if {![info exists fileNames(destination)]} then { } } -if {![info exists fileNames(buildNeutral)]} then { - set fileNames(buildNeutral) [list 1 1 1 1 0 0] +if {![info exists fileNames(flags)]} then { + set fileNames(flags) [list \ + [list buildNeutral platformNeutral subst] \ + [list buildNeutral platformNeutral subst] \ + [list buildNeutral platformNeutral subst move] \ + [list buildNeutral platformNeutral] \ + [list] [list] [list noRetail]] if {![info exists no(symbols)]} then { - lappend fileNames(buildNeutral) 0 - } -} - -if {![info exists fileNames(platformNeutral)]} then { - set fileNames(platformNeutral) [list 1 1 1 1 0 0] - - if {![info exists no(symbols)]} then { - lappend fileNames(platformNeutral) 0 - } -} - -if {![info exists fileNames(subst)]} then { - set fileNames(subst) [list 1 1 1 0 0 0] - - if {![info exists no(symbols)]} then { - lappend fileNames(subst) 0 - } -} - -if {![info exists fileNames(noDebug)]} then { - set fileNames(noDebug) [list 0 0 0 0 0 0] - - if {![info exists no(symbols)]} then { - lappend fileNames(noDebug) 0 - } -} - -if {![info exists fileNames(noRetail)]} then { - set fileNames(noRetail) [list 0 0 0 0 0 0] - - if {![info exists no(symbols)]} then { - lappend fileNames(noRetail) 1 + lappend fileNames(flags) [list noRetail] } } ############################################################################### # -# NOTE: Setup the list of builds supported by this script. +# NOTE: Setup the list of builds supported by this script. These may be +# overridden via the user-specific customizations file. # if {![info exists buildNames]} then { set buildNames [list Debug Retail] @@ -327,7 +462,9 @@ if {![info exists buildNames]} then { ############################################################################### # -# NOTE: Setup the list of platforms supported by this script. +# NOTE: Setup the list of platforms supported by this script. These may be +# overridden via the command line or the user-specific customizations +# file. # if {![info exists platformNames]} then { set platformNames [list x86 x64 ARM] @@ -341,47 +478,64 @@ if {![info exists platformNames]} then { file mkdir $stagingDirectory # -# NOTE: Build the Tcl command used to extract the template package to the -# staging directory. +# NOTE: Build the Tcl command used to extract the template VSIX package to +# the staging directory. # set extractCommand [list exec -- $unzip $templateFile -d $stagingDirectory] # -# NOTE: Extract the template package to the staging directory. +# NOTE: Extract the template VSIX package to the staging directory. # eval $extractCommand ############################################################################### # -# NOTE: Process each file in the master file list. There are actually four -# parallel lists that contain the source file names, destination file -# names, the platform-neutral flags, and the use-subst flags. When the -# platform-neutral flag is non-zero, the file is not platform-specific. -# When the use-subst flag is non-zero, the file is considered to be a -# text file that may contain Tcl variable and/or command replacements, -# to be dynamically replaced during processing. If the source file name -# is an empty string, then the destination file name will be assumed to -# already exist in the staging directory and will not be copied; however, -# dynamic replacements may still be performed on the destination file -# prior to the package being re-zipped. +# NOTE: Process each file in the master file list. There are actually three +# parallel lists that contain the source file names, the destination file +# names, and the file processing flags. If the "buildNeutral" flag is +# present, the file location and content do not depend on the build +# configuration and "CommonConfiguration" will be used in place of the +# build configuration name. If the "platformNeutral" flag is present, +# the file location and content do not depend on the build platform and +# "neutral" will be used in place of the build platform name. If the +# "subst" flag is present, the file is assumed to be a text file that may +# contain Tcl variable, command, and backslash replacements, to be +# dynamically replaced during processing using the Tcl [subst] command. +# If the "noDebug" flag is present, the file will be skipped when +# processing for the debug build. If the "noRetail" flag is present, the +# file will be skipped when processing for the retail build. If the +# "move" flag is present, the source file will be deleted after it is +# copied to the destination file. If the source file name is an empty +# string, the destination file name will be assumed to already exist in +# the staging directory and will not be copied; however, Tcl variable, +# command, and backslash replacements may still be performed on the +# destination file prior to the final VSIX package being built if the +# "subst" flag is present. # -foreach sourceFileName $fileNames(source) \ - destinationFileName $fileNames(destination) \ - buildNeutral $fileNames(buildNeutral) platformNeutral \ - $fileNames(platformNeutral) useSubst $fileNames(subst) \ - noDebug $fileNames(noDebug) noRetail $fileNames(noRetail) { +foreach sourceFileName $fileNames(source) \ + destinationFileName $fileNames(destination) \ + fileFlags $fileNames(flags) { + # + # NOTE: Process the file flags into separate boolean variables that may be + # used within the loop. + # + set isBuildNeutral [expr {[lsearch $fileFlags buildNeutral] != -1}] + set isPlatformNeutral [expr {[lsearch $fileFlags platformNeutral] != -1}] + set isMove [expr {[lsearch $fileFlags move] != -1}] + set useSubst [expr {[lsearch $fileFlags subst] != -1}] + # # NOTE: If the current file is build-neutral, then only one build will # be processed for it, namely "CommonConfiguration"; otherwise, each # supported build will be processed for it individually. # foreach buildName \ - [expr {$buildNeutral ? [list CommonConfiguration] : $buildNames}] { + [expr {$isBuildNeutral ? [list CommonConfiguration] : $buildNames}] { # # NOTE: Should the current file be skipped for this build? # - if {[info exists no${buildName}] && [set no${buildName}]} then { + if {[lsearch $fileFlags no${buildName}] != -1} then { continue } @@ -391,12 +545,12 @@ foreach sourceFileName $fileNames(source) \ # supported platform will be processed for it individually. # foreach platformName \ - [expr {$platformNeutral ? [list neutral] : $platformNames}] { + [expr {$isPlatformNeutral ? [list neutral] : $platformNames}] { # # NOTE: Use the actual platform name in the destination file name. # - set newDestinationFileName [replaceBuildAndPlatform \ - $destinationFileName $buildName $platformName] + set newDestinationFileName [replaceFileNameTokens $destinationFileName \ + $shortName $buildName $platformName] # # NOTE: Does the source file need to be copied to the destination file? @@ -410,8 +564,18 @@ foreach sourceFileName $fileNames(source) \ # # NOTE: Then, copy the source file to the destination file verbatim. # - file copy [replaceBuildAndPlatform $sourceFileName $buildName \ - $platformName] $newDestinationFileName + set newSourceFileName [replaceFileNameTokens $sourceFileName \ + $shortName $buildName $platformName] + + file copy $newSourceFileName $newDestinationFileName + + # + # NOTE: If this is a move instead of a copy, delete the source file + # now. + # + if {$isMove} then { + file delete $newSourceFileName + } } # @@ -439,13 +603,13 @@ foreach sourceFileName $fileNames(source) \ cd $stagingDirectory # -# NOTE: Build the Tcl command used to archive the final package in the +# NOTE: Build the Tcl command used to archive the final VSIX package in the # output directory. # set archiveCommand [list exec -- $zip -r $outputFile *] # -# NOTE: Build the final package archive in the output directory. +# NOTE: Build the final VSIX package archive in the output directory. # eval $archiveCommand diff --git a/tool/win/sqlite.vsix b/tool/win/sqlite.vsix index 4bdfda5c7d..93eefac2db 100644 Binary files a/tool/win/sqlite.vsix and b/tool/win/sqlite.vsix differ