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:
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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) */
|
||||||
|
@ -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);
|
||||||
|
@ -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
14
main.mk
@ -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
|
|
||||||
|
80
manifest
80
manifest
@ -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
|
||||||
|
@ -1 +1 @@
|
|||||||
a5d94eaba6aa12ff16d2a0af2fc752bcdb461877
|
a9db017eabdefafcda87c497e8bafa07002ac0fe
|
@ -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;
|
||||||
|
34
src/build.c
34
src/build.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/expr.c
11
src/expr.c
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
159
src/shell.c
159
src/shell.c
@ -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));
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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]=='.' ){
|
||||||
|
58
src/util.c
58
src/util.c
@ -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;
|
||||||
}
|
}
|
||||||
|
64
src/vdbe.c
64
src/vdbe.c
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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++;
|
||||||
|
34
src/where.c
34
src/where.c
@ -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++;
|
||||||
}
|
}
|
||||||
|
@ -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}
|
||||||
|
@ -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
167
test/analyzeC.test
Normal 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
|
@ -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
114
test/hexlit.test
Normal 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
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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 ){
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user