1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Merge recent trunk changes into the sessions branch.

FossilOrigin-Name: a9db017eabdefafcda87c497e8bafa07002ac0fe
This commit is contained in:
drh
2014-07-24 16:23:51 +00:00
38 changed files with 993 additions and 241 deletions

View File

@ -1010,6 +1010,9 @@ clean:
rm -rf tsrc .target_source rm -rf tsrc .target_source
rm -f tclsqlite3$(TEXE) rm -f tclsqlite3$(TEXE)
rm -f testfixture$(TEXE) test.db rm -f testfixture$(TEXE) test.db
rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE)
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
rm -f wordcount$(TEXE)
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
rm -f sqlite3.c rm -f sqlite3.c
rm -f sqlite3rc.h rm -f sqlite3rc.h

View File

@ -1476,6 +1476,10 @@ showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C)
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showwal.c $(SQLITE3C) $(TOP)\tool\showwal.c $(SQLITE3C)
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C)
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\rollback-test.c $(SQLITE3C) $(TOP)\tool\rollback-test.c $(SQLITE3C)
@ -1508,6 +1512,9 @@ clean:
del /Q tclsqlite3.exe tclsqlite3.exp del /Q tclsqlite3.exe tclsqlite3.exp
del /Q testloadext.dll testloadext.exp del /Q testloadext.dll testloadext.exp
del /Q testfixture.exe testfixture.exp test.db del /Q testfixture.exe testfixture.exp test.db
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe
del /Q wordcount.exe
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
del /Q sqlite3.c sqlite3-*.c del /Q sqlite3.c sqlite3-*.c
del /Q sqlite3rc.h del /Q sqlite3rc.h

View File

@ -3750,7 +3750,7 @@ static void hashDestroy(void *p){
*/ */
void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#ifdef SQLITE_ENABLE_FTS4_UNICODE61 #ifndef SQLITE_DISABLE_FTS3_UNICODE
void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule);
#endif #endif
#ifdef SQLITE_ENABLE_ICU #ifdef SQLITE_ENABLE_ICU
@ -3768,7 +3768,7 @@ int sqlite3Fts3Init(sqlite3 *db){
Fts3Hash *pHash = 0; Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0; const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0; const sqlite3_tokenizer_module *pPorter = 0;
#ifdef SQLITE_ENABLE_FTS4_UNICODE61 #ifndef SQLITE_DISABLE_FTS3_UNICODE
const sqlite3_tokenizer_module *pUnicode = 0; const sqlite3_tokenizer_module *pUnicode = 0;
#endif #endif
@ -3777,7 +3777,7 @@ int sqlite3Fts3Init(sqlite3 *db){
sqlite3Fts3IcuTokenizerModule(&pIcu); sqlite3Fts3IcuTokenizerModule(&pIcu);
#endif #endif
#ifdef SQLITE_ENABLE_FTS4_UNICODE61 #ifndef SQLITE_DISABLE_FTS3_UNICODE
sqlite3Fts3UnicodeTokenizer(&pUnicode); sqlite3Fts3UnicodeTokenizer(&pUnicode);
#endif #endif
@ -3805,7 +3805,7 @@ int sqlite3Fts3Init(sqlite3 *db){
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
#ifdef SQLITE_ENABLE_FTS4_UNICODE61 #ifndef SQLITE_DISABLE_FTS3_UNICODE
|| sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
#endif #endif
#ifdef SQLITE_ENABLE_ICU #ifdef SQLITE_ENABLE_ICU

View File

@ -585,7 +585,7 @@ int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *);
/* fts3_unicode2.c (functions generated by parsing unicode text files) */ /* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifdef SQLITE_ENABLE_FTS4_UNICODE61 #ifndef SQLITE_DISABLE_FTS3_UNICODE
int sqlite3FtsUnicodeFold(int, int); int sqlite3FtsUnicodeFold(int, int);
int sqlite3FtsUnicodeIsalnum(int); int sqlite3FtsUnicodeIsalnum(int);
int sqlite3FtsUnicodeIsdiacritic(int); int sqlite3FtsUnicodeIsdiacritic(int);

View File

@ -13,7 +13,7 @@
** Implementation of the "unicode" full-text-search tokenizer. ** Implementation of the "unicode" full-text-search tokenizer.
*/ */
#ifdef SQLITE_ENABLE_FTS4_UNICODE61 #ifndef SQLITE_DISABLE_FTS3_UNICODE
#include "fts3Int.h" #include "fts3Int.h"
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
@ -231,7 +231,7 @@ static int unicodeCreate(
for(i=0; rc==SQLITE_OK && i<nArg; i++){ for(i=0; rc==SQLITE_OK && i<nArg; i++){
const char *z = azArg[i]; const char *z = azArg[i];
int n = strlen(z); int n = (int)strlen(z);
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
pNew->bRemoveDiacritic = 1; pNew->bRemoveDiacritic = 1;
@ -363,11 +363,11 @@ static int unicodeNext(
); );
/* Set the output variables and return. */ /* Set the output variables and return. */
pCsr->iOff = (z - pCsr->aInput); pCsr->iOff = (int)(z - pCsr->aInput);
*paToken = pCsr->zToken; *paToken = pCsr->zToken;
*pnToken = zOut - pCsr->zToken; *pnToken = (int)(zOut - pCsr->zToken);
*piStart = (zStart - pCsr->aInput); *piStart = (int)(zStart - pCsr->aInput);
*piEnd = (zEnd - pCsr->aInput); *piEnd = (int)(zEnd - pCsr->aInput);
*piPos = pCsr->iToken++; *piPos = pCsr->iToken++;
return SQLITE_OK; return SQLITE_OK;
} }
@ -390,4 +390,4 @@ void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){
} }
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */ #endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */

View File

@ -15,7 +15,7 @@
** DO NOT EDIT THIS MACHINE GENERATED FILE. ** DO NOT EDIT THIS MACHINE GENERATED FILE.
*/ */
#if defined(SQLITE_ENABLE_FTS4_UNICODE61) #ifndef SQLITE_DISABLE_FTS3_UNICODE
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
#include <assert.h> #include <assert.h>
@ -362,4 +362,4 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
return ret; return ret;
} }
#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ #endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */ #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */

View File

@ -376,7 +376,7 @@ static void showSegmentStats(sqlite3 *db, const char *zTab){
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
nLeaf = nSeg - nIdx; nLeaf = nSeg - nIdx;
printf("Leaf segments larger than %5d bytes.... %9d %5.2f%%\n", printf("Leaf segments larger than %5d bytes.... %9d %5.2f%%\n",
pgsz-45, n, n*100.0/nLeaf); pgsz-45, n, nLeaf>0 ? n*100.0/nLeaf : 0.0);
pStmt = prepare(db, "SELECT max(level%%1024) FROM '%q_segdir'", zTab); pStmt = prepare(db, "SELECT max(level%%1024) FROM '%q_segdir'", zTab);
mxLevel = 0; mxLevel = 0;
@ -554,7 +554,7 @@ static void decodeSegment(
sqlite3_int64 n; sqlite3_int64 n;
sqlite3_int64 iDocsz; sqlite3_int64 iDocsz;
int iHeight; int iHeight;
int i = 0; sqlite3_int64 i = 0;
int cnt = 0; int cnt = 0;
char zTerm[1000]; char zTerm[1000];
@ -576,12 +576,12 @@ static void decodeSegment(
fprintf(stderr, "term to long\n"); fprintf(stderr, "term to long\n");
exit(1); exit(1);
} }
memcpy(zTerm+iPrefix, aData+i, nTerm); memcpy(zTerm+iPrefix, aData+i, (size_t)nTerm);
zTerm[iPrefix+nTerm] = 0; zTerm[iPrefix+nTerm] = 0;
i += nTerm; i += nTerm;
if( iHeight==0 ){ if( iHeight==0 ){
i += getVarint(aData+i, &iDocsz); i += getVarint(aData+i, &iDocsz);
printf("term: %-25s doclist %7lld bytes offset %d\n", zTerm, iDocsz, i); printf("term: %-25s doclist %7lld bytes offset %lld\n", zTerm, iDocsz, i);
i += iDocsz; i += iDocsz;
}else{ }else{
printf("term: %-25s child %lld\n", zTerm, ++iChild); printf("term: %-25s child %lld\n", zTerm, ++iChild);
@ -749,18 +749,19 @@ static void decodeDoclist(
*/ */
static void showDoclist(sqlite3 *db, const char *zTab){ static void showDoclist(sqlite3 *db, const char *zTab){
const unsigned char *aData; const unsigned char *aData;
sqlite3_int64 offset, nData; sqlite3_int64 offset;
int nData;
sqlite3_stmt *pStmt; sqlite3_stmt *pStmt;
offset = atoi64(azExtra[1]); offset = atoi64(azExtra[1]);
nData = atoi64(azExtra[2]); nData = atoi(azExtra[2]);
pStmt = prepareToGetSegment(db, zTab, azExtra[0]); pStmt = prepareToGetSegment(db, zTab, azExtra[0]);
if( sqlite3_step(pStmt)!=SQLITE_ROW ){ if( sqlite3_step(pStmt)!=SQLITE_ROW ){
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
return; return;
} }
aData = sqlite3_column_blob(pStmt, 0); aData = sqlite3_column_blob(pStmt, 0);
printf("Doclist at %s offset %lld of size %lld bytes:\n", printf("Doclist at %s offset %lld of size %d bytes:\n",
azExtra[0], offset, nData); azExtra[0], offset, nData);
if( findOption("raw", 0, 0)!=0 ){ if( findOption("raw", 0, 0)!=0 ){
printBlob(aData+offset, nData); printBlob(aData+offset, nData);

View File

@ -1893,7 +1893,7 @@ static int spellfix1Init(
char **pzErr char **pzErr
){ ){
spellfix1_vtab *pNew = 0; spellfix1_vtab *pNew = 0;
const char *zModule = argv[0]; /* const char *zModule = argv[0]; // not used */
const char *zDbName = argv[1]; const char *zDbName = argv[1];
const char *zTableName = argv[2]; const char *zTableName = argv[2];
int nDbName; int nDbName;
@ -1947,7 +1947,7 @@ static int spellfix1Init(
spellfix1DbExec(&rc, db, spellfix1DbExec(&rc, db,
"CREATE INDEX IF NOT EXISTS \"%w\".\"%w_vocab_index_langid_k2\" " "CREATE INDEX IF NOT EXISTS \"%w\".\"%w_vocab_index_langid_k2\" "
"ON \"%w_vocab\"(langid,k2);", "ON \"%w_vocab\"(langid,k2);",
zDbName, zModule, zTableName zDbName, zTableName, zTableName
); );
} }
for(i=3; rc==SQLITE_OK && i<argc; i++){ for(i=3; rc==SQLITE_OK && i<argc; i++){

14
main.mk
View File

@ -655,6 +655,10 @@ showwal$(EXE): $(TOP)/tool/showwal.c sqlite3.o
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showwal$(EXE) \ $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showwal$(EXE) \
$(TOP)/tool/showwal.c sqlite3.o $(THREADLIB) $(TOP)/tool/showwal.c sqlite3.o $(THREADLIB)
fts3view$(EXE): $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o fts3view$(EXE) \
$(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(THREADLIB)
rollback-test$(EXE): $(TOP)/tool/rollback-test.c sqlite3.o rollback-test$(EXE): $(TOP)/tool/rollback-test.c sqlite3.o
$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o rollback-test$(EXE) \ $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o rollback-test$(EXE) \
$(TOP)/tool/rollback-test.c sqlite3.o $(THREADLIB) $(TOP)/tool/rollback-test.c sqlite3.o $(THREADLIB)
@ -702,10 +706,18 @@ clean:
rm -f fts3-testfixture fts3-testfixture.exe rm -f fts3-testfixture fts3-testfixture.exe
rm -f testfixture testfixture.exe rm -f testfixture testfixture.exe
rm -f threadtest3 threadtest3.exe rm -f threadtest3 threadtest3.exe
rm -f LogEst LogEst.exe
rm -f fts3view fts3view.exe
rm -f rollback-test rollback-test.exe
rm -f showdb showdb.exe
rm -f showjournal showjournal.exe
rm -f showstat4 showstat4.exe
rm -f showwal showwal.exe
rm -f speedtest1 speedtest1.exe
rm -f wordcount wordcount.exe
rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c
rm -f sqlite3rc.h rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h rm -f shell.c sqlite3ext.h
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
rm -f sqlite-*-output.vsix rm -f sqlite-*-output.vsix
rm -f mptester mptester.exe rm -f mptester mptester.exe
rm -f showdb

View File

@ -1,9 +1,9 @@
C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\ssessions\sbranch. C Merge\srecent\strunk\schanges\sinto\sthe\ssessions\sbranch.
D 2014-06-30T20:02:55.053 D 2014-07-24T16:23:51.251
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cdca3064ff319e7ef34eaf20bc32429e30903f48 F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 91ddfb80ab8afc6d5bd9145d82e52e800f29acf5 F Makefile.msc d389ce1d436d21a93a9f5f6211dc45e4b8860962
F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0 F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0
F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8 F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8
F VERSION 1c877615a9db323e3cd301e3d57d853f9d5c4a07 F VERSION 1c877615a9db323e3cd301e3d57d853f9d5c4a07
@ -78,9 +78,9 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 20bc65862cfcea0a39bb64a819f8fe92a8e144c1 F ext/fts3/fts3.c 2f5e925bdb9d6d3e488c5a981af60cad4f9cdfe7
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 16cddf2d7b0e5f3681615ae1d8ca0e45fca44918 F ext/fts3/fts3Int.h 53d4eca1fb23eab00681fb028fb82eb5705c1e21
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
F ext/fts3/fts3_expr.c 351395fad6fcb16ecfc61db0861008a70101330c F ext/fts3/fts3_expr.c 351395fad6fcb16ecfc61db0861008a70101330c
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60 F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
@ -94,12 +94,12 @@ F ext/fts3/fts3_tokenize_vtab.c 011170fe9eba5ff062f1a31d3188e00267716706
F ext/fts3/fts3_tokenizer.c bbdc731bc91338050675c6d1da9ab82147391e16 F ext/fts3/fts3_tokenizer.c bbdc731bc91338050675c6d1da9ab82147391e16
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9 F ext/fts3/fts3_unicode.c e80eef8a11f2020dc9c1eb95c5b405b9012f2fbe
F ext/fts3/fts3_unicode2.c 0113d3acf13429e6dc38e0647d1bc71211c31a4d F ext/fts3/fts3_unicode2.c c8adda75aad0c6c252ef3dd555f811f437485044
F ext/fts3/fts3_write.c 8260388626516a7005d06a9dce94f9e55c6c2a41 F ext/fts3/fts3_write.c 8260388626516a7005d06a9dce94f9e55c6c2a41
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197 F ext/fts3/tool/fts3view.c 3986531f2fc0ceca0c89c31ec7d0589b6adb19d6
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368 F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368
@ -116,7 +116,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/spellfix.c 93f3961074cebe63c31fcefe62ca2a032ee8dfed F ext/misc/spellfix.c cb016c2dab951ffd7b819a7bc8a750ebd6c26c0f
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@ -160,7 +160,7 @@ F ext/session/test_session.c 7878ac0e2fe9675e8ec24d54f6a538ccc105977f
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk cd6daae5f386acaf508b63dd9888018602f50da8 F main.mk 152593de5d19eeab0fdaacfdedd5eafdfdd83d5a
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@ -175,7 +175,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1
F src/analyze.c ec6e0691a6a23e0239dc733109b906ee04b89cc3 F src/analyze.c 1c9831015e8c575796a97692d1493ba720d16f27
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
@ -184,13 +184,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c
F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
F src/build.c 927e39b6aaf872c7b28f154f6acfeb9a05a72442 F src/build.c 48f400fa14fd6add244b954ce7e223ce7ccacf0b
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c 50b74c1dde25d1ebcb4fa5c870762e6470ee46f1 F src/delete.c 50b74c1dde25d1ebcb4fa5c870762e6470ee46f1
F src/expr.c 40d06d1543b1355aa02efa9666178f7642a96ed6 F src/expr.c b989d07fc7c8780fff77365a4fc59881223e340c
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c a549cff9fe8b736cdae21650ea0af6de29b77619 F src/fkey.c a549cff9fe8b736cdae21650ea0af6de29b77619
F src/func.c 3bc223ea36cd29a91c481485343d0ee4257ab8dc F src/func.c 3bc223ea36cd29a91c481485343d0ee4257ab8dc
@ -203,7 +203,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c 13f3dcd2037ea5891e2c83a87f29872a50d5ab79 F src/main.c 20aa3e3d5ef5727dff8efbfc3a9420460e201e05
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
@ -230,18 +230,18 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
F src/pragma.c 810ef31ccfaa233201dcf100637a9777cc24e897 F src/pragma.c e17c5ea1cb9eb9d93c41bbb7c3a17e747d5e0335
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c af06f66927919730f03479fed6ae9854f73419f4 F src/printf.c af06f66927919730f03479fed6ae9854f73419f4
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 5fc110baeacf120a73fe34e103f052632ff11a02 F src/resolve.c 5fc110baeacf120a73fe34e103f052632ff11a02
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
F src/select.c 6762c62e11b504aa014edceab8886495165e3a77 F src/select.c 6762c62e11b504aa014edceab8886495165e3a77
F src/shell.c 56de2dfa3f25def4bf03098f7e2256fbb42f6e3c F src/shell.c 191129c3f7a9cf241aea90ff6a6be3e74d3767f0
F src/sqlite.h.in a585e10c0d181b0f102df93477cfd3ab2b98b2e5 F src/sqlite.h.in a7cfafa4874726efb9ae51a88770a9de8b21a42c
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 19dc37674323885ba5b6be808d711253a7b027ae F src/sqliteInt.h 83f438c59867d023c9d555243706a9edb4945662
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@ -259,7 +259,7 @@ F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c f3865829c8add75c49b3cb53f0494650b9292138 F src/test_config.c f0252240543895769a6bf037c206a4af74cf1e3c
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
@ -291,17 +291,17 @@ F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
F src/test_vfs.c f84075a388527892ff184988f43b69ce69b8083c F src/test_vfs.c f84075a388527892ff184988f43b69ce69b8083c
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 F src/tokenize.c ae45399d6252b4d736af43bee1576ce7bff86aec
F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb
F src/update.c 0f16e1d55d642a7ae3199bd0c2c1f51a7ef1b9d4 F src/update.c 0f16e1d55d642a7ae3199bd0c2c1f51a7ef1b9d4
F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05
F src/util.c 049fe1d3c0e2209c1bee107aec2fcff6285f909f F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 62f985592bfa011c2b35f8d7bfb4d4090340ae40 F src/vdbe.c 7224ed5d23599e0bc57b79d03901e4b86d609da1
F src/vdbe.h ca3b6df299adce6e2f499c57e42ae54f142ae823 F src/vdbe.h ca3b6df299adce6e2f499c57e42ae54f142ae823
F src/vdbeInt.h 3c295f4466f4b8a7f4b9b126d20bbbb21c38011f F src/vdbeInt.h 31b5cb53bd7f7fda3805a323c970da65fb5a5efc
F src/vdbeapi.c d3c662762b62e330a03f29de8e2ac7098ef78030 F src/vdbeapi.c 52335de5ff97bba93d6779d8df87feab5d53d7df
F src/vdbeaux.c 36eb94ea73e470ffcfec401043d8c2fc7359be98 F src/vdbeaux.c f7ef74c5fb7f3da380b719ecbf9f23e558b099d3
F src/vdbeblob.c d7c232d1c6afc7ee1176c38b7d81b2e17af15ceb F src/vdbeblob.c d7c232d1c6afc7ee1176c38b7d81b2e17af15ceb
F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394 F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27 F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27
@ -310,7 +310,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c 6ff6f7e3b272fad66eea601af489777adea3cc1f F src/where.c 9454af8e5e18d6e91e5169eadfb61878e2cb42b1
F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6 F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -327,12 +327,13 @@ F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
F test/analyze3.test bf41f0f680dd1e0d44eed5e769531e93a5320275 F test/analyze3.test bf41f0f680dd1e0d44eed5e769531e93a5320275
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213 F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
F test/analyze6.test d31defa011a561b938b4608d3538c1b4e0b5e92c F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88 F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
F test/analyze9.test 93619368fff2db833747a6dfa9b1146a82e5d4d2 F test/analyze9.test 3ef1b471247308e710a794b6e50a6ab536c5604b
F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944 F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944
F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
@ -386,7 +387,7 @@ F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test 71bcf2fbd36a9732f617766dfd752552c8e491b5 F test/capi3.test 71bcf2fbd36a9732f617766dfd752552c8e491b5
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32 F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32
F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0 F test/capi3d.test c84af0c49267f9c3fbf4c1c46aa647646023811e
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
@ -614,6 +615,7 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/hexlit.test f9ecde8145bfc2341573473256c74ae37a200497
F test/hook.test 5429d34d6e59086175d8efbcd7e14d891375bdfb F test/hook.test 5429d34d6e59086175d8efbcd7e14d891375bdfb
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
@ -657,7 +659,7 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/join.test 559b81eb56ae350246f9c25986aa52c81c725c7e F test/join.test 52d4d49f86d0cf46926672878c4eaf0da399104a
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324 F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
@ -833,11 +835,11 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test fb080d67c81e8a80a79ea04b36f127209b5bd112 F test/shell1.test d60946b5fde4d85fe06db7331dfe89011f564350
F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3 F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5 F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
F test/shell5.test ef0c52952a4a96dc1d9ec3b1fa81ec897ca48154 F test/shell5.test 15a419cc1df21c892ed64f5596ae7a501f2816f2
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
@ -1111,7 +1113,7 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b
F test/where2.test 455a2eb2666e66c1e84e2cb5815173a85e6237db F test/where2.test 23fdb5d8e756554aad4ca7ae03de9dd8367a2c6e
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
@ -1175,10 +1177,10 @@ F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c 213e0288501b2cf67c1b2c72a9e5b8acda4738b3 F tool/showdb.c b9ee6b6c81a094bf33badbf7e9da34cdbc0cce25
F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5 F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5
F tool/showstat4.c c39279d6bd37cb999b634f0064f6f86ad7af008f F tool/showstat4.c c39279d6bd37cb999b634f0064f6f86ad7af008f
F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5 F tool/showwal.c 3209120269cdf9380f091459e47b776b4f81dfd3
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
F tool/spaceanal.tcl 8e50b217c56a6a086a1b47eac9d09c5cd65b996f F tool/spaceanal.tcl 8e50b217c56a6a086a1b47eac9d09c5cd65b996f
@ -1197,7 +1199,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 09e75d82d02f900e58eceaaa010a42fc7044c89f f925e9baafea625f63105f8013abb3807b418379 P a5d94eaba6aa12ff16d2a0af2fc752bcdb461877 fb1048cb2b613a0dbfe625a5df05e9dcd736a433
R 479d9c5a6e74a479850ba5a90b6bb579 R ccf3fca6dda4e0dab5dd164f413978b7
U drh U drh
Z 79686a893dbf1703dda2bbbc832594c3 Z 6de22260129246198d4b45e0c941be73

View File

@ -1 +1 @@
a5d94eaba6aa12ff16d2a0af2fc752bcdb461877 a9db017eabdefafcda87c497e8bafa07002ac0fe

View File

@ -1109,7 +1109,7 @@ static void analyzeOneTable(
** goto chng_addr_N ** goto chng_addr_N
*/ */
addrNextRow = sqlite3VdbeCurrentAddr(v); addrNextRow = sqlite3VdbeCurrentAddr(v);
for(i=0; i<nCol; i++){ for(i=0; i<nCol-1; i++){
char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
@ -1118,7 +1118,7 @@ static void analyzeOneTable(
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
VdbeCoverage(v); VdbeCoverage(v);
} }
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); sqlite3VdbeAddOp2(v, OP_Integer, nCol-1, regChng);
aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto);
/* /*
@ -1129,7 +1129,7 @@ static void analyzeOneTable(
** ... ** ...
*/ */
sqlite3VdbeJumpHere(v, addrGotoChng0); sqlite3VdbeJumpHere(v, addrGotoChng0);
for(i=0; i<nCol; i++){ for(i=0; i<nCol-1; i++){
sqlite3VdbeJumpHere(v, aGotoChng[i]); sqlite3VdbeJumpHere(v, aGotoChng[i]);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
} }
@ -1320,6 +1320,7 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
Table *pTab; Table *pTab;
Index *pIdx; Index *pIdx;
Token *pTableName; Token *pTableName;
Vdbe *v;
/* Read the database schema. If an error occurs, leave an error message /* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */ ** and code in pParse and return NULL. */
@ -1367,6 +1368,8 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
} }
} }
} }
v = sqlite3GetVdbe(pParse);
if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
} }
/* /*
@ -1425,14 +1428,19 @@ static void decodeIntArray(
#else #else
if( pIndex ) if( pIndex )
#endif #endif
{ while( z[0] ){
if( strcmp(z, "unordered")==0 ){ if( sqlite3_strglob("unordered*", z)==0 ){
pIndex->bUnordered = 1; pIndex->bUnordered = 1;
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
int v32 = 0; pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
sqlite3GetInt32(z+3, &v32);
pIndex->szIdxRow = sqlite3LogEst(v32);
} }
#ifdef SQLITE_ENABLE_COSTMULT
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
}
#endif
while( z[0]!=0 && z[0]!=' ' ) z++;
while( z[0]==' ' ) z++;
} }
} }
@ -1473,11 +1481,15 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
z = argv[2]; z = argv[2];
if( pIndex ){ if( pIndex ){
pIndex->bUnordered = 0;
decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex); decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
}else{ }else{
Index fakeIdx; Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow; fakeIdx.szIdxRow = pTable->szTabRow;
#ifdef SQLITE_ENABLE_COSTMULT
fakeIdx.pTable = pTable;
#endif
decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
pTable->szTabRow = fakeIdx.szIdxRow; pTable->szTabRow = fakeIdx.szIdxRow;
} }
@ -1519,7 +1531,16 @@ static void initAvgEq(Index *pIdx){
IndexSample *aSample = pIdx->aSample; IndexSample *aSample = pIdx->aSample;
IndexSample *pFinal = &aSample[pIdx->nSample-1]; IndexSample *pFinal = &aSample[pIdx->nSample-1];
int iCol; int iCol;
for(iCol=0; iCol<pIdx->nKeyCol; iCol++){ int nCol = 1;
if( pIdx->nSampleCol>1 ){
/* If this is stat4 data, then calculate aAvgEq[] values for all
** sample columns except the last. The last is always set to 1, as
** once the trailing PK fields are considered all index keys are
** unique. */
nCol = pIdx->nSampleCol-1;
pIdx->aAvgEq[nCol] = 1;
}
for(iCol=0; iCol<nCol; iCol++){
int i; /* Used to iterate through samples */ int i; /* Used to iterate through samples */
tRowcnt sumEq = 0; /* Sum of the nEq values */ tRowcnt sumEq = 0; /* Sum of the nEq values */
tRowcnt nSum = 0; /* Number of terms contributing to sumEq */ tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
@ -1542,7 +1563,6 @@ static void initAvgEq(Index *pIdx){
} }
if( avgEq==0 ) avgEq = 1; if( avgEq==0 ) avgEq = 1;
pIdx->aAvgEq[iCol] = avgEq; pIdx->aAvgEq[iCol] = avgEq;
if( pIdx->nSampleCol==1 ) break;
} }
} }
} }
@ -1601,7 +1621,6 @@ static int loadStatTbl(
while( sqlite3_step(pStmt)==SQLITE_ROW ){ while( sqlite3_step(pStmt)==SQLITE_ROW ){
int nIdxCol = 1; /* Number of columns in stat4 records */ int nIdxCol = 1; /* Number of columns in stat4 records */
int nAvgCol = 1; /* Number of entries in Index.aAvgEq */
char *zIndex; /* Index name */ char *zIndex; /* Index name */
Index *pIdx; /* Pointer to the index object */ Index *pIdx; /* Pointer to the index object */
@ -1619,13 +1638,17 @@ static int loadStatTbl(
** loaded from the stat4 table. In this case ignore stat3 data. */ ** loaded from the stat4 table. In this case ignore stat3 data. */
if( pIdx==0 || pIdx->nSample ) continue; if( pIdx==0 || pIdx->nSample ) continue;
if( bStat3==0 ){ if( bStat3==0 ){
nIdxCol = pIdx->nKeyCol+1; assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
nAvgCol = pIdx->nKeyCol; if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
nIdxCol = pIdx->nKeyCol;
}else{
nIdxCol = pIdx->nColumn;
}
} }
pIdx->nSampleCol = nIdxCol; pIdx->nSampleCol = nIdxCol;
nByte = sizeof(IndexSample) * nSample; nByte = sizeof(IndexSample) * nSample;
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
pIdx->aSample = sqlite3DbMallocZero(db, nByte); pIdx->aSample = sqlite3DbMallocZero(db, nByte);
if( pIdx->aSample==0 ){ if( pIdx->aSample==0 ){
@ -1633,7 +1656,7 @@ static int loadStatTbl(
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
pSpace = (tRowcnt*)&pIdx->aSample[nSample]; pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nAvgCol; pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
for(i=0; i<nSample; i++){ for(i=0; i<nSample; i++){
pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;

View File

@ -113,6 +113,19 @@ static void codeTableLocks(Parse *pParse){
#define codeTableLocks(x) #define codeTableLocks(x)
#endif #endif
/*
** Return TRUE if the given yDbMask object is empty - if it contains no
** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero()
** macros when SQLITE_MAX_ATTACHED is greater than 30.
*/
#if SQLITE_MAX_ATTACHED>30
int sqlite3DbMaskAllZero(yDbMask m){
int i;
for(i=0; i<sizeof(yDbMask); i++) if( m[i] ) return 0;
return 1;
}
#endif
/* /*
** This routine is called after a single SQL statement has been ** This routine is called after a single SQL statement has been
** parsed and a VDBE program to execute that statement has been ** parsed and a VDBE program to execute that statement has been
@ -149,18 +162,19 @@ void sqlite3FinishCoding(Parse *pParse){
** transaction on each used database and to verify the schema cookie ** transaction on each used database and to verify the schema cookie
** on each used database. ** on each used database.
*/ */
if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){ if( db->mallocFailed==0
yDbMask mask; && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
){
int iDb, i; int iDb, i;
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
sqlite3VdbeJumpHere(v, 0); sqlite3VdbeJumpHere(v, 0);
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ for(iDb=0; iDb<db->nDb; iDb++){
if( (mask & pParse->cookieMask)==0 ) continue; if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp4Int(v, sqlite3VdbeAddOp4Int(v,
OP_Transaction, /* Opcode */ OP_Transaction, /* Opcode */
iDb, /* P1 */ iDb, /* P1 */
(mask & pParse->writeMask)!=0, /* P2 */ DbMaskTest(pParse->writeMask,iDb), /* P2 */
pParse->cookieValue[iDb], /* P3 */ pParse->cookieValue[iDb], /* P3 */
db->aDb[iDb].pSchema->iGeneration /* P4 */ db->aDb[iDb].pSchema->iGeneration /* P4 */
); );
@ -216,7 +230,7 @@ void sqlite3FinishCoding(Parse *pParse){
pParse->nMem = 0; pParse->nMem = 0;
pParse->nSet = 0; pParse->nSet = 0;
pParse->nVar = 0; pParse->nVar = 0;
pParse->cookieMask = 0; DbMaskZero(pParse->cookieMask);
} }
/* /*
@ -3843,15 +3857,13 @@ int sqlite3OpenTempDatabase(Parse *pParse){
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse); Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3 *db = pToplevel->db; sqlite3 *db = pToplevel->db;
yDbMask mask;
assert( iDb>=0 && iDb<db->nDb ); assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 || iDb==1 ); assert( db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<SQLITE_MAX_ATTACHED+2 ); assert( iDb<SQLITE_MAX_ATTACHED+2 );
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
mask = ((yDbMask)1)<<iDb; if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
if( (pToplevel->cookieMask & mask)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb);
pToplevel->cookieMask |= mask;
pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
if( !OMIT_TEMPDB && iDb==1 ){ if( !OMIT_TEMPDB && iDb==1 ){
sqlite3OpenTempDatabase(pToplevel); sqlite3OpenTempDatabase(pToplevel);
@ -3890,7 +3902,7 @@ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse); Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3CodeVerifySchema(pParse, iDb); sqlite3CodeVerifySchema(pParse, iDb);
pToplevel->writeMask |= ((yDbMask)1)<<iDb; DbMaskSet(pToplevel->writeMask, iDb);
pToplevel->isMultiWrite |= setStatement; pToplevel->isMultiWrite |= setStatement;
} }

View File

@ -2075,7 +2075,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
i64 value; i64 value;
const char *z = pExpr->u.zToken; const char *z = pExpr->u.zToken;
assert( z!=0 ); assert( z!=0 );
c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); c = sqlite3DecOrHexToI64(z, &value);
if( c==0 || (c==2 && negFlag) ){ if( c==0 || (c==2 && negFlag) ){
char *zV; char *zV;
if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
@ -2085,7 +2085,14 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
#ifdef SQLITE_OMIT_FLOATING_POINT #ifdef SQLITE_OMIT_FLOATING_POINT
sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else #else
codeReal(v, z, negFlag, iMem); #ifndef SQLITE_OMIT_HEX_INTEGER
if( sqlite3_strnicmp(z,"0x",2)==0 ){
sqlite3ErrorMsg(pParse, "hex literal too big: %s", z);
}else
#endif
{
codeReal(v, z, negFlag, iMem);
}
#endif #endif
} }
} }

View File

@ -2122,8 +2122,8 @@ static const int aHardLimit[] = {
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
#endif #endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
# error SQLITE_MAX_ATTACHED must be between 0 and 62 # error SQLITE_MAX_ATTACHED must be between 0 and 125
#endif #endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
@ -3430,7 +3430,7 @@ sqlite3_int64 sqlite3_uri_int64(
){ ){
const char *z = sqlite3_uri_parameter(zFilename, zParam); const char *z = sqlite3_uri_parameter(zFilename, zParam);
sqlite3_int64 v; sqlite3_int64 v;
if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){
bDflt = v; bDflt = v;
} }
return bDflt; return bDflt;

View File

@ -1048,7 +1048,7 @@ void sqlite3Pragma(
Pager *pPager = sqlite3BtreePager(pDb->pBt); Pager *pPager = sqlite3BtreePager(pDb->pBt);
i64 iLimit = -2; i64 iLimit = -2;
if( zRight ){ if( zRight ){
sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); sqlite3DecOrHexToI64(zRight, &iLimit);
if( iLimit<-1 ) iLimit = -1; if( iLimit<-1 ) iLimit = -1;
} }
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
@ -1176,7 +1176,7 @@ void sqlite3Pragma(
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( zRight ){ if( zRight ){
int ii; int ii;
sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); sqlite3DecOrHexToI64(zRight, &sz);
if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
if( pId2->n==0 ) db->szMmap = sz; if( pId2->n==0 ) db->szMmap = sz;
for(ii=db->nDb-1; ii>=0; ii--){ for(ii=db->nDb-1; ii>=0; ii--){
@ -2219,7 +2219,7 @@ void sqlite3Pragma(
*/ */
case PragTyp_SOFT_HEAP_LIMIT: { case PragTyp_SOFT_HEAP_LIMIT: {
sqlite3_int64 N; sqlite3_int64 N;
if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){ if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
sqlite3_soft_heap_limit64(N); sqlite3_soft_heap_limit64(N);
} }
returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));

View File

@ -64,6 +64,7 @@
#if defined(_WIN32) || defined(WIN32) #if defined(_WIN32) || defined(WIN32)
# include <io.h> # include <io.h>
# include <fcntl.h>
#define isatty(h) _isatty(h) #define isatty(h) _isatty(h)
#ifndef access #ifndef access
# define access(f,m) _access((f),(m)) # define access(f,m) _access((f),(m))
@ -458,6 +459,7 @@ struct callback_data {
int showHeader; /* True to show column names in List or Column mode */ int showHeader; /* True to show column names in List or Column mode */
char *zDestTable; /* Name of destination table when MODE_Insert */ char *zDestTable; /* Name of destination table when MODE_Insert */
char separator[20]; /* Separator character for MODE_List */ char separator[20]; /* Separator character for MODE_List */
char newline[20]; /* Record separator in MODE_Csv */
int colWidth[100]; /* Requested width of each column when in column mode*/ int colWidth[100]; /* Requested width of each column when in column mode*/
int actualWidth[100]; /* Actual width of each column */ int actualWidth[100]; /* Actual width of each column */
char nullvalue[20]; /* The text to print when a NULL comes back from char nullvalue[20]; /* The text to print when a NULL comes back from
@ -659,7 +661,8 @@ static const char needCsvQuote[] = {
/* /*
** Output a single term of CSV. Actually, p->separator is used for ** Output a single term of CSV. Actually, p->separator is used for
** the separator, which may or may not be a comma. p->nullvalue is ** the separator, which may or may not be a comma. p->nullvalue is
** the null value. Strings are quoted if necessary. ** the null value. Strings are quoted if necessary. The separator
** is only issued if bSep is true.
*/ */
static void output_csv(struct callback_data *p, const char *z, int bSep){ static void output_csv(struct callback_data *p, const char *z, int bSep){
FILE *out = p->out; FILE *out = p->out;
@ -855,17 +858,26 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
break; break;
} }
case MODE_Csv: { case MODE_Csv: {
#if defined(WIN32) || defined(_WIN32)
fflush(p->out);
_setmode(_fileno(p->out), _O_BINARY);
#endif
if( p->cnt++==0 && p->showHeader ){ if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){ for(i=0; i<nArg; i++){
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
} }
fprintf(p->out,"\n"); fprintf(p->out,"%s",p->newline);
} }
if( azArg==0 ) break; if( azArg>0 ){
for(i=0; i<nArg; i++){ for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1); output_csv(p, azArg[i], i<nArg-1);
}
fprintf(p->out,"%s",p->newline);
} }
fprintf(p->out,"\n"); #if defined(WIN32) || defined(_WIN32)
fflush(p->out);
_setmode(_fileno(p->out), _O_TEXT);
#endif
break; break;
} }
case MODE_Insert: { case MODE_Insert: {
@ -1619,7 +1631,8 @@ static char zHelp[] =
".schema ?TABLE? Show the CREATE statements\n" ".schema ?TABLE? Show the CREATE statements\n"
" If TABLE specified, only show tables matching\n" " If TABLE specified, only show tables matching\n"
" LIKE pattern TABLE.\n" " LIKE pattern TABLE.\n"
".separator STRING Change separator used by output mode and .import\n" ".separator STRING ?NL? Change separator used by output mode and .import\n"
" NL is the end-of-line mark for CSV\n"
".shell CMD ARGS... Run CMD ARGS... in a system shell\n" ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
".show Show the current values for various settings\n" ".show Show the current values for various settings\n"
".stats on|off Turn stats on or off\n" ".stats on|off Turn stats on or off\n"
@ -1637,6 +1650,69 @@ static char zHelp[] =
/* Forward reference */ /* Forward reference */
static int process_input(struct callback_data *p, FILE *in); static int process_input(struct callback_data *p, FILE *in);
/*
** Implementation of the "readfile(X)" SQL function. The entire content
** of the file named X is read and returned as a BLOB. NULL is returned
** if the file does not exist or is unreadable.
*/
static void readfileFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zName;
FILE *in;
long nIn;
void *pBuf;
zName = (const char*)sqlite3_value_text(argv[0]);
if( zName==0 ) return;
in = fopen(zName, "rb");
if( in==0 ) return;
fseek(in, 0, SEEK_END);
nIn = ftell(in);
rewind(in);
pBuf = sqlite3_malloc( nIn );
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
}else{
sqlite3_free(pBuf);
}
fclose(in);
}
/*
** Implementation of the "writefile(X,Y)" SQL function. The argument Y
** is written into file X. The number of bytes written is returned. Or
** NULL is returned if something goes wrong, such as being unable to open
** file X for writing.
*/
static void writefileFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
FILE *out;
const char *z;
int n;
sqlite3_int64 rc;
const char *zFile;
zFile = (const char*)sqlite3_value_text(argv[0]);
if( zFile==0 ) return;
out = fopen(zFile, "wb");
if( out==0 ) return;
z = (const char*)sqlite3_value_blob(argv[1]);
if( z==0 ){
n = 0;
rc = 0;
}else{
n = sqlite3_value_bytes(argv[1]);
rc = fwrite(z, 1, n, out);
}
fclose(out);
sqlite3_result_int64(context, rc);
}
/* /*
** Make sure the database is open. If it is not, then open it. If ** Make sure the database is open. If it is not, then open it. If
@ -1660,6 +1736,10 @@ static void open_db(struct callback_data *p, int keepAlive){
#ifndef SQLITE_OMIT_LOAD_EXTENSION #ifndef SQLITE_OMIT_LOAD_EXTENSION
sqlite3_enable_load_extension(p->db, 1); sqlite3_enable_load_extension(p->db, 1);
#endif #endif
sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
readfileFunc, 0, 0);
sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
writefileFunc, 0, 0);
} }
} }
@ -2416,6 +2496,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
struct callback_data data; struct callback_data data;
char *zErrMsg = 0; char *zErrMsg = 0;
int doStats = 0;
if( nArg!=1 ){ if( nArg!=1 ){
fprintf(stderr, "Usage: .fullschema\n"); fprintf(stderr, "Usage: .fullschema\n");
rc = 1; rc = 1;
@ -2434,21 +2515,33 @@ static int do_meta_command(char *zLine, struct callback_data *p){
"ORDER BY rowid", "ORDER BY rowid",
callback, &data, &zErrMsg callback, &data, &zErrMsg
); );
sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master;'", if( rc==SQLITE_OK ){
callback, &data, &zErrMsg); sqlite3_stmt *pStmt;
data.mode = MODE_Insert; rc = sqlite3_prepare_v2(p->db,
data.zDestTable = "sqlite_stat1"; "SELECT rowid FROM sqlite_master"
shell_exec(p->db, "SELECT * FROM sqlite_stat1", " WHERE name GLOB 'sqlite_stat[134]'",
shell_callback, &data,&zErrMsg); -1, &pStmt, 0);
data.zDestTable = "sqlite_stat3"; doStats = sqlite3_step(pStmt)==SQLITE_ROW;
shell_exec(p->db, "SELECT * FROM sqlite_stat3", sqlite3_finalize(pStmt);
shell_callback, &data,&zErrMsg); }
data.zDestTable = "sqlite_stat4"; if( doStats==0 ){
shell_exec(p->db, "SELECT * FROM sqlite_stat4", fprintf(p->out, "/* No STAT tables available */\n");
shell_callback, &data, &zErrMsg); }else{
data.mode = MODE_Semi; fprintf(p->out, "ANALYZE sqlite_master;\n");
shell_exec(p->db, "SELECT 'ANALYZE sqlite_master;'", sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
shell_callback, &data, &zErrMsg); callback, &data, &zErrMsg);
data.mode = MODE_Insert;
data.zDestTable = "sqlite_stat1";
shell_exec(p->db, "SELECT * FROM sqlite_stat1",
shell_callback, &data,&zErrMsg);
data.zDestTable = "sqlite_stat3";
shell_exec(p->db, "SELECT * FROM sqlite_stat3",
shell_callback, &data,&zErrMsg);
data.zDestTable = "sqlite_stat4";
shell_exec(p->db, "SELECT * FROM sqlite_stat4",
shell_callback, &data, &zErrMsg);
fprintf(p->out, "ANALYZE sqlite_master;\n");
}
}else }else
if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
@ -2738,6 +2831,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
p->mode = MODE_Csv; p->mode = MODE_Csv;
sqlite3_snprintf(sizeof(p->separator), p->separator, ","); sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n");
}else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
p->mode = MODE_List; p->mode = MODE_List;
sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
@ -3016,13 +3110,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){
#endif #endif
if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
if( nArg==2 ){ if( nArg<2 || nArg>3 ){
sqlite3_snprintf(sizeof(p->separator), p->separator, fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n");
"%.*s", (int)sizeof(p->separator)-1, azArg[1]);
}else{
fprintf(stderr, "Usage: .separator STRING\n");
rc = 1; rc = 1;
} }
if( nArg>=2 ){
sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]);
}
if( nArg>=3 ){
sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]);
}
}else }else
if( c=='s' if( c=='s'
@ -3063,6 +3160,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
strlen30(p->outfile) ? p->outfile : "stdout"); strlen30(p->outfile) ? p->outfile : "stdout");
fprintf(p->out,"%9.9s: ", "separator"); fprintf(p->out,"%9.9s: ", "separator");
output_c_string(p->out, p->separator); output_c_string(p->out, p->separator);
fprintf(p->out," ");
output_c_string(p->out, p->newline);
fprintf(p->out, "\n"); fprintf(p->out, "\n");
fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
fprintf(p->out,"%9.9s: ","width"); fprintf(p->out,"%9.9s: ","width");
@ -3679,6 +3778,7 @@ static const char zOptions[] =
#ifdef SQLITE_ENABLE_MULTIPLEX #ifdef SQLITE_ENABLE_MULTIPLEX
" -multiplex enable the multiplexor VFS\n" " -multiplex enable the multiplexor VFS\n"
#endif #endif
" -newline SEP set newline character(s) for CSV\n"
" -nullvalue TEXT set text string for NULL values. Default ''\n" " -nullvalue TEXT set text string for NULL values. Default ''\n"
" -separator SEP set output field separator. Default: '|'\n" " -separator SEP set output field separator. Default: '|'\n"
" -stats print memory stats before each finalize\n" " -stats print memory stats before each finalize\n"
@ -3708,6 +3808,7 @@ static void main_init(struct callback_data *data) {
memset(data, 0, sizeof(*data)); memset(data, 0, sizeof(*data));
data->mode = MODE_List; data->mode = MODE_List;
memcpy(data->separator,"|", 2); memcpy(data->separator,"|", 2);
memcpy(data->newline,"\r\n", 3);
data->showHeader = 0; data->showHeader = 0;
sqlite3_config(SQLITE_CONFIG_URI, 1); sqlite3_config(SQLITE_CONFIG_URI, 1);
sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
@ -3800,6 +3901,7 @@ int main(int argc, char **argv){
if( z[1]=='-' ) z++; if( z[1]=='-' ) z++;
if( strcmp(z,"-separator")==0 if( strcmp(z,"-separator")==0
|| strcmp(z,"-nullvalue")==0 || strcmp(z,"-nullvalue")==0
|| strcmp(z,"-newline")==0
|| strcmp(z,"-cmd")==0 || strcmp(z,"-cmd")==0
){ ){
(void)cmdline_option_value(argc, argv, ++i); (void)cmdline_option_value(argc, argv, ++i);
@ -3909,6 +4011,9 @@ int main(int argc, char **argv){
}else if( strcmp(z,"-separator")==0 ){ }else if( strcmp(z,"-separator")==0 ){
sqlite3_snprintf(sizeof(data.separator), data.separator, sqlite3_snprintf(sizeof(data.separator), data.separator,
"%s",cmdline_option_value(argc,argv,++i)); "%s",cmdline_option_value(argc,argv,++i));
}else if( strcmp(z,"-newline")==0 ){
sqlite3_snprintf(sizeof(data.newline), data.newline,
"%s",cmdline_option_value(argc,argv,++i));
}else if( strcmp(z,"-nullvalue")==0 ){ }else if( strcmp(z,"-nullvalue")==0 ){
sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
"%s",cmdline_option_value(argc,argv,++i)); "%s",cmdline_option_value(argc,argv,++i));

View File

@ -2032,9 +2032,13 @@ int sqlite3_complete16(const void *sql);
/* /*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
** **
** ^This routine sets a callback function that might be invoked whenever ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
** an attempt is made to open a database table that another thread ** that might be invoked with argument P whenever
** or process has locked. ** an attempt is made to access a database table associated with
** [database connection] D when another thread
** or process has the table locked.
** The sqlite3_busy_handler() interface is used to implement
** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout].
** **
** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] ** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
** is returned immediately upon encountering the lock. ^If the busy callback ** is returned immediately upon encountering the lock. ^If the busy callback
@ -2043,16 +2047,18 @@ int sqlite3_complete16(const void *sql);
** ^The first argument to the busy handler is a copy of the void* pointer which ** ^The first argument to the busy handler is a copy of the void* pointer which
** is the third argument to sqlite3_busy_handler(). ^The second argument to ** is the third argument to sqlite3_busy_handler(). ^The second argument to
** the busy handler callback is the number of times that the busy handler has ** the busy handler callback is the number of times that the busy handler has
** been invoked for this locking event. ^If the ** been invoked for the same locking event. ^If the
** busy callback returns 0, then no additional attempts are made to ** busy callback returns 0, then no additional attempts are made to
** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned. ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned
** to the application.
** ^If the callback returns non-zero, then another attempt ** ^If the callback returns non-zero, then another attempt
** is made to open the database for reading and the cycle repeats. ** is made to access the database and the cycle repeats.
** **
** The presence of a busy handler does not guarantee that it will be invoked ** The presence of a busy handler does not guarantee that it will be invoked
** when there is lock contention. ^If SQLite determines that invoking the busy ** when there is lock contention. ^If SQLite determines that invoking the busy
** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler. ** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the
** busy handler.
** Consider a scenario where one process is holding a read lock that ** Consider a scenario where one process is holding a read lock that
** it is trying to promote to a reserved lock and ** it is trying to promote to a reserved lock and
** a second process is holding a reserved lock that it is trying ** a second process is holding a reserved lock that it is trying
@ -2084,10 +2090,12 @@ int sqlite3_complete16(const void *sql);
** ^(There can only be a single busy handler defined for each ** ^(There can only be a single busy handler defined for each
** [database connection]. Setting a new busy handler clears any ** [database connection]. Setting a new busy handler clears any
** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] ** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()]
** will also set or clear the busy handler. ** or evaluating [PRAGMA busy_timeout=N] will change the
** busy handler and thus clear any previously set busy handler.
** **
** The busy callback should not take any actions which modify the ** The busy callback should not take any actions which modify the
** database connection that invoked the busy handler. Any such actions ** database connection that invoked the busy handler. In other words,
** the busy handler is not reentrant. Any such actions
** result in undefined behavior. ** result in undefined behavior.
** **
** A busy handler must not close the database connection ** A busy handler must not close the database connection
@ -2112,6 +2120,8 @@ int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
** [database connection] any any given moment. If another busy handler ** [database connection] any any given moment. If another busy handler
** was defined (using [sqlite3_busy_handler()]) prior to calling ** was defined (using [sqlite3_busy_handler()]) prior to calling
** this routine, that other busy handler is cleared.)^ ** this routine, that other busy handler is cleared.)^
**
** See also: [PRAGMA busy_timeout]
*/ */
int sqlite3_busy_timeout(sqlite3*, int ms); int sqlite3_busy_timeout(sqlite3*, int ms);
@ -4701,6 +4711,13 @@ int sqlite3_sleep(int);
** is a NULL pointer, then SQLite performs a search for an appropriate ** is a NULL pointer, then SQLite performs a search for an appropriate
** temporary file directory. ** temporary file directory.
** **
** Applications are strongly discouraged from using this global variable.
** It is required to set a temporary folder on Windows Runtime (WinRT).
** But for all other platforms, it is highly recommended that applications
** neither read nor write this variable. This global variable is a relic
** that exists for backwards compatibility of legacy applications and should
** be avoided in new projects.
**
** It is not safe to read or modify this variable in more than one ** It is not safe to read or modify this variable in more than one
** thread at a time. It is not safe to read or modify this variable ** thread at a time. It is not safe to read or modify this variable
** if a [database connection] is being used at the same time in a separate ** if a [database connection] is being used at the same time in a separate
@ -4719,6 +4736,11 @@ int sqlite3_sleep(int);
** Hence, if this variable is modified directly, either it should be ** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc] ** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided. ** or else the use of the [temp_store_directory pragma] should be avoided.
** Except when requested by the [temp_store_directory pragma], SQLite
** does not free the memory that sqlite3_temp_directory points to. If
** the application wants that memory to be freed, it must do
** so itself, taking care to only do so after all [database connection]
** objects have been destroyed.
** **
** <b>Note to Windows Runtime users:</b> The temporary directory must be set ** <b>Note to Windows Runtime users:</b> The temporary directory must be set
** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various ** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various
@ -7139,6 +7161,9 @@ void *sqlite3_wal_hook(
** ^The [wal_autocheckpoint pragma] can be used to invoke this interface ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
** from SQL. ** from SQL.
** **
** ^Checkpoints initiated by this mechanism are
** [sqlite3_wal_checkpoint_v2|PASSIVE].
**
** ^Every new [database connection] defaults to having the auto-checkpoint ** ^Every new [database connection] defaults to having the auto-checkpoint
** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
** pages. The use of this interface ** pages. The use of this interface
@ -7155,6 +7180,10 @@ int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
** empty string, then a checkpoint is run on all databases of ** empty string, then a checkpoint is run on all databases of
** connection D. ^If the database connection D is not in ** connection D. ^If the database connection D is not in
** [WAL | write-ahead log mode] then this interface is a harmless no-op. ** [WAL | write-ahead log mode] then this interface is a harmless no-op.
** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a
** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint.
** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL
** or RESET checkpoint.
** **
** ^The [wal_checkpoint pragma] can be used to invoke this interface ** ^The [wal_checkpoint pragma] can be used to invoke this interface
** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the
@ -7177,10 +7206,12 @@ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
** Checkpoint as many frames as possible without waiting for any database ** Checkpoint as many frames as possible without waiting for any database
** readers or writers to finish. Sync the db file if all frames in the log ** readers or writers to finish. Sync the db file if all frames in the log
** are checkpointed. This mode is the same as calling ** are checkpointed. This mode is the same as calling
** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked. ** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback]
** is never invoked.
** **
** <dt>SQLITE_CHECKPOINT_FULL<dd> ** <dt>SQLITE_CHECKPOINT_FULL<dd>
** This mode blocks (calls the busy-handler callback) until there is no ** This mode blocks (it invokes the
** [sqlite3_busy_handler|busy-handler callback]) until there is no
** database writer and all readers are reading from the most recent database ** database writer and all readers are reading from the most recent database
** snapshot. It then checkpoints all frames in the log file and syncs the ** snapshot. It then checkpoints all frames in the log file and syncs the
** database file. This call blocks database writers while it is running, ** database file. This call blocks database writers while it is running,
@ -7188,7 +7219,8 @@ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
** **
** <dt>SQLITE_CHECKPOINT_RESTART<dd> ** <dt>SQLITE_CHECKPOINT_RESTART<dd>
** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after
** checkpointing the log file it blocks (calls the busy-handler callback) ** checkpointing the log file it blocks (calls the
** [sqlite3_busy_handler|busy-handler callback])
** until all readers are reading from the database file only. This ensures ** until all readers are reading from the database file only. This ensures
** that the next client to write to the database file restarts the log file ** that the next client to write to the database file restarts the log file
** from the beginning. This call blocks database writers while it is running, ** from the beginning. This call blocks database writers while it is running,

View File

@ -1485,6 +1485,9 @@ struct Table {
i16 nCol; /* Number of columns in this table */ i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */ u16 nRef; /* Number of pointers to this Table */
LogEst szTabRow; /* Estimated size of each table row in bytes */ LogEst szTabRow; /* Estimated size of each table row in bytes */
#ifdef SQLITE_ENABLE_COSTMULT
LogEst costMult; /* Cost multiplier for using this table */
#endif
u8 tabFlags; /* Mask of TF_* values */ u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE #ifndef SQLITE_OMIT_ALTERTABLE
@ -2144,6 +2147,7 @@ struct SrcList {
#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
/* Allowed return values from sqlite3WhereIsDistinct() /* Allowed return values from sqlite3WhereIsDistinct()
*/ */
@ -2400,9 +2404,19 @@ struct TriggerPrg {
** The yDbMask datatype for the bitmask of all attached databases. ** The yDbMask datatype for the bitmask of all attached databases.
*/ */
#if SQLITE_MAX_ATTACHED>30 #if SQLITE_MAX_ATTACHED>30
typedef sqlite3_uint64 yDbMask; typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8];
# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0)
# define DbMaskZero(M) memset((M),0,sizeof(M))
# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7))
# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M)
# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0)
#else #else
typedef unsigned int yDbMask; typedef unsigned int yDbMask;
# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0)
# define DbMaskZero(M) (M)=0
# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I))
# define DbMaskAllZero(M) (M)==0
# define DbMaskNonZero(M) (M)!=0
#endif #endif
/* /*
@ -3079,6 +3093,9 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
# define sqlite3ViewGetColumnNames(A,B) 0 # define sqlite3ViewGetColumnNames(A,B) 0
#endif #endif
#if SQLITE_MAX_ATTACHED>30
int sqlite3DbMaskAllZero(yDbMask);
#endif
void sqlite3DropTable(Parse*, SrcList*, int, int); void sqlite3DropTable(Parse*, SrcList*, int, int);
void sqlite3CodeDropTable(Parse*, Table*, int, int); void sqlite3CodeDropTable(Parse*, Table*, int, int);
void sqlite3DeleteTable(sqlite3*, Table*); void sqlite3DeleteTable(sqlite3*, Table*);
@ -3329,6 +3346,7 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr); char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3Atoi64(const char*, i64*, int, u8); int sqlite3Atoi64(const char*, i64*, int, u8);
int sqlite3DecOrHexToI64(const char*, i64*);
void sqlite3Error(sqlite3*, int, const char*,...); void sqlite3Error(sqlite3*, int, const char*,...);
void *sqlite3HexToBlob(sqlite3*, const char *z, int n); void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
u8 sqlite3HexToInt(int h); u8 sqlite3HexToInt(int h);

View File

@ -336,7 +336,7 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY);
#endif #endif
#if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_ENABLE_FTS4_UNICODE61) #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_DISABLE_FTS3_UNICODE)
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "1", TCL_GLOBAL_ONLY);
#else #else
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY);

View File

@ -270,6 +270,12 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' );
testcase( z[0]=='9' ); testcase( z[0]=='9' );
*tokenType = TK_INTEGER; *tokenType = TK_INTEGER;
#ifndef SQLITE_OMIT_HEX_INTEGER
if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){
for(i=3; sqlite3Isxdigit(z[i]); i++){}
return i;
}
#endif
for(i=0; sqlite3Isdigit(z[i]); i++){} for(i=0; sqlite3Isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT #ifndef SQLITE_OMIT_FLOATING_POINT
if( z[i]=='.' ){ if( z[i]=='.' ){

View File

@ -475,9 +475,9 @@ static int compare2pow63(const char *zNum, int incr){
return c; return c;
} }
/* /*
** Convert zNum to a 64-bit signed integer. ** Convert zNum to a 64-bit signed integer. zNum must be decimal. This
** routine does *not* accept hexadecimal notation.
** **
** If the zNum value is representable as a 64-bit twos-complement ** If the zNum value is representable as a 64-bit twos-complement
** integer, then write that value into *pNum and return 0. ** integer, then write that value into *pNum and return 0.
@ -565,10 +565,44 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
} }
} }
/*
** Transform a UTF-8 integer literal, in either decimal or hexadecimal,
** into a 64-bit signed integer. This routine accepts hexadecimal literals,
** whereas sqlite3Atoi64() does not.
**
** Returns:
**
** 0 Successful transformation. Fits in a 64-bit signed integer.
** 1 Integer too large for a 64-bit signed integer or is malformed
** 2 Special case of 9223372036854775808
*/
int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
#ifndef SQLITE_OMIT_HEX_INTEGER
if( z[0]=='0'
&& (z[1]=='x' || z[1]=='X')
&& sqlite3Isxdigit(z[2])
){
u64 u = 0;
int i, k;
for(i=2; z[i]=='0'; i++){}
for(k=i; sqlite3Isxdigit(z[k]); k++){
u = u*16 + sqlite3HexToInt(z[k]);
}
memcpy(pOut, &u, 8);
return (z[k]==0 && k-i<=16) ? 0 : 1;
}else
#endif /* SQLITE_OMIT_HEX_INTEGER */
{
return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8);
}
}
/* /*
** If zNum represents an integer that will fit in 32-bits, then set ** If zNum represents an integer that will fit in 32-bits, then set
** *pValue to that integer and return true. Otherwise return false. ** *pValue to that integer and return true. Otherwise return false.
** **
** This routine accepts both decimal and hexadecimal notation for integers.
**
** Any non-numeric characters that following zNum are ignored. ** Any non-numeric characters that following zNum are ignored.
** This is different from sqlite3Atoi64() which requires the ** This is different from sqlite3Atoi64() which requires the
** input number to be zero-terminated. ** input number to be zero-terminated.
@ -583,7 +617,25 @@ int sqlite3GetInt32(const char *zNum, int *pValue){
}else if( zNum[0]=='+' ){ }else if( zNum[0]=='+' ){
zNum++; zNum++;
} }
while( zNum[0]=='0' ) zNum++; #ifndef SQLITE_OMIT_HEX_INTEGER
else if( zNum[0]=='0'
&& (zNum[1]=='x' || zNum[1]=='X')
&& sqlite3Isxdigit(zNum[2])
){
u32 u = 0;
zNum += 2;
while( zNum[0]=='0' ) zNum++;
for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){
u = u*16 + sqlite3HexToInt(zNum[i]);
}
if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){
memcpy(pValue, &u, 4);
return 1;
}else{
return 0;
}
}
#endif
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c; v = v*10 + c;
} }

View File

@ -3044,7 +3044,7 @@ case OP_Transaction: {
assert( p->bIsReader ); assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 ); assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
rc = SQLITE_READONLY; rc = SQLITE_READONLY;
goto abort_due_to_error; goto abort_due_to_error;
@ -3139,7 +3139,7 @@ case OP_ReadCookie: { /* out2-prerelease */
assert( pOp->p3<SQLITE_N_BTREE_META ); assert( pOp->p3<SQLITE_N_BTREE_META );
assert( iDb>=0 && iDb<db->nDb ); assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 ); assert( db->aDb[iDb].pBt!=0 );
assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
pOut->u.i = iMeta; pOut->u.i = iMeta;
@ -3160,7 +3160,7 @@ case OP_SetCookie: { /* in3 */
Db *pDb; Db *pDb;
assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 ); assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1]; pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 ); assert( pDb->pBt!=0 );
@ -3215,7 +3215,21 @@ case OP_SetCookie: { /* in3 */
** sequence of the index being opened. Otherwise, if P4 is an integer ** sequence of the index being opened. Otherwise, if P4 is an integer
** value, it is set to the number of columns in the table. ** value, it is set to the number of columns in the table.
** **
** See also OpenWrite. ** See also: OpenWrite, ReopenIdx
*/
/* Opcode: ReopenIdx P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3
**
** The ReopenIdx opcode works exactly like ReadOpen except that it first
** checks to see if the cursor on P1 is already open with a root page
** number of P2 and if it is this opcode becomes a no-op. In other words,
** if the cursor is already open, do not reopen it.
**
** The ReopenIdx opcode may only be used with P5==0 and with P4 being
** a P4_KEYINFO object. Furthermore, the P3 value must be the same as
** every other ReopenIdx or OpenRead for the same cursor number.
**
** See the OpenRead opcode documentation for additional information.
*/ */
/* Opcode: OpenWrite P1 P2 P3 P4 P5 /* Opcode: OpenWrite P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3 ** Synopsis: root=P2 iDb=P3
@ -3237,6 +3251,19 @@ case OP_SetCookie: { /* in3 */
** **
** See also OpenRead. ** See also OpenRead.
*/ */
case OP_ReopenIdx: {
VdbeCursor *pCur;
assert( pOp->p5==0 );
assert( pOp->p4type==P4_KEYINFO );
pCur = p->apCsr[pOp->p1];
if( pCur && pCur->pgnoRoot==pOp->p2 ){
assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */
break;
}
/* If the cursor is not currently open or is open on a different
** index, then fall through into OP_OpenRead to force a reopen */
}
case OP_OpenRead: case OP_OpenRead:
case OP_OpenWrite: { case OP_OpenWrite: {
int nField; int nField;
@ -3251,7 +3278,8 @@ case OP_OpenWrite: {
assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
assert( p->bIsReader ); assert( p->bIsReader );
assert( pOp->opcode==OP_OpenRead || p->readOnly==0 ); assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
|| p->readOnly==0 );
if( p->expired ){ if( p->expired ){
rc = SQLITE_ABORT; rc = SQLITE_ABORT;
@ -3263,7 +3291,7 @@ case OP_OpenWrite: {
p2 = pOp->p2; p2 = pOp->p2;
iDb = pOp->p3; iDb = pOp->p3;
assert( iDb>=0 && iDb<db->nDb ); assert( iDb>=0 && iDb<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); assert( DbMaskTest(p->btreeMask, iDb) );
pDb = &db->aDb[iDb]; pDb = &db->aDb[iDb];
pX = pDb->pBt; pX = pDb->pBt;
assert( pX!=0 ); assert( pX!=0 );
@ -3308,6 +3336,7 @@ case OP_OpenWrite: {
if( pCur==0 ) goto no_mem; if( pCur==0 ) goto no_mem;
pCur->nullRow = 1; pCur->nullRow = 1;
pCur->isOrdered = 1; pCur->isOrdered = 1;
pCur->pgnoRoot = p2;
rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
pCur->pKeyInfo = pKeyInfo; pCur->pKeyInfo = pKeyInfo;
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
@ -4905,7 +4934,7 @@ case OP_Destroy: { /* out2-prerelease */
}else{ }else{
iDb = pOp->p3; iDb = pOp->p3;
assert( iCnt==1 ); assert( iCnt==1 );
assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); assert( DbMaskTest(p->btreeMask, iDb) );
iMoved = 0; /* Not needed. Only to silence a warning. */ iMoved = 0; /* Not needed. Only to silence a warning. */
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int; pOut->flags = MEM_Int;
@ -4945,7 +4974,7 @@ case OP_Clear: {
nChange = 0; nChange = 0;
assert( p->readOnly==0 ); assert( p->readOnly==0 );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p2) );
rc = sqlite3BtreeClearTable( rc = sqlite3BtreeClearTable(
db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
); );
@ -5015,7 +5044,7 @@ case OP_CreateTable: { /* out2-prerelease */
pgno = 0; pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 ); assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1]; pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 ); assert( pDb->pBt!=0 );
@ -5180,7 +5209,7 @@ case OP_IntegrityCk: {
} }
aRoot[j] = 0; aRoot[j] = 0;
assert( pOp->p5<db->nDb ); assert( pOp->p5<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p5) );
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
(int)pnErr->u.i, &nErr); (int)pnErr->u.i, &nErr);
sqlite3DbFree(db, aRoot); sqlite3DbFree(db, aRoot);
@ -5840,7 +5869,7 @@ case OP_IncrVacuum: { /* jump */
Btree *pBt; Btree *pBt;
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 ); assert( p->readOnly==0 );
pBt = db->aDb[pOp->p1].pBt; pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt); rc = sqlite3BtreeIncrVacuum(pBt);
@ -5855,12 +5884,13 @@ case OP_IncrVacuum: { /* jump */
/* Opcode: Expire P1 * * * * /* Opcode: Expire P1 * * * *
** **
** Cause precompiled statements to become expired. An expired statement ** Cause precompiled statements to expire. When an expired statement
** fails with an error code of SQLITE_SCHEMA if it is ever executed ** is executed using sqlite3_step() it will either automatically
** (via sqlite3_step()). ** reprepare itself (if it was originally created using sqlite3_prepare_v2())
** or it will fail with SQLITE_SCHEMA.
** **
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
** then only the currently executing statement is affected. ** then only the currently executing statement is expired.
*/ */
case OP_Expire: { case OP_Expire: {
if( !pOp->p1 ){ if( !pOp->p1 ){
@ -5892,7 +5922,7 @@ case OP_TableLock: {
if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
int p1 = pOp->p1; int p1 = pOp->p1;
assert( p1>=0 && p1<db->nDb ); assert( p1>=0 && p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); assert( DbMaskTest(p->btreeMask, p1) );
assert( isWriteLock==0 || isWriteLock==1 ); assert( isWriteLock==0 || isWriteLock==1 );
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
if( (rc&0xFF)==SQLITE_LOCKED ){ if( (rc&0xFF)==SQLITE_LOCKED ){
@ -6342,7 +6372,7 @@ case OP_Init: { /* jump */
if( zTrace ){ if( zTrace ){
int i; int i;
for(i=0; i<db->nDb; i++){ for(i=0; i<db->nDb; i++){
if( (MASKBIT(i) & p->btreeMask)==0 ) continue; if( DbMaskTest(p->btreeMask, i)==0 ) continue;
sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
} }
} }

View File

@ -76,6 +76,7 @@ struct VdbeCursor {
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
Bool isTable:1; /* True if a table requiring integer keys */ Bool isTable:1; /* True if a table requiring integer keys */
Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
Pgno pgnoRoot; /* Root page of the open btree cursor */
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
i64 seqCount; /* Sequence counter */ i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */

View File

@ -1323,7 +1323,7 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
*/ */
int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt; Vdbe *v = (Vdbe*)pStmt;
return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
} }
/* /*

View File

@ -500,7 +500,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
pParse->aLabel = 0; pParse->aLabel = 0;
pParse->nLabel = 0; pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs; *pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || p->btreeMask==0 ); assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
} }
/* /*
@ -527,7 +527,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
assert( aOp && !p->db->mallocFailed ); assert( aOp && !p->db->mallocFailed );
/* Check that sqlite3VdbeUsesBtree() was not called on this VM */ /* Check that sqlite3VdbeUsesBtree() was not called on this VM */
assert( p->btreeMask==0 ); assert( DbMaskAllZero(p->btreeMask) );
resolveP2Values(p, pnMaxArg); resolveP2Values(p, pnMaxArg);
*pnOp = p->nOp; *pnOp = p->nOp;
@ -1112,9 +1112,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
void sqlite3VdbeUsesBtree(Vdbe *p, int i){ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 );
assert( i<(int)sizeof(p->btreeMask)*8 ); assert( i<(int)sizeof(p->btreeMask)*8 );
p->btreeMask |= ((yDbMask)1)<<i; DbMaskSet(p->btreeMask, i);
if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){
p->lockMask |= ((yDbMask)1)<<i; DbMaskSet(p->lockMask, i);
} }
} }
@ -1142,16 +1142,15 @@ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
*/ */
void sqlite3VdbeEnter(Vdbe *p){ void sqlite3VdbeEnter(Vdbe *p){
int i; int i;
yDbMask mask;
sqlite3 *db; sqlite3 *db;
Db *aDb; Db *aDb;
int nDb; int nDb;
if( p->lockMask==0 ) return; /* The common case */ if( DbMaskAllZero(p->lockMask) ) return; /* The common case */
db = p->db; db = p->db;
aDb = db->aDb; aDb = db->aDb;
nDb = db->nDb; nDb = db->nDb;
for(i=0, mask=1; i<nDb; i++, mask += mask){ for(i=0; i<nDb; i++){
if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){
sqlite3BtreeEnter(aDb[i].pBt); sqlite3BtreeEnter(aDb[i].pBt);
} }
} }
@ -1164,16 +1163,15 @@ void sqlite3VdbeEnter(Vdbe *p){
*/ */
void sqlite3VdbeLeave(Vdbe *p){ void sqlite3VdbeLeave(Vdbe *p){
int i; int i;
yDbMask mask;
sqlite3 *db; sqlite3 *db;
Db *aDb; Db *aDb;
int nDb; int nDb;
if( p->lockMask==0 ) return; /* The common case */ if( DbMaskAllZero(p->lockMask) ) return; /* The common case */
db = p->db; db = p->db;
aDb = db->aDb; aDb = db->aDb;
nDb = db->nDb; nDb = db->nDb;
for(i=0, mask=1; i<nDb; i++, mask += mask){ for(i=0; i<nDb; i++){
if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){
sqlite3BtreeLeave(aDb[i].pBt); sqlite3BtreeLeave(aDb[i].pBt);
} }
} }
@ -2144,7 +2142,7 @@ static void checkActiveVdbeCnt(sqlite3 *db){
int nRead = 0; int nRead = 0;
p = db->pVdbe; p = db->pVdbe;
while( p ){ while( p ){
if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){ if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){
cnt++; cnt++;
if( p->readOnly==0 ) nWrite++; if( p->readOnly==0 ) nWrite++;
if( p->bIsReader ) nRead++; if( p->bIsReader ) nRead++;

View File

@ -1959,7 +1959,7 @@ static void whereKeyStats(
iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol]; iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol];
iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
} }
aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1); aStat[1] = pIdx->aAvgEq[iCol];
if( iLower>=iUpper ){ if( iLower>=iUpper ){
iGap = 0; iGap = 0;
}else{ }else{
@ -3422,6 +3422,7 @@ static Bitmask codeOneLoopStart(
int iRetInit; /* Address of regReturn init */ int iRetInit; /* Address of regReturn init */
int untestedTerms = 0; /* Some terms not completely tested */ int untestedTerms = 0; /* Some terms not completely tested */
int ii; /* Loop counter */ int ii; /* Loop counter */
u16 wctrlFlags; /* Flags for sub-WHERE clause */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
Table *pTab = pTabItem->pTab; Table *pTab = pTabItem->pTab;
@ -3517,6 +3518,8 @@ static Bitmask codeOneLoopStart(
** eliminating duplicates from other WHERE clauses, the action for each ** eliminating duplicates from other WHERE clauses, the action for each
** sub-WHERE clause is to to invoke the main loop body as a subroutine. ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
*/ */
wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY;
for(ii=0; ii<pOrWc->nTerm; ii++){ for(ii=0; ii<pOrWc->nTerm; ii++){
WhereTerm *pOrTerm = &pOrWc->a[ii]; WhereTerm *pOrTerm = &pOrWc->a[ii];
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
@ -3529,8 +3532,7 @@ static Bitmask codeOneLoopStart(
} }
/* Loop through table entries that match term pOrTerm. */ /* Loop through table entries that match term pOrTerm. */
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY | wctrlFlags, iCovCur);
WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
assert( pSubWInfo || pParse->nErr || db->mallocFailed ); assert( pSubWInfo || pParse->nErr || db->mallocFailed );
if( pSubWInfo ){ if( pSubWInfo ){
WhereLoop *pSubLoop; WhereLoop *pSubLoop;
@ -3621,6 +3623,7 @@ static Bitmask codeOneLoopStart(
){ ){
assert( pSubWInfo->a[0].iIdxCur==iCovCur ); assert( pSubWInfo->a[0].iIdxCur==iCovCur );
pCov = pSubLoop->u.btree.pIndex; pCov = pSubLoop->u.btree.pIndex;
wctrlFlags |= WHERE_REOPEN_IDX;
}else{ }else{
pCov = 0; pCov = 0;
} }
@ -4227,6 +4230,16 @@ static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop){
} }
} }
/*
** Adjust the cost C by the costMult facter T. This only occurs if
** compiled with -DSQLITE_ENABLE_COSTMULT
*/
#ifdef SQLITE_ENABLE_COSTMULT
# define ApplyCostMultiplier(C,T) C += T
#else
# define ApplyCostMultiplier(C,T)
#endif
/* /*
** We have so far matched pBuilder->pNew->u.btree.nEq terms of the ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the
** index pIndex. Try to match one more. ** index pIndex. Try to match one more.
@ -4423,7 +4436,6 @@ static int whereLoopAddBtreeIndex(
}else{ }else{
rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
} }
assert( rc!=SQLITE_OK || nOut>0 );
if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */
if( nOut ){ if( nOut ){
@ -4455,6 +4467,7 @@ static int whereLoopAddBtreeIndex(
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
} }
ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult);
nOutUnadjusted = pNew->nOut; nOutUnadjusted = pNew->nOut;
pNew->rRun += nInMul + nIn; pNew->rRun += nInMul + nIn;
@ -4574,6 +4587,14 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
** Normally, nSeek is 1. nSeek values greater than 1 come about if the ** Normally, nSeek is 1. nSeek values greater than 1 come about if the
** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when ** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when
** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans.
**
** The estimated values (nRow, nVisit, nSeek) often contain a large amount
** of uncertainty. For this reason, scoring is designed to pick plans that
** "do the least harm" if the estimates are inaccurate. For example, a
** log(nRow) factor is omitted from a non-covering index scan in order to
** bias the scoring in favor of using an index, since the worst-case
** performance of using an index is far better than the worst-case performance
** of a full table scan.
*/ */
static int whereLoopAddBtree( static int whereLoopAddBtree(
WhereLoopBuilder *pBuilder, /* WHERE clause information */ WhereLoopBuilder *pBuilder, /* WHERE clause information */
@ -4661,6 +4682,7 @@ static int whereLoopAddBtree(
** approximately 7*N*log2(N) where N is the number of rows in ** approximately 7*N*log2(N) where N is the number of rows in
** the table being indexed. */ ** the table being indexed. */
pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) ); pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) );
ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
/* TUNING: Each index lookup yields 20 rows in the table. This /* TUNING: Each index lookup yields 20 rows in the table. This
** is more than the usual guess of 10 rows, since we have no way ** is more than the usual guess of 10 rows, since we have no way
** of knowning how selective the index will ultimately be. It would ** of knowning how selective the index will ultimately be. It would
@ -4702,6 +4724,7 @@ static int whereLoopAddBtree(
pNew->iSortIdx = b ? iSortIdx : 0; pNew->iSortIdx = b ? iSortIdx : 0;
/* TUNING: Cost of full table scan is (N*3.0). */ /* TUNING: Cost of full table scan is (N*3.0). */
pNew->rRun = rSize + 16; pNew->rRun = rSize + 16;
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
whereLoopOutputAdjust(pWC, pNew); whereLoopOutputAdjust(pWC, pNew);
rc = whereLoopInsert(pBuilder, pNew); rc = whereLoopInsert(pBuilder, pNew);
pNew->nOut = rSize; pNew->nOut = rSize;
@ -4737,7 +4760,7 @@ static int whereLoopAddBtree(
if( m!=0 ){ if( m!=0 ){
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16);
} }
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
whereLoopOutputAdjust(pWC, pNew); whereLoopOutputAdjust(pWC, pNew);
rc = whereLoopInsert(pBuilder, pNew); rc = whereLoopInsert(pBuilder, pNew);
pNew->nOut = rSize; pNew->nOut = rSize;
@ -6212,6 +6235,7 @@ WhereInfo *sqlite3WhereBegin(
pWInfo->aiCurOnePass[1] = iIndexCur; pWInfo->aiCurOnePass[1] = iIndexCur;
}else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
iIndexCur = iIdxCur; iIndexCur = iIdxCur;
if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx;
}else{ }else{
iIndexCur = pParse->nTab++; iIndexCur = pParse->nTab++;
} }

View File

@ -91,7 +91,7 @@ do_test analyze6-2.3 {
} {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}} } {0 0 0 {SEARCH TABLE t201 USING INTEGER PRIMARY KEY (rowid=?)}}
do_test analyze6-2.4 { do_test analyze6-2.4 {
execsql { execsql {
INSERT INTO t201 VALUES(1,2,3); INSERT INTO t201 VALUES(1,2,3),(2,3,4),(3,4,5);
ANALYZE t201; ANALYZE t201;
} }
eqp {SELECT * FROM t201 WHERE z=5} eqp {SELECT * FROM t201 WHERE z=5}

View File

@ -1019,6 +1019,73 @@ foreach {tn where res} {
do_eqp_test 22.2.$tn "SELECT * FROM t3 WHERE $where" $res do_eqp_test 22.2.$tn "SELECT * FROM t3 WHERE $where" $res
} }
proc int_to_char {i} {
set ret ""
set char [list a b c d e f g h i j]
foreach {div} {1000 100 10 1} {
append ret [lindex $char [expr ($i / $div) % 10]]
}
set ret
}
db func int_to_char int_to_char
do_execsql_test 23.0 {
CREATE TABLE t4(
a COLLATE nocase, b, c,
d, e, f,
PRIMARY KEY(c, b, a)
) WITHOUT ROWID;
CREATE INDEX i41 ON t4(e);
CREATE INDEX i42 ON t4(f);
WITH data(a, b, c, d, e, f) AS (
SELECT int_to_char(0), 'xyz', 'zyx', '*', 0, 0
UNION ALL
SELECT
int_to_char(f+1), b, c, d, (e+1) % 2, f+1
FROM data WHERE f<1024
)
INSERT INTO t4 SELECT a, b, c, d, e, f FROM data;
ANALYZE;
} {}
do_eqp_test 23.1 {
SELECT * FROM t4 WHERE
(e=1 AND b='xyz' AND c='zyx' AND a<'AEA') AND f<300
} {
0 0 0 {SEARCH TABLE t4 USING INDEX i41 (e=? AND c=? AND b=? AND a<?)}
}
do_eqp_test 23.2 {
SELECT * FROM t4 WHERE
(e=1 AND b='xyz' AND c='zyx' AND a<'JJJ') AND f<300
} {
0 0 0 {SEARCH TABLE t4 USING INDEX i42 (f<?)}
}
do_execsql_test 24.0 {
CREATE TABLE t5(c, d, b, e, a, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
WITH data(a, b, c, d, e) AS (
SELECT 'z', 'y', 0, 0, 0
UNION ALL
SELECT
a, CASE WHEN b='y' THEN 'n' ELSE 'y' END, c+1, e/250, e+1
FROM data
WHERE e<1000
)
INSERT INTO t5(a, b, c, d, e) SELECT * FROM data;
CREATE INDEX t5d ON t5(d);
CREATE INDEX t5e ON t5(e);
ANALYZE;
}
foreach {tn where eqp} {
1 "d=0 AND a='z' AND b='n' AND e<200" {/*t5d (d=? AND a=? AND b=?)*/}
2 "d=0 AND a='z' AND b='n' AND e<100" {/*t5e (e<?)*/}
3 "d=0 AND e<300" {/*t5d (d=?)*/}
4 "d=0 AND e<200" {/*t5e (e<?)*/}
} {
do_eqp_test 24.$tn "SeLeCt * FROM t5 WHERE $where" $eqp
}
finish_test finish_test

167
test/analyzeC.test Normal file
View File

@ -0,0 +1,167 @@
# 2014-07-22
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains automated tests used to verify that the text terms
# at the end of sqlite_stat1.stat are processed correctly.
#
# (1) "unordered" means that the index cannot be used for ORDER BY
# or for range queries
#
# (2) "sz=NNN" sets the relative size of the index entries
#
# (3) All other fields are silently ignored
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix analyzeC
# Baseline case. Range queries work OK. Indexes can be used for
# ORDER BY.
#
do_execsql_test 1.0 {
CREATE TABLE t1(a,b,c);
INSERT INTO t1(a,b,c)
VALUES(1,2,3),(7,8,9),(4,5,6),(10,11,12),(4,8,12),(1,11,111);
CREATE INDEX t1a ON t1(a);
CREATE INDEX t1b ON t1(b);
ANALYZE;
DELETE FROM sqlite_stat1;
INSERT INTO sqlite_stat1(tbl,idx,stat)
VALUES('t1','t1a','12345 2'),('t1','t1b','12345 4');
ANALYZE sqlite_master;
SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
} {4 5 6 # 7 8 9 # 4 8 12 #}
do_execsql_test 1.1 {
EXPLAIN QUERY PLAN
SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
} {/.* USING INDEX t1a .a>. AND a<...*/}
do_execsql_test 1.2 {
SELECT c FROM t1 ORDER BY a;
} {3 111 6 12 9 12}
do_execsql_test 1.3 {
EXPLAIN QUERY PLAN
SELECT c FROM t1 ORDER BY a;
} {/.*SCAN TABLE t1 USING INDEX t1a.*/}
do_execsql_test 1.3x {
EXPLAIN QUERY PLAN
SELECT c FROM t1 ORDER BY a;
} {~/.*B-TREE FOR ORDER BY.*/}
# Now mark the t1a index as "unordered". Range queries and ORDER BY no
# longer use the index, but equality queries do.
#
do_execsql_test 2.0 {
UPDATE sqlite_stat1 SET stat='12345 2 unordered' WHERE idx='t1a';
ANALYZE sqlite_master;
SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
} {4 5 6 # 7 8 9 # 4 8 12 #}
do_execsql_test 2.1 {
EXPLAIN QUERY PLAN
SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
} {~/.*USING INDEX.*/}
do_execsql_test 2.2 {
SELECT c FROM t1 ORDER BY a;
} {3 111 6 12 9 12}
do_execsql_test 2.3 {
EXPLAIN QUERY PLAN
SELECT c FROM t1 ORDER BY a;
} {~/.*USING INDEX.*/}
do_execsql_test 2.3x {
EXPLAIN QUERY PLAN
SELECT c FROM t1 ORDER BY a;
} {/.*B-TREE FOR ORDER BY.*/}
# Ignore extraneous text parameters in the sqlite_stat1.stat field.
#
do_execsql_test 3.0 {
UPDATE sqlite_stat1 SET stat='12345 2 whatever=5 unordered xyzzy=11'
WHERE idx='t1a';
ANALYZE sqlite_master;
SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
} {4 5 6 # 7 8 9 # 4 8 12 #}
do_execsql_test 3.1 {
EXPLAIN QUERY PLAN
SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
} {~/.*USING INDEX.*/}
do_execsql_test 3.2 {
SELECT c FROM t1 ORDER BY a;
} {3 111 6 12 9 12}
do_execsql_test 3.3 {
EXPLAIN QUERY PLAN
SELECT c FROM t1 ORDER BY a;
} {~/.*USING INDEX.*/}
do_execsql_test 3.3x {
EXPLAIN QUERY PLAN
SELECT c FROM t1 ORDER BY a;
} {/.*B-TREE FOR ORDER BY.*/}
# The sz=NNN parameter determines which index to scan
#
do_execsql_test 4.0 {
DROP INDEX t1a;
CREATE INDEX t1ab ON t1(a,b);
CREATE INDEX t1ca ON t1(c,a);
DELETE FROM sqlite_stat1;
INSERT INTO sqlite_stat1(tbl,idx,stat)
VALUES('t1','t1ab','12345 3 2 sz=10'),('t1','t1ca','12345 3 2 sz=20');
ANALYZE sqlite_master;
SELECT count(a) FROM t1;
} {6}
do_execsql_test 4.1 {
EXPLAIN QUERY PLAN
SELECT count(a) FROM t1;
} {/.*INDEX t1ab.*/}
do_execsql_test 4.2 {
DELETE FROM sqlite_stat1;
INSERT INTO sqlite_stat1(tbl,idx,stat)
VALUES('t1','t1ab','12345 3 2 sz=20'),('t1','t1ca','12345 3 2 sz=10');
ANALYZE sqlite_master;
SELECT count(a) FROM t1;
} {6}
do_execsql_test 4.3 {
EXPLAIN QUERY PLAN
SELECT count(a) FROM t1;
} {/.*INDEX t1ca.*/}
# The sz=NNN parameter works even if there is other extraneous text
# in the sqlite_stat1.stat column.
#
do_execsql_test 5.0 {
DELETE FROM sqlite_stat1;
INSERT INTO sqlite_stat1(tbl,idx,stat)
VALUES('t1','t1ab','12345 3 2 x=5 sz=10 y=10'),
('t1','t1ca','12345 3 2 whatever sz=20 junk');
ANALYZE sqlite_master;
SELECT count(a) FROM t1;
} {6}
do_execsql_test 5.1 {
EXPLAIN QUERY PLAN
SELECT count(a) FROM t1;
} {/.*INDEX t1ab.*/}
do_execsql_test 5.2 {
DELETE FROM sqlite_stat1;
INSERT INTO sqlite_stat1(tbl,idx,stat)
VALUES('t1','t1ca','12345 3 2 x=5 sz=10 y=10'),
('t1','t1ab','12345 3 2 whatever sz=20 junk');
ANALYZE sqlite_master;
SELECT count(a) FROM t1;
} {6}
do_execsql_test 5.3 {
EXPLAIN QUERY PLAN
SELECT count(a) FROM t1;
} {/.*INDEX t1ca.*/}
finish_test

View File

@ -144,4 +144,41 @@ do_test capi3d-3.99 {
sqlite3_stmt_busy 0 sqlite3_stmt_busy 0
} {0} } {0}
#--------------------------------------------------------------------------
# Test the sqlite3_stmt_busy() function with ROLLBACK statements.
#
reset_db
do_execsql_test capi3d-4.1 {
CREATE TABLE t4(x,y);
BEGIN;
}
do_test capi3d-4.2.1 {
breakpoint
set ::s1 [sqlite3_prepare_v2 db "ROLLBACK" -1 notused]
sqlite3_step $::s1
} {SQLITE_DONE}
do_test capi3d-4.2.2 {
sqlite3_stmt_busy $::s1
} {1}
do_catchsql_test capi3d-4.2.3 {
VACUUM
} {1 {cannot VACUUM - SQL statements in progress}}
do_test capi3d-4.2.4 {
sqlite3_reset $::s1
} {SQLITE_OK}
do_catchsql_test capi3d-4.2.5 {
VACUUM
} {0 {}}
do_test capi3d-4.2.6 {
sqlite3_finalize $::s1
} {SQLITE_OK}
finish_test finish_test

114
test/hexlit.test Normal file
View File

@ -0,0 +1,114 @@
# 2014-07-23
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements tests for hexadecimal literals
set testdir [file dirname $argv0]
source $testdir/tester.tcl
proc hexlit1 {tnum val ans} {
do_execsql_test hexlit-$tnum "SELECT $val" $ans
}
hexlit1 100 0x0 0
hexlit1 101 0x0000000000000000000000000000000000000000000001 1
hexlit1 102 0x2 2
hexlit1 103 0x4 4
hexlit1 104 0x8 8
hexlit1 105 0x00000000000000000000000000000000000000000000010 16
hexlit1 103 0x20 32
hexlit1 106 0x40 64
hexlit1 107 0x80 128
hexlit1 108 0x100 256
hexlit1 109 0x200 512
hexlit1 110 0X400 1024
hexlit1 111 0x800 2048
hexlit1 112 0x1000 4096
hexlit1 113 0x2000 8192
hexlit1 114 0x4000 16384
hexlit1 115 0x8000 32768
hexlit1 116 0x10000 65536
hexlit1 117 0x20000 131072
hexlit1 118 0x40000 262144
hexlit1 119 0x80000 524288
hexlit1 120 0x100000 1048576
hexlit1 121 0x200000 2097152
hexlit1 122 0x400000 4194304
hexlit1 123 0x800000 8388608
hexlit1 124 0x1000000 16777216
hexlit1 125 0x2000000 33554432
hexlit1 126 0x4000000 67108864
hexlit1 127 0x8000000 134217728
hexlit1 128 0x10000000 268435456
hexlit1 129 0x20000000 536870912
hexlit1 130 0x40000000 1073741824
hexlit1 131 0x80000000 2147483648
hexlit1 132 0x100000000 4294967296
hexlit1 133 0x200000000 8589934592
hexlit1 134 0x400000000 17179869184
hexlit1 135 0x800000000 34359738368
hexlit1 136 0x1000000000 68719476736
hexlit1 137 0x2000000000 137438953472
hexlit1 138 0x4000000000 274877906944
hexlit1 139 0x8000000000 549755813888
hexlit1 140 0x10000000000 1099511627776
hexlit1 141 0x20000000000 2199023255552
hexlit1 142 0x40000000000 4398046511104
hexlit1 143 0x80000000000 8796093022208
hexlit1 144 0x100000000000 17592186044416
hexlit1 145 0x200000000000 35184372088832
hexlit1 146 0x400000000000 70368744177664
hexlit1 147 0x800000000000 140737488355328
hexlit1 148 0x1000000000000 281474976710656
hexlit1 149 0x2000000000000 562949953421312
hexlit1 150 0x4000000000000 1125899906842624
hexlit1 151 0x8000000000000 2251799813685248
hexlit1 152 0x10000000000000 4503599627370496
hexlit1 153 0x20000000000000 9007199254740992
hexlit1 154 0x40000000000000 18014398509481984
hexlit1 155 0x80000000000000 36028797018963968
hexlit1 156 0x100000000000000 72057594037927936
hexlit1 157 0x200000000000000 144115188075855872
hexlit1 158 0x400000000000000 288230376151711744
hexlit1 159 0x800000000000000 576460752303423488
hexlit1 160 0X1000000000000000 1152921504606846976
hexlit1 161 0x2000000000000000 2305843009213693952
hexlit1 162 0X4000000000000000 4611686018427387904
hexlit1 163 0x8000000000000000 -9223372036854775808
hexlit1 164 0XFFFFFFFFFFFFFFFF -1
for {set n 1} {$n < 0x10} {incr n} {
hexlit1 200.$n.1 0X[format %03X $n] $n
hexlit1 200.$n.2 0x[format %03X $n] $n
hexlit1 200.$n.3 0X[format %03x $n] $n
hexlit1 200.$n.4 0x[format %03x $n] $n
}
# String literals that look like hex do not get cast or coerced.
#
do_execsql_test hexlit-300 {
CREATE TABLE t1(x INT, y REAL);
INSERT INTO t1 VALUES('1234','4567'),('0x1234','0x4567');
SELECT typeof(x), x, typeof(y), y, '#' FROM t1 ORDER BY rowid;
} {integer 1234 real 4567.0 # text 0x1234 text 0x4567 #}
do_execsql_test hexlit-301 {
SELECT CAST('0x1234' AS INTEGER);
} {0}
# Oversized hex literals are rejected
#
do_catchsql_test hexlist-400 {
SELECT 0x10000000000000000;
} {1 {hex literal too big: 0x10000000000000000}}
finish_test

View File

@ -36,6 +36,17 @@ do_test join-1.2 {
} }
} {1 2 3 2 3 4 3 4 5} } {1 2 3 2 3 4 3 4 5}
# A FROM clause of the form: "<table>, <table> ON <expr>" is not
# allowed by the SQLite syntax diagram, nor by any other SQL database
# engine that we are aware of. Nevertheless, historic versions of
# SQLite have allowed it. We need to continue to support it moving
# forward to prevent breakage of legacy applications. Though, we will
# not advertise it as being supported.
#
do_execsql_test join-1.2.1 {
SELECT t1.rowid, t2.rowid, '|' FROM t1, t2 ON t1.a=t2.b;
} {1 1 | 2 2 | 3 3 |}
do_test join-1.3 { do_test join-1.3 {
execsql2 { execsql2 {
SELECT * FROM t1 NATURAL JOIN t2; SELECT * FROM t1 NATURAL JOIN t2;

View File

@ -588,14 +588,17 @@ db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;}
# .separator STRING Change separator used by output mode and .import # .separator STRING Change separator used by output mode and .import
do_test shell1-3.22.1 { do_test shell1-3.22.1 {
catchcmd "test.db" ".separator" catchcmd "test.db" ".separator"
} {1 {Usage: .separator STRING}} } {1 {Usage: .separator SEPARATOR ?NEWLINE?}}
do_test shell1-3.22.2 { do_test shell1-3.22.2 {
catchcmd "test.db" ".separator FOO" catchcmd "test.db" ".separator FOO"
} {0 {}} } {0 {}}
do_test shell1-3.22.3 { do_test shell1-3.22.3 {
catchcmd "test.db" ".separator ABC XYZ"
} {0 {}}
do_test shell1-3.22.4 {
# too many arguments # too many arguments
catchcmd "test.db" ".separator FOO BAD" catchcmd "test.db" ".separator FOO BAD BAD2"
} {1 {Usage: .separator STRING}} } {1 {Usage: .separator SEPARATOR ?NEWLINE?}}
# .show Show the current values for various settings # .show Show the current values for various settings
do_test shell1-3.23.1 { do_test shell1-3.23.1 {

View File

@ -55,14 +55,17 @@ do_test shell5-1.1.3 {
# .separator STRING Change separator used by output mode and .import # .separator STRING Change separator used by output mode and .import
do_test shell5-1.2.1 { do_test shell5-1.2.1 {
catchcmd "test.db" ".separator" catchcmd "test.db" ".separator"
} {1 {Usage: .separator STRING}} } {1 {Usage: .separator SEPARATOR ?NEWLINE?}}
do_test shell5-1.2.2 { do_test shell5-1.2.2 {
catchcmd "test.db" ".separator FOO" catchcmd "test.db" ".separator ONE"
} {0 {}} } {0 {}}
do_test shell5-1.2.3 { do_test shell5-1.2.3 {
catchcmd "test.db" ".separator ONE TWO"
} {0 {}}
do_test shell5-1.2.4 {
# too many arguments # too many arguments
catchcmd "test.db" ".separator FOO BAD" catchcmd "test.db" ".separator ONE TWO THREE"
} {1 {Usage: .separator STRING}} } {1 {Usage: .separator SEPARATOR ?NEWLINE?}}
# separator should default to "|" # separator should default to "|"
do_test shell5-1.3.1 { do_test shell5-1.3.1 {

View File

@ -751,5 +751,13 @@ do_execsql_test where2-12.1 {
} {/.*SEARCH TABLE t12 AS b .*SEARCH TABLE t12 AS b .*/} } {/.*SEARCH TABLE t12 AS b .*SEARCH TABLE t12 AS b .*/}
} }
# Verify that all necessary OP_OpenRead opcodes occur in the OR optimization.
#
do_execsql_test where2-13.1 {
CREATE TABLE t13(a,b);
CREATE INDEX t13a ON t13(a);
INSERT INTO t13 VALUES(4,5);
SELECT * FROM t13 WHERE (1=2 AND a=3) OR a=4;
} {4 5}
finish_test finish_test

View File

@ -9,6 +9,8 @@
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
#include <unistd.h> #include <unistd.h>
#else
#include <io.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
@ -141,7 +143,7 @@ static void print_decode_line(
int val = aData[ofst]; int val = aData[ofst];
char zBuf[100]; char zBuf[100];
sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]); sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
i = strlen(zBuf); i = (int)strlen(zBuf);
for(j=1; j<4; j++){ for(j=1; j<4; j++){
if( j>=nByte ){ if( j>=nByte ){
sprintf(&zBuf[i], " "); sprintf(&zBuf[i], " ");
@ -149,7 +151,7 @@ static void print_decode_line(
sprintf(&zBuf[i], " %02x", aData[ofst+j]); sprintf(&zBuf[i], " %02x", aData[ofst+j]);
val = val*256 + aData[ofst+j]; val = val*256 + aData[ofst+j];
} }
i += strlen(&zBuf[i]); i += (int)strlen(&zBuf[i]);
} }
sprintf(&zBuf[i], " %9d", val); sprintf(&zBuf[i], " %9d", val);
printf("%s %s\n", zBuf, zMsg); printf("%s %s\n", zBuf, zMsg);
@ -190,14 +192,14 @@ static void print_db_header(void){
/* /*
** Describe cell content. ** Describe cell content.
*/ */
static int describeContent( static i64 describeContent(
unsigned char *a, /* Cell content */ unsigned char *a, /* Cell content */
int nLocal, /* Bytes in a[] */ i64 nLocal, /* Bytes in a[] */
char *zDesc /* Write description here */ char *zDesc /* Write description here */
){ ){
int nDesc = 0; i64 nDesc = 0;
int n, i, j; int n, j;
i64 x, v; i64 i, x, v;
const unsigned char *pData; const unsigned char *pData;
const unsigned char *pLimit; const unsigned char *pLimit;
char sep = ' '; char sep = ' ';
@ -237,15 +239,15 @@ static int describeContent(
}else if( x==9 ){ }else if( x==9 ){
sprintf(zDesc, "1"); sprintf(zDesc, "1");
}else if( x>=12 ){ }else if( x>=12 ){
int size = (x-12)/2; i64 size = (x-12)/2;
if( (x&1)==0 ){ if( (x&1)==0 ){
sprintf(zDesc, "blob(%d)", size); sprintf(zDesc, "blob(%lld)", size);
}else{ }else{
sprintf(zDesc, "txt(%d)", size); sprintf(zDesc, "txt(%lld)", size);
} }
pData += size; pData += size;
} }
j = strlen(zDesc); j = (int)strlen(zDesc);
zDesc += j; zDesc += j;
nDesc += j; nDesc += j;
} }
@ -256,11 +258,11 @@ static int describeContent(
** Compute the local payload size given the total payload size and ** Compute the local payload size given the total payload size and
** the page size. ** the page size.
*/ */
static int localPayload(i64 nPayload, char cType){ static i64 localPayload(i64 nPayload, char cType){
int maxLocal; i64 maxLocal;
int minLocal; i64 minLocal;
int surplus; i64 surplus;
int nLocal; i64 nLocal;
if( cType==13 ){ if( cType==13 ){
/* Table leaf */ /* Table leaf */
maxLocal = pagesize-35; maxLocal = pagesize-35;
@ -288,19 +290,19 @@ static int localPayload(i64 nPayload, char cType){
** **
** The return value is the local cell size. ** The return value is the local cell size.
*/ */
static int describeCell( static i64 describeCell(
unsigned char cType, /* Page type */ unsigned char cType, /* Page type */
unsigned char *a, /* Cell content */ unsigned char *a, /* Cell content */
int showCellContent, /* Show cell content if true */ int showCellContent, /* Show cell content if true */
char **pzDesc /* Store description here */ char **pzDesc /* Store description here */
){ ){
int i; int i;
int nDesc = 0; i64 nDesc = 0;
int n = 0; int n = 0;
int leftChild; int leftChild;
i64 nPayload; i64 nPayload;
i64 rowid; i64 rowid;
int nLocal; i64 nLocal;
static char zDesc[1000]; static char zDesc[1000];
i = 0; i = 0;
if( cType<=5 ){ if( cType<=5 ){
@ -373,13 +375,14 @@ static void decodeCell(
int szPgHdr, /* Size of the page header. 0 or 100 */ int szPgHdr, /* Size of the page header. 0 or 100 */
int ofst /* Cell begins at a[ofst] */ int ofst /* Cell begins at a[ofst] */
){ ){
int i, j, k; int i, j;
int leftChild; int leftChild;
i64 k;
i64 nPayload; i64 nPayload;
i64 rowid; i64 rowid;
i64 nHdr; i64 nHdr;
i64 iType; i64 iType;
int nLocal; i64 nLocal;
unsigned char *x = a + ofst; unsigned char *x = a + ofst;
unsigned char *end; unsigned char *end;
unsigned char cType = a[0]; unsigned char cType = a[0];
@ -400,10 +403,10 @@ static void decodeCell(
printBytes(a, x, i); printBytes(a, x, i);
nLocal = localPayload(nPayload, cType); nLocal = localPayload(nPayload, cType);
if( nLocal==nPayload ){ if( nLocal==nPayload ){
printf("payload-size: %d\n", (int)nPayload); printf("payload-size: %lld\n", nPayload);
}else{ }else{
printf("payload-size: %d (%d local, %d overflow)\n", printf("payload-size: %lld (%lld local, %lld overflow)\n",
(int)nPayload, nLocal, (int)(nPayload-nLocal)); nPayload, nLocal, nPayload-nLocal);
} }
x += i; x += i;
}else{ }else{
@ -452,7 +455,7 @@ static void decodeCell(
} }
printf("%s\n", zTypeName); printf("%s\n", zTypeName);
szCol[nCol] = sz; szCol[nCol] = sz;
ofstCol[nCol] = k; ofstCol[nCol] = (int)k;
typeCol[nCol] = (int)iType; typeCol[nCol] = (int)iType;
k += sz; k += sz;
nCol++; nCol++;
@ -506,7 +509,7 @@ static void decodeCell(
} }
if( j<nLocal ){ if( j<nLocal ){
printBytes(a, x+j, 0); printBytes(a, x+j, 0);
printf("... %d bytes of content ...\n", nLocal-j); printf("... %lld bytes of content ...\n", nLocal-j);
} }
if( nLocal<nPayload ){ if( nLocal<nPayload ){
printBytes(a, x+nLocal, 4); printBytes(a, x+nLocal, 4);
@ -585,17 +588,17 @@ static void decode_btree_page(
for(i=0; i<nCell; i++){ for(i=0; i<nCell; i++){
int cofst = iCellPtr + i*2; int cofst = iCellPtr + i*2;
char *zDesc; char *zDesc;
int n; i64 n;
cofst = a[cofst]*256 + a[cofst+1]; cofst = a[cofst]*256 + a[cofst+1];
n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc); n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc);
if( showMap ){ if( showMap ){
char zBuf[30]; char zBuf[30];
memset(&zMap[cofst], '*', n); memset(&zMap[cofst], '*', (size_t)n);
zMap[cofst] = '['; zMap[cofst] = '[';
zMap[cofst+n-1] = ']'; zMap[cofst+n-1] = ']';
sprintf(zBuf, "%d", i); sprintf(zBuf, "%d", i);
j = strlen(zBuf); j = (int)strlen(zBuf);
if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j); if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j);
} }
if( cellToDecode==(-2) ){ if( cellToDecode==(-2) ){
@ -692,7 +695,7 @@ static void page_usage_cell(
int n = 0; int n = 0;
i64 nPayload; i64 nPayload;
i64 rowid; i64 rowid;
int nLocal; i64 nLocal;
i = 0; i = 0;
if( cType<=5 ){ if( cType<=5 ){
a += 4; a += 4;
@ -893,12 +896,12 @@ static void page_usage_report(const char *zDbName){
** Try to figure out how every page in the database file is being used. ** Try to figure out how every page in the database file is being used.
*/ */
static void ptrmap_coverage_report(const char *zDbName){ static void ptrmap_coverage_report(const char *zDbName){
unsigned int pgno; int pgno;
unsigned char *aHdr; unsigned char *aHdr;
unsigned char *a; unsigned char *a;
int usable; int usable;
int perPage; int perPage;
unsigned int i; int i;
/* Avoid the pathological case */ /* Avoid the pathological case */
if( mxPage<1 ){ if( mxPage<1 ){

View File

@ -6,7 +6,13 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#if !defined(_MSC_VER)
#include <unistd.h> #include <unistd.h>
#else
#include <io.h>
#endif
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -172,7 +178,7 @@ static void print_decode_line(
int val = aData[ofst]; int val = aData[ofst];
char zBuf[100]; char zBuf[100];
sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]); sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
i = strlen(zBuf); i = (int)strlen(zBuf);
for(j=1; j<4; j++){ for(j=1; j<4; j++){
if( j>=nByte ){ if( j>=nByte ){
sprintf(&zBuf[i], " "); sprintf(&zBuf[i], " ");
@ -180,7 +186,7 @@ static void print_decode_line(
sprintf(&zBuf[i], " %02x", aData[ofst+j]); sprintf(&zBuf[i], " %02x", aData[ofst+j]);
val = val*256 + aData[ofst+j]; val = val*256 + aData[ofst+j];
} }
i += strlen(&zBuf[i]); i += (int)strlen(&zBuf[i]);
} }
if( asHex ){ if( asHex ){
sprintf(&zBuf[i], " 0x%08x", val); sprintf(&zBuf[i], " 0x%08x", val);
@ -273,14 +279,14 @@ static void print_wal_header(Cksum *pCksum){
/* /*
** Describe cell content. ** Describe cell content.
*/ */
static int describeContent( static i64 describeContent(
unsigned char *a, /* Cell content */ unsigned char *a, /* Cell content */
int nLocal, /* Bytes in a[] */ i64 nLocal, /* Bytes in a[] */
char *zDesc /* Write description here */ char *zDesc /* Write description here */
){ ){
int nDesc = 0; int nDesc = 0;
int n, i, j; int n, j;
i64 x, v; i64 i, x, v;
const unsigned char *pData; const unsigned char *pData;
const unsigned char *pLimit; const unsigned char *pLimit;
char sep = ' '; char sep = ' ';
@ -320,15 +326,15 @@ static int describeContent(
}else if( x==9 ){ }else if( x==9 ){
sprintf(zDesc, "1"); sprintf(zDesc, "1");
}else if( x>=12 ){ }else if( x>=12 ){
int size = (x-12)/2; i64 size = (x-12)/2;
if( (x&1)==0 ){ if( (x&1)==0 ){
sprintf(zDesc, "blob(%d)", size); sprintf(zDesc, "blob(%lld)", size);
}else{ }else{
sprintf(zDesc, "txt(%d)", size); sprintf(zDesc, "txt(%lld)", size);
} }
pData += size; pData += size;
} }
j = strlen(zDesc); j = (int)strlen(zDesc);
zDesc += j; zDesc += j;
nDesc += j; nDesc += j;
} }
@ -339,11 +345,11 @@ static int describeContent(
** Compute the local payload size given the total payload size and ** Compute the local payload size given the total payload size and
** the page size. ** the page size.
*/ */
static int localPayload(i64 nPayload, char cType){ static i64 localPayload(i64 nPayload, char cType){
int maxLocal; i64 maxLocal;
int minLocal; i64 minLocal;
int surplus; i64 surplus;
int nLocal; i64 nLocal;
if( cType==13 ){ if( cType==13 ){
/* Table leaf */ /* Table leaf */
maxLocal = pagesize-35; maxLocal = pagesize-35;
@ -370,19 +376,19 @@ static int localPayload(i64 nPayload, char cType){
** **
** The return value is the local cell size. ** The return value is the local cell size.
*/ */
static int describeCell( static i64 describeCell(
unsigned char cType, /* Page type */ unsigned char cType, /* Page type */
unsigned char *a, /* Cell content */ unsigned char *a, /* Cell content */
int showCellContent, /* Show cell content if true */ int showCellContent, /* Show cell content if true */
char **pzDesc /* Store description here */ char **pzDesc /* Store description here */
){ ){
int i; int i;
int nDesc = 0; i64 nDesc = 0;
int n = 0; int n = 0;
int leftChild; int leftChild;
i64 nPayload; i64 nPayload;
i64 rowid; i64 rowid;
int nLocal; i64 nLocal;
static char zDesc[1000]; static char zDesc[1000];
i = 0; i = 0;
if( cType<=5 ){ if( cType<=5 ){
@ -479,17 +485,17 @@ static void decode_btree_page(
for(i=0; i<nCell; i++){ for(i=0; i<nCell; i++){
int cofst = iCellPtr + i*2; int cofst = iCellPtr + i*2;
char *zDesc; char *zDesc;
int n; i64 n;
cofst = a[cofst]*256 + a[cofst+1]; cofst = a[cofst]*256 + a[cofst+1];
n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc); n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc);
if( showMap ){ if( showMap ){
char zBuf[30]; char zBuf[30];
memset(&zMap[cofst], '*', n); memset(&zMap[cofst], '*', (size_t)n);
zMap[cofst] = '['; zMap[cofst] = '[';
zMap[cofst+n-1] = ']'; zMap[cofst+n-1] = ']';
sprintf(zBuf, "%d", i); sprintf(zBuf, "%d", i);
j = strlen(zBuf); j = (int)strlen(zBuf);
if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j); if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j);
} }
printf(" %03x: cell[%d] %s\n", cofst, i, zDesc); printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);