Compare commits
124 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 14faa061fd | |||
| 8443533178 | |||
| 14cee38be8 | |||
| 75ab50ce8f | |||
| 3104c4d6f4 | |||
| 10c0a2a7c9 | |||
| 609d5846ba | |||
| 05accd2216 | |||
| ad975d539e | |||
| c6daa01c05 | |||
| 15af62acff | |||
| e5f06fdc87 | |||
| 97a7e5e68c | |||
| b283a0cde9 | |||
| ae20690e2c | |||
| b1ec87afdb | |||
| 1de86ca17f | |||
| 23ee893752 | |||
| 7694e06461 | |||
| 83b74f29c5 | |||
| b7a208686a | |||
| 2e8bfb67d4 | |||
| 26f7977c53 | |||
| f602a16123 | |||
| 191dd06195 | |||
| 94d49697b5 | |||
| cdce61e133 | |||
| 333f80562b | |||
| 132dde5cdf | |||
| 1a55dedf7b | |||
| 1aea63032a | |||
| 46f0035b48 | |||
| bff4b6367c | |||
| 58e3812988 | |||
| beccf1d16f | |||
| a6dddd9bde | |||
| f9986d90d1 | |||
| 303a094466 | |||
| 2bb5f4478e | |||
| 977cbe78b3 | |||
| ee65eea4af | |||
| f89157653a | |||
| eacd29d484 | |||
| 5313f2e12e | |||
| 497116007e | |||
| fc26f7cfed | |||
| 7111c93c40 | |||
| f1b5ff73cb | |||
| 8f2ce91462 | |||
| 7512cb47e8 | |||
| 07d683fdbc | |||
| 0cb64edc95 | |||
| 4926fec967 | |||
| 02d436b1f6 | |||
| c5896b5cbb | |||
| 77fac879d2 | |||
| 02267cc213 | |||
| 74f598b677 | |||
| 741c2772db | |||
| 2160ca5f8d | |||
| e11003d5ba | |||
| 8366ddf242 | |||
| 752b102e9b | |||
| 745be369c7 | |||
| 70b8d6bbcc | |||
| 6f07734349 | |||
| f3c57ff54c | |||
| 926957f0a6 | |||
| 0cedb963a3 | |||
| 9cdd401d37 | |||
| 4f2c822cc5 | |||
| 0e188e1d1e | |||
| ad2d5baf1f | |||
| 244b9d6ec6 | |||
| affa855c94 | |||
| bea119cdeb | |||
| 3c19469ca2 | |||
| c310db39ff | |||
| 4f0010b1bc | |||
| 7cc84c2cdd | |||
| 8679fbabaa | |||
| 8f3b137fa6 | |||
| 08de4f7933 | |||
| ba26faa33f | |||
| bfc7a8bb01 | |||
| 53801efcdf | |||
| 11b264019c | |||
| dca595c4a3 | |||
| 38b3dde00e | |||
| 45c3c66385 | |||
| be5000d6bf | |||
| 3b42be9178 | |||
| f878e6e1a7 | |||
| 40dc357a01 | |||
| ed06a131da | |||
| 18a1549322 | |||
| c0d10c8d4f | |||
| 60de73e83d | |||
| aed11f2072 | |||
| 868f0398e4 | |||
| 1c715f67b9 | |||
| cca6698408 | |||
| 73a6bb5851 | |||
| 48dcf2b60b | |||
| bdeb125741 | |||
| de613c6d4a | |||
| 455684a036 | |||
| 49e1125b69 | |||
| ae0c84bd9e | |||
| 5fd0c12049 | |||
| 51b55a3ee6 | |||
| 1810f22809 | |||
| 1fe36bb8a8 | |||
| 1293120345 | |||
| 5daed673b8 | |||
| 899c5c9d34 | |||
| 0784f8a460 | |||
| 076b6468f5 | |||
| f6661a8896 | |||
| 2779989110 | |||
| 5996a77987 | |||
| 6cc16fc070 | |||
| e787cbbe2a | |||
| 710b33b999 |
+3
-3
@@ -1032,7 +1032,7 @@ FTS5_SRC = \
|
||||
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
|
||||
cp $(TOP)/ext/fts5/fts5parse.y .
|
||||
rm -f fts5parse.h
|
||||
./lemon $(OPTS) fts5parse.y
|
||||
./lemon$(BEXE) $(OPTS) fts5parse.y
|
||||
|
||||
fts5parse.h: fts5parse.c
|
||||
|
||||
@@ -1164,8 +1164,9 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
|
||||
# symbols that do not begin with "sqlite3_". It is run as part of the
|
||||
# releasetest.tcl script.
|
||||
#
|
||||
VALIDIDS=' sqlite3(changeset|changegroup|session)?_'
|
||||
checksymbols: sqlite3.lo
|
||||
nm -g --defined-only sqlite3.o | egrep -v ' sqlite3(changeset|session)?_' ; test $$? -ne 0
|
||||
nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0
|
||||
echo '0 errors out of 1 tests'
|
||||
|
||||
# Build the amalgamation-autoconf package. The amalamgation-tarball target builds
|
||||
@@ -1228,7 +1229,6 @@ clean:
|
||||
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
|
||||
rm -f mkkeywordhash$(BEXE) keywordhash.h
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf quota2a quota2b quota2c
|
||||
rm -rf tsrc .target_source
|
||||
rm -f tclsqlite3$(TEXE)
|
||||
rm -f testfixture$(TEXE) test.db
|
||||
|
||||
+2
-5
@@ -1882,7 +1882,7 @@ fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
|
||||
rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c
|
||||
|
||||
sqlite3session.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR)
|
||||
sqlite3session.lo: $(TOP)\ext\session\sqlite3session.c $(HDR) $(EXTHDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c
|
||||
|
||||
# FTS5 things
|
||||
@@ -2075,9 +2075,6 @@ clean:
|
||||
del /Q notasharedlib.* 2>NUL
|
||||
-rmdir /Q/S .deps 2>NUL
|
||||
-rmdir /Q/S .libs 2>NUL
|
||||
-rmdir /Q/S quota2a 2>NUL
|
||||
-rmdir /Q/S quota2b 2>NUL
|
||||
-rmdir /Q/S quota2c 2>NUL
|
||||
-rmdir /Q/S tsrc 2>NUL
|
||||
del /Q .target_source 2>NUL
|
||||
del /Q tclsqlite3.exe 2>NUL
|
||||
@@ -2089,7 +2086,7 @@ clean:
|
||||
del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
|
||||
del /Q sqlite3.c sqlite3-*.c 2>NUL
|
||||
del /Q sqlite3rc.h 2>NUL
|
||||
del /Q shell.c sqlite3ext.h 2>NUL
|
||||
del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
|
||||
del /Q sqlite-*-output.vsix 2>NUL
|
||||
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL
|
||||
|
||||
@@ -458,7 +458,7 @@ static int testTokenizerNext(
|
||||
if( pCsr->iLangid & 0x00000001 ){
|
||||
for(i=0; i<nToken; i++) pCsr->aBuffer[i] = pToken[i];
|
||||
}else{
|
||||
for(i=0; i<nToken; i++) pCsr->aBuffer[i] = testTolower(pToken[i]);
|
||||
for(i=0; i<nToken; i++) pCsr->aBuffer[i] = (char)testTolower(pToken[i]);
|
||||
}
|
||||
pCsr->iToken++;
|
||||
pCsr->iInput = (int)(p - pCsr->aInput);
|
||||
|
||||
@@ -398,8 +398,8 @@ static void showSegmentStats(sqlite3 *db, const char *zTab){
|
||||
if( sqlite3_step(pStmt)==SQLITE_ROW
|
||||
&& (nLeaf = sqlite3_column_int(pStmt, 0))>0
|
||||
){
|
||||
nIdx = sqlite3_column_int(pStmt, 5);
|
||||
sqlite3_int64 sz;
|
||||
nIdx = sqlite3_column_int(pStmt, 5);
|
||||
printf("For level %d:\n", i);
|
||||
printf(" Number of indexes...................... %9d\n", nIdx);
|
||||
printf(" Number of leaf segments................ %9d\n", nLeaf);
|
||||
|
||||
@@ -345,11 +345,11 @@ int sqlite3Fts5HashWrite(
|
||||
if( pHash->eDetail==FTS5_DETAIL_FULL ){
|
||||
pPtr[p->nData++] = 0x01;
|
||||
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
|
||||
p->iCol = iCol;
|
||||
p->iCol = (i16)iCol;
|
||||
p->iPos = 0;
|
||||
}else{
|
||||
bNew = 1;
|
||||
p->iCol = iPos = iCol;
|
||||
p->iCol = (i16)(iPos = iCol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3244,7 +3244,7 @@ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||
if( aiCol==aiColEnd ) goto setoutputs_col_out;
|
||||
}
|
||||
if( *aiCol==iPrev ){
|
||||
*aOut++ = (iPrev - iPrevOut) + 2;
|
||||
*aOut++ = (u8)((iPrev - iPrevOut) + 2);
|
||||
iPrevOut = iPrev;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -354,15 +354,17 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
|
||||
** http://www.icu-project.org/userguide/posix.html#case_mappings
|
||||
*/
|
||||
static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
|
||||
const UChar *zInput;
|
||||
UChar *zOutput = 0;
|
||||
int nInput;
|
||||
int nOut;
|
||||
const UChar *zInput; /* Pointer to input string */
|
||||
UChar *zOutput = 0; /* Pointer to output buffer */
|
||||
int nInput; /* Size of utf-16 input string in bytes */
|
||||
int nOut; /* Size of output buffer in bytes */
|
||||
int cnt;
|
||||
int bToUpper; /* True for toupper(), false for tolower() */
|
||||
UErrorCode status;
|
||||
const char *zLocale = 0;
|
||||
|
||||
assert(nArg==1 || nArg==2);
|
||||
bToUpper = (sqlite3_user_data(p)!=0);
|
||||
if( nArg==2 ){
|
||||
zLocale = (const char *)sqlite3_value_text(apArg[1]);
|
||||
}
|
||||
@@ -386,19 +388,23 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
|
||||
}
|
||||
zOutput = zNew;
|
||||
status = U_ZERO_ERROR;
|
||||
if( sqlite3_user_data(p) ){
|
||||
if( bToUpper ){
|
||||
nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
|
||||
}else{
|
||||
nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
|
||||
}
|
||||
if( !U_SUCCESS(status) ){
|
||||
if( status==U_BUFFER_OVERFLOW_ERROR ) continue;
|
||||
icuFunctionError(p,
|
||||
sqlite3_user_data(p) ? "u_strToUpper" : "u_strToLower", status);
|
||||
return;
|
||||
|
||||
if( U_SUCCESS(status) ){
|
||||
sqlite3_result_text16(p, zOutput, nOut, xFree);
|
||||
}else if( status==U_BUFFER_OVERFLOW_ERROR ){
|
||||
assert( cnt==0 );
|
||||
continue;
|
||||
}else{
|
||||
icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
sqlite3_result_text16(p, zOutput, nOut, xFree);
|
||||
assert( 0 ); /* Unreachable */
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+4
-4
@@ -625,10 +625,10 @@ static int amatchLoadOneRule(
|
||||
}else{
|
||||
memset(pRule, 0, sizeof(*pRule));
|
||||
pRule->zFrom = &pRule->zTo[nTo+1];
|
||||
pRule->nFrom = nFrom;
|
||||
pRule->nFrom = (amatch_len)nFrom;
|
||||
memcpy(pRule->zFrom, zFrom, nFrom+1);
|
||||
memcpy(pRule->zTo, zTo, nTo+1);
|
||||
pRule->nTo = nTo;
|
||||
pRule->nTo = (amatch_len)nTo;
|
||||
pRule->rCost = rCost;
|
||||
pRule->iLang = (int)iLang;
|
||||
}
|
||||
@@ -1081,7 +1081,7 @@ static void amatchAddWord(
|
||||
pWord->rCost = rCost;
|
||||
pWord->iSeq = pCur->nWord++;
|
||||
amatchWriteCost(pWord);
|
||||
pWord->nMatch = nMatch;
|
||||
pWord->nMatch = (short)nMatch;
|
||||
pWord->pNext = pCur->pAllWords;
|
||||
pCur->pAllWords = pWord;
|
||||
pWord->sCost.zKey = pWord->zCost;
|
||||
@@ -1162,7 +1162,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
|
||||
#endif
|
||||
nWord = (int)strlen(pWord->zWord+2);
|
||||
if( nWord+20>nBuf ){
|
||||
nBuf = nWord+100;
|
||||
nBuf = (char)(nWord+100);
|
||||
zBuf = sqlite3_realloc(zBuf, nBuf);
|
||||
if( zBuf==0 ) return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
+2
-2
@@ -344,10 +344,10 @@ static int fuzzerLoadOneRule(
|
||||
memset(pRule, 0, sizeof(*pRule));
|
||||
pRule->zFrom = pRule->zTo;
|
||||
pRule->zFrom += nTo + 1;
|
||||
pRule->nFrom = nFrom;
|
||||
pRule->nFrom = (fuzzer_len)nFrom;
|
||||
memcpy(pRule->zFrom, zFrom, nFrom+1);
|
||||
memcpy(pRule->zTo, zTo, nTo+1);
|
||||
pRule->nTo = nTo;
|
||||
pRule->nTo = (fuzzer_len)nTo;
|
||||
pRule->rCost = nCost;
|
||||
pRule->iRuleset = (int)iRuleset;
|
||||
}
|
||||
|
||||
+5
-5
@@ -136,7 +136,7 @@ struct ReCompiled {
|
||||
static void re_add_state(ReStateSet *pSet, int newState){
|
||||
unsigned i;
|
||||
for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return;
|
||||
pSet->aState[pSet->nState++] = newState;
|
||||
pSet->aState[pSet->nState++] = (ReStateNumber)newState;
|
||||
}
|
||||
|
||||
/* Extract the next unicode character from *pzIn and return it. Advance
|
||||
@@ -358,7 +358,7 @@ static int re_insert(ReCompiled *p, int iBefore, int op, int arg){
|
||||
p->aArg[i] = p->aArg[i-1];
|
||||
}
|
||||
p->nState++;
|
||||
p->aOp[iBefore] = op;
|
||||
p->aOp[iBefore] = (char)op;
|
||||
p->aArg[iBefore] = arg;
|
||||
return iBefore;
|
||||
}
|
||||
@@ -677,12 +677,12 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
|
||||
for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
|
||||
unsigned x = pRe->aArg[i];
|
||||
if( x<=127 ){
|
||||
pRe->zInit[j++] = x;
|
||||
pRe->zInit[j++] = (unsigned char)x;
|
||||
}else if( x<=0xfff ){
|
||||
pRe->zInit[j++] = 0xc0 | (x>>6);
|
||||
pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
|
||||
pRe->zInit[j++] = 0x80 | (x&0x3f);
|
||||
}else if( x<=0xffff ){
|
||||
pRe->zInit[j++] = 0xd0 | (x>>12);
|
||||
pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
|
||||
pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
|
||||
pRe->zInit[j++] = 0x80 | (x&0x3f);
|
||||
}else{
|
||||
|
||||
+10
-10
@@ -390,7 +390,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
||||
|
||||
/* Special processing if either string is empty */
|
||||
if( nA==0 ){
|
||||
cBprev = dc;
|
||||
cBprev = (char)dc;
|
||||
for(xB=res=0; (cB = zB[xB])!=0; xB++){
|
||||
res += insertOrDeleteCost(cBprev, cB, zB[xB+1])/FINAL_INS_COST_DIV;
|
||||
cBprev = cB;
|
||||
@@ -398,7 +398,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
||||
return res;
|
||||
}
|
||||
if( nB==0 ){
|
||||
cAprev = dc;
|
||||
cAprev = (char)dc;
|
||||
for(xA=res=0; (cA = zA[xA])!=0; xA++){
|
||||
res += insertOrDeleteCost(cAprev, cA, zA[xA+1]);
|
||||
cAprev = cA;
|
||||
@@ -420,8 +420,8 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
||||
|
||||
/* Compute the Wagner edit distance */
|
||||
m[0] = 0;
|
||||
cx[0] = dc;
|
||||
cBprev = dc;
|
||||
cx[0] = (char)dc;
|
||||
cBprev = (char)dc;
|
||||
for(xB=1; xB<=nB; xB++){
|
||||
cBnext = zB[xB];
|
||||
cB = zB[xB-1];
|
||||
@@ -429,7 +429,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
||||
m[xB] = m[xB-1] + insertOrDeleteCost(cBprev, cB, cBnext);
|
||||
cBprev = cB;
|
||||
}
|
||||
cAprev = dc;
|
||||
cAprev = (char)dc;
|
||||
for(xA=1; xA<=nA; xA++){
|
||||
int lastA = (xA==nA);
|
||||
cA = zA[xA-1];
|
||||
@@ -476,7 +476,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
|
||||
d = m[xB];
|
||||
dc = cx[xB];
|
||||
m[xB] = totalCost;
|
||||
cx[xB] = ncx;
|
||||
cx[xB] = (char)ncx;
|
||||
cBprev = cB;
|
||||
}
|
||||
cAprev = cA;
|
||||
@@ -711,9 +711,9 @@ static int editDist3ConfigLoad(
|
||||
if( nExtra<0 ) nExtra = 0;
|
||||
pCost = sqlite3_malloc64( sizeof(*pCost) + nExtra );
|
||||
if( pCost==0 ){ rc = SQLITE_NOMEM; break; }
|
||||
pCost->nFrom = nFrom;
|
||||
pCost->nTo = nTo;
|
||||
pCost->iCost = iCost;
|
||||
pCost->nFrom = (u8)nFrom;
|
||||
pCost->nTo = (u8)nTo;
|
||||
pCost->iCost = (u16)iCost;
|
||||
memcpy(pCost->a, zFrom, nFrom);
|
||||
memcpy(pCost->a + nFrom, zTo, nTo);
|
||||
pCost->pNext = pLang->pCost;
|
||||
@@ -1616,7 +1616,7 @@ static unsigned char *transliterate(const unsigned char *zIn, int nIn){
|
||||
zIn += sz;
|
||||
nIn -= sz;
|
||||
if( c<=127 ){
|
||||
zOut[nOut++] = c;
|
||||
zOut[nOut++] = (unsigned char)c;
|
||||
}else{
|
||||
int xTop, xBtm, x;
|
||||
xTop = sizeof(translit)/sizeof(translit[0]) - 1;
|
||||
|
||||
+40
-16
@@ -24,12 +24,22 @@
|
||||
*/
|
||||
void usage(const char *zArgv0){
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-step NSTEP] TARGET-DB RBU-DB\n"
|
||||
"Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n"
|
||||
"\n"
|
||||
" Argument RBU-DB must be an RBU database containing an update suitable for\n"
|
||||
" target database TARGET-DB. If NSTEP is set to less than or equal to zero\n"
|
||||
" (the default value), this program attempts to apply the entire update to\n"
|
||||
" the target database.\n"
|
||||
"Where options are:\n"
|
||||
"\n"
|
||||
" -step NSTEP\n"
|
||||
" -vacuum\n"
|
||||
"\n"
|
||||
" If the -vacuum switch is not present, argument RBU-DB must be an RBU\n"
|
||||
" database containing an update suitable for target database TARGET-DB.\n"
|
||||
" Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n"
|
||||
" RBU, and RBU-DB is used as the state database for the vacuum (refer to\n"
|
||||
" API documentation for details).\n"
|
||||
"\n"
|
||||
" If NSTEP is set to less than or equal to zero (the default value), this \n"
|
||||
" program attempts to perform the entire update or vacuum operation before\n"
|
||||
" exiting\n"
|
||||
"\n"
|
||||
" If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
|
||||
" to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
|
||||
@@ -69,29 +79,43 @@ int main(int argc, char **argv){
|
||||
char *zErrmsg; /* Error message, if any */
|
||||
sqlite3rbu *pRbu; /* RBU handle */
|
||||
int nStep = 0; /* Maximum number of step() calls */
|
||||
int bVacuum = 0;
|
||||
int rc;
|
||||
sqlite3_int64 nProgress = 0;
|
||||
int nArg = argc-2;
|
||||
|
||||
/* Process command line arguments. Following this block local variables
|
||||
** zTarget, zRbu and nStep are all set. */
|
||||
if( argc==5 ){
|
||||
size_t nArg1 = strlen(argv[1]);
|
||||
if( nArg1>5 || nArg1<2 || memcmp("-step", argv[1], nArg1) ) usage(argv[0]);
|
||||
nStep = atoi(argv[2]);
|
||||
}else if( argc!=3 ){
|
||||
usage(argv[0]);
|
||||
if( argc<3 ) usage(argv[0]);
|
||||
for(i=1; i<nArg; i++){
|
||||
const char *zArg = argv[i];
|
||||
int nArg = strlen(zArg);
|
||||
if( nArg>1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){
|
||||
bVacuum = 1;
|
||||
}else if( nArg>1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i<nArg-1 ){
|
||||
i++;
|
||||
nStep = atoi(argv[i]);
|
||||
}else{
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
zTarget = argv[argc-2];
|
||||
zRbu = argv[argc-1];
|
||||
|
||||
report_default_vfs();
|
||||
|
||||
/* Open an RBU handle. If nStep is less than or equal to zero, call
|
||||
/* Open an RBU handle. A vacuum handle if -vacuum was specified, or a
|
||||
** regular RBU update handle otherwise. */
|
||||
if( bVacuum ){
|
||||
pRbu = sqlite3rbu_vacuum(zTarget, zRbu);
|
||||
}else{
|
||||
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
|
||||
}
|
||||
report_rbu_vfs(pRbu);
|
||||
|
||||
/* If nStep is less than or equal to zero, call
|
||||
** sqlite3rbu_step() until either the RBU has been completely applied
|
||||
** or an error occurs. Or, if nStep is greater than zero, call
|
||||
** sqlite3rbu_step() a maximum of nStep times. */
|
||||
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
|
||||
report_rbu_vfs(pRbu);
|
||||
for(i=0; (nStep<=0 || i<nStep) && sqlite3rbu_step(pRbu)==SQLITE_OK; i++);
|
||||
nProgress = sqlite3rbu_progress(pRbu);
|
||||
rc = sqlite3rbu_close(pRbu, &zErrmsg);
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# 2016 April 20
|
||||
#
|
||||
# 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 fault injection tests for RBU vacuum operations.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set ::testprefix rbufault3
|
||||
|
||||
foreach {fault errlist} {
|
||||
oom-* {
|
||||
{1 SQLITE_NOMEM}
|
||||
{1 SQLITE_IOERR_NOMEM}
|
||||
{1 {SQLITE_NOMEM - out of memory}}
|
||||
}
|
||||
|
||||
ioerr-* {
|
||||
{1 {SQLITE_IOERR - disk I/O error}}
|
||||
{1 SQLITE_IOERR}
|
||||
{1 SQLITE_IOERR_WRITE}
|
||||
{1 SQLITE_IOERR_FSYNC}
|
||||
{1 SQLITE_IOERR_READ}
|
||||
{1 {SQLITE_IOERR - unable to open database: test.db2}}
|
||||
{1 {SQLITE_ERROR - unable to open database: test.db2}}
|
||||
{1 {SQLITE_ERROR - SQL logic error or missing database}}
|
||||
}
|
||||
|
||||
cantopen* {
|
||||
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
|
||||
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
|
||||
{1 {SQLITE_CANTOPEN - unable to open database file}}
|
||||
{1 SQLITE_CANTOPEN}
|
||||
}
|
||||
|
||||
} {
|
||||
|
||||
reset_db
|
||||
do_execsql_test 0 {
|
||||
CREATE TABLE target(x UNIQUE, y, z, PRIMARY KEY(y));
|
||||
INSERT INTO target VALUES(1, 2, 3);
|
||||
INSERT INTO target VALUES(4, 5, 6);
|
||||
INSERT INTO target VALUES(7, 8, 9);
|
||||
CREATE INDEX i1 ON target(z);
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 1 -faults $fault -prep {
|
||||
faultsim_restore_and_reopen
|
||||
forcedelete test.db2
|
||||
} -body {
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
rbu close
|
||||
} -test {
|
||||
eval [list faultsim_test_result {0 SQLITE_DONE} {*}$::errlist]
|
||||
}
|
||||
|
||||
do_faultsim_test 2 -faults $fault -prep {
|
||||
faultsim_restore_and_reopen
|
||||
forcedelete test.db2
|
||||
} -body {
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
rbu step
|
||||
rbu close
|
||||
} -test {
|
||||
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
|
||||
}
|
||||
|
||||
forcedelete test.db2
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
rbu step
|
||||
rbu close
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 3 -faults $fault -prep {
|
||||
faultsim_restore_and_reopen
|
||||
forcedelete test.db2
|
||||
} -body {
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
rbu step
|
||||
rbu close
|
||||
} -test {
|
||||
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
# 2016 April 15
|
||||
#
|
||||
# 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 tests for the RBU module. More specifically, it
|
||||
# contains tests to ensure that the sqlite3rbu_vacuum() API works as
|
||||
# expected.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbuvacuum
|
||||
|
||||
proc do_rbu_vacuum_test {tn step} {
|
||||
uplevel [list do_test $tn.1 {
|
||||
if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||
while 1 {
|
||||
if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
if {$step==1} { rbu close }
|
||||
}
|
||||
rbu close
|
||||
} {SQLITE_DONE}]
|
||||
|
||||
uplevel [list do_execsql_test $tn.2 {
|
||||
PRAGMA integrity_check
|
||||
} ok]
|
||||
}
|
||||
|
||||
foreach step {0 1} {
|
||||
|
||||
set ::testprefix rbuvacuum-step=$step
|
||||
reset_db
|
||||
|
||||
# Simplest possible vacuum.
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA page_size = 1024;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
INSERT INTO t1 VALUES(4, 5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8, 9);
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_rbu_vacuum_test 1.1 $step
|
||||
|
||||
# A vacuum that actually reclaims space.
|
||||
do_execsql_test 1.2.1 {
|
||||
INSERT INTO t1 VALUES(8, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(9, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(10, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(11, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(12, randomblob(900), randomblob(900));
|
||||
PRAGMA page_count;
|
||||
} {12}
|
||||
do_execsql_test 1.2.2 {
|
||||
DELETE FROM t1 WHERE rowid BETWEEN 8 AND 11;
|
||||
PRAGMA page_count;
|
||||
} {12}
|
||||
do_rbu_vacuum_test 1.2.3 $step
|
||||
do_execsql_test 1.2.4 {
|
||||
PRAGMA page_count;
|
||||
} {3}
|
||||
|
||||
# Add an index to the table.
|
||||
do_execsql_test 1.3.1 {
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
INSERT INTO t1 VALUES(13, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(14, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(15, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(16, randomblob(900), randomblob(900));
|
||||
PRAGMA page_count;
|
||||
} {18}
|
||||
do_execsql_test 1.3.2 {
|
||||
DELETE FROM t1 WHERE rowid BETWEEN 12 AND 15;
|
||||
PRAGMA page_count;
|
||||
} {18}
|
||||
do_rbu_vacuum_test 1.3.3 $step
|
||||
do_execsql_test 1.3.4 {
|
||||
PRAGMA page_count;
|
||||
} {5}
|
||||
|
||||
# WITHOUT ROWID table.
|
||||
do_execsql_test 1.4.1 {
|
||||
CREATE TABLE t2(a, b, c, PRIMARY KEY(a, b)) WITHOUT ROWID;
|
||||
|
||||
INSERT INTO t2 VALUES(randomblob(900), 1, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 2, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 3, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 4, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 6, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 7, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 8, randomblob(900));
|
||||
|
||||
DELETE FROM t2 WHERE b BETWEEN 2 AND 7;
|
||||
PRAGMA page_count;
|
||||
} {20}
|
||||
do_rbu_vacuum_test 1.4.2 $step
|
||||
do_execsql_test 1.4.3 {
|
||||
PRAGMA page_count;
|
||||
} {10}
|
||||
|
||||
# WITHOUT ROWID table with an index.
|
||||
do_execsql_test 1.4.1 {
|
||||
CREATE INDEX t2c ON t2(c);
|
||||
|
||||
INSERT INTO t2 VALUES(randomblob(900), 9, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 10, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 11, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 12, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 13, randomblob(900));
|
||||
|
||||
DELETE FROM t2 WHERE b BETWEEN 8 AND 12;
|
||||
PRAGMA page_count;
|
||||
} {35}
|
||||
do_rbu_vacuum_test 1.4.2 $step
|
||||
do_execsql_test 1.4.3 {
|
||||
PRAGMA page_count;
|
||||
} {15}
|
||||
do_execsql_test 1.4.4 {
|
||||
VACUUM;
|
||||
PRAGMA page_count;
|
||||
} {15}
|
||||
|
||||
do_execsql_test 1.5.1 {
|
||||
CREATE TABLE t3(a, b, c);
|
||||
INSERT INTO t3 VALUES('a', 'b', 'c');
|
||||
INSERT INTO t3 VALUES('d', 'e', 'f');
|
||||
INSERT INTO t3 VALUES('g', 'h', 'i');
|
||||
}
|
||||
do_rbu_vacuum_test 1.5.2 $step
|
||||
do_execsql_test 1.5.3 {
|
||||
SELECT * FROM t3
|
||||
} {a b c d e f g h i}
|
||||
do_execsql_test 1.5.4 {
|
||||
CREATE INDEX t3a ON t3(a);
|
||||
CREATE INDEX t3b ON t3(b);
|
||||
CREATE INDEX t3c ON t3(c);
|
||||
INSERT INTO t3 VALUES('j', 'k', 'l');
|
||||
DELETE FROM t3 WHERE a = 'g';
|
||||
}
|
||||
do_rbu_vacuum_test 1.5.5 $step
|
||||
do_execsql_test 1.5.6 {
|
||||
SELECT rowid, * FROM t3 ORDER BY b
|
||||
} {1 a b c 2 d e f 4 j k l}
|
||||
|
||||
do_execsql_test 1.6.1 {
|
||||
CREATE TABLE t4(a PRIMARY KEY, b, c);
|
||||
INSERT INTO t4 VALUES('a', 'b', 'c');
|
||||
INSERT INTO t4 VALUES('d', 'e', 'f');
|
||||
INSERT INTO t4 VALUES('g', 'h', 'i');
|
||||
}
|
||||
do_rbu_vacuum_test 1.6.2 $step
|
||||
do_execsql_test 1.6.3 {
|
||||
SELECT * FROM t4
|
||||
} {a b c d e f g h i}
|
||||
do_execsql_test 1.6.4 {
|
||||
CREATE INDEX t4a ON t4(a);
|
||||
CREATE INDEX t4b ON t4(b);
|
||||
CREATE INDEX t4c ON t4(c);
|
||||
|
||||
INSERT INTO t4 VALUES('j', 'k', 'l');
|
||||
DELETE FROM t4 WHERE a='g';
|
||||
}
|
||||
do_rbu_vacuum_test 1.6.5 $step
|
||||
do_execsql_test 1.6.6 {
|
||||
SELECT * FROM t4 ORDER BY b
|
||||
} {a b c d e f j k l}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 1.7.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
INSERT INTO t1 VALUES(NULL, 'one');
|
||||
INSERT INTO t1 VALUES(NULL, 'two');
|
||||
DELETE FROM t1 WHERE a=2;
|
||||
INSERT INTO t1 VALUES(NULL, 'three');
|
||||
INSERT INTO t1 VALUES(NULL, 'four');
|
||||
DELETE FROM t1 WHERE a=4;
|
||||
INSERT INTO t1 VALUES(NULL, 'five');
|
||||
INSERT INTO t1 VALUES(NULL, 'six');
|
||||
DELETE FROM t1 WHERE a=6;
|
||||
SELECT * FROM t1;
|
||||
} {1 one 3 three 5 five}
|
||||
do_rbu_vacuum_test 1.7.1 $step
|
||||
do_execsql_test 1.7.2 {
|
||||
INSERT INTO t1 VALUES(NULL, 'seven');
|
||||
SELECT * FROM t1;
|
||||
} {1 one 3 three 5 five 7 seven}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 1.8.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(NULL, 'one');
|
||||
INSERT INTO t1 VALUES(NULL, 'two');
|
||||
INSERT INTO t1 VALUES(NULL, 'three');
|
||||
INSERT INTO t1 VALUES(NULL, 'four');
|
||||
INSERT INTO t1 VALUES(NULL, 'five');
|
||||
INSERT INTO t1 VALUES(NULL, 'six');
|
||||
ANALYZE;
|
||||
SELECT * FROM sqlite_stat1;
|
||||
} {t1 i1 {6 1}}
|
||||
do_rbu_vacuum_test 1.8.1 $step
|
||||
do_execsql_test 1.7.2 {
|
||||
SELECT * FROM sqlite_stat1;
|
||||
} {t1 i1 {6 1}}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 1.9.0 {
|
||||
PRAGMA page_size = 8192;
|
||||
PRAGMA auto_vacuum = 2;
|
||||
PRAGMA user_version = 412;
|
||||
PRAGMA application_id = 413;
|
||||
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(NULL, 'one');
|
||||
INSERT INTO t1 VALUES(NULL, 'two');
|
||||
INSERT INTO t1 VALUES(NULL, 'three');
|
||||
INSERT INTO t1 VALUES(NULL, 'four');
|
||||
INSERT INTO t1 VALUES(NULL, 'five');
|
||||
INSERT INTO t1 VALUES(NULL, 'six');
|
||||
|
||||
PRAGMA main.page_size;
|
||||
PRAGMA main.auto_vacuum;
|
||||
PRAGMA main.user_version;
|
||||
PRAGMA main.application_id;
|
||||
} {8192 2 412 413}
|
||||
|
||||
do_rbu_vacuum_test 1.9.1 $step
|
||||
do_execsql_test 1.9.2 {
|
||||
PRAGMA main.page_size;
|
||||
PRAGMA main.auto_vacuum;
|
||||
PRAGMA main.user_version;
|
||||
PRAGMA main.application_id;
|
||||
} {8192 2 412 413}
|
||||
|
||||
# Vacuum a database with a large sqlite_master table.
|
||||
#
|
||||
reset_db
|
||||
do_test 1.10.1 {
|
||||
for {set i 1} {$i < 50} {incr i} {
|
||||
execsql "PRAGMA page_size = 1024"
|
||||
execsql "CREATE TABLE t$i (a, b, c, PRIMARY KEY(a, b));"
|
||||
execsql "
|
||||
INSERT INTO t$i VALUES(1, 2, 3);
|
||||
INSERT INTO t$i VALUES(4, 5, 6);
|
||||
"
|
||||
}
|
||||
} {}
|
||||
do_rbu_vacuum_test 1.10.2 $step
|
||||
|
||||
# Database with empty tables.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 1.11.1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t4 VALUES(1, 2);
|
||||
}
|
||||
do_rbu_vacuum_test 1.11.2 $step
|
||||
do_execsql_test 1.11.3 {
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
SELECT * FROM t3;
|
||||
SELECT * FROM t4;
|
||||
} {1 2}
|
||||
reset_db
|
||||
do_execsql_test 1.12.1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
do_rbu_vacuum_test 1.12.2 $step
|
||||
do_execsql_test 1.12.3 {
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
SELECT * FROM t3;
|
||||
SELECT * FROM t4;
|
||||
} {1 2}
|
||||
}
|
||||
set ::testprefix rbuvacuum
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test some error cases:
|
||||
#
|
||||
# 2.1.* the db being vacuumed being in wal mode already.
|
||||
# 2.2.* database modified mid vacuum.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
PRAGMA journal_mode = wal;
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
} wal
|
||||
do_test 2.1.1 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
rbu step
|
||||
} {SQLITE_ERROR}
|
||||
do_test 2.1.2 {
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_ERROR - cannot vacuum wal mode database}}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.2.0 {
|
||||
CREATE TABLE tx(a PRIMARY KEY, b BLOB);
|
||||
INSERT INTO tx VALUES(1, randomblob(900));
|
||||
INSERT INTO tx SELECT a+1, randomblob(900) FROM tx;
|
||||
INSERT INTO tx SELECT a+2, randomblob(900) FROM tx;
|
||||
INSERT INTO tx SELECT a+4, randomblob(900) FROM tx;
|
||||
INSERT INTO tx SELECT a+8, randomblob(900) FROM tx;
|
||||
}
|
||||
db_save_and_close
|
||||
for {set i 1} 1 {incr i} {
|
||||
db_restore_and_reopen
|
||||
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
for {set step 0} {$step<$i} {incr step} { rbu step }
|
||||
rbu close
|
||||
if {[file exists test.db-wal]} break
|
||||
|
||||
execsql { INSERT INTO tx VALUES(20, 20) }
|
||||
|
||||
do_test 2.2.$i.1 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
rbu step
|
||||
} {SQLITE_BUSY}
|
||||
do_test 2.2.$i.2 {
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_BUSY - database modified during rbu vacuum}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that a database that uses custom collation sequences can be RBU
|
||||
# vacuumed.
|
||||
#
|
||||
reset_db
|
||||
forcedelete state.db
|
||||
proc noop {args} {}
|
||||
proc length_cmp {x y} {
|
||||
set n1 [string length $x]
|
||||
set n2 [string length $y]
|
||||
return [expr $n1 - $n2]
|
||||
}
|
||||
sqlite3_create_collation_v2 db length length_cmp noop
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1, 'i');
|
||||
INSERT INTO t1 VALUES(2, 'iiii');
|
||||
INSERT INTO t1 VALUES(3, 'ii');
|
||||
INSERT INTO t1 VALUES(4, 'iii');
|
||||
SELECT a FROM t1 ORDER BY b COLLATE length;
|
||||
} {1 3 4 2}
|
||||
do_execsql_test 3.1 {
|
||||
CREATE INDEX i1 ON t1(b COLLATE length);
|
||||
}
|
||||
|
||||
do_test 3.2 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_ERROR - no such collation sequence: length}}
|
||||
|
||||
do_test 3.3 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
set db1 [rbu db 0]
|
||||
sqlite3_create_collation_v2 $db1 length length_cmp noop
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_ERROR - no such collation sequence: length}}
|
||||
|
||||
do_test 3.4 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
set db1 [rbu db 1]
|
||||
sqlite3_create_collation_v2 $db1 length length_cmp noop
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_ERROR - no such collation sequence: length}}
|
||||
|
||||
do_test 3.5 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
set db1 [rbu db 0]
|
||||
set db2 [rbu db 1]
|
||||
|
||||
sqlite3_create_collation_v2 $db1 length length_cmp noop
|
||||
sqlite3_create_collation_v2 $db2 length length_cmp noop
|
||||
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
|
||||
catch { db close }
|
||||
finish_test
|
||||
|
||||
+579
-179
File diff suppressed because it is too large
Load Diff
@@ -314,6 +314,38 @@ sqlite3rbu *sqlite3rbu_open(
|
||||
const char *zState
|
||||
);
|
||||
|
||||
/*
|
||||
** Open an RBU handle to perform an RBU vacuum on database file zTarget.
|
||||
** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
|
||||
** that it can be suspended and resumed like an RBU update.
|
||||
**
|
||||
** The second argument to this function, which may not be NULL, identifies
|
||||
** a database in which to store the state of the RBU vacuum operation if
|
||||
** it is suspended. The first time sqlite3rbu_vacuum() is called, to start
|
||||
** an RBU vacuum operation, the state database should either not exist or
|
||||
** be empty (contain no tables). If an RBU vacuum is suspended by calling
|
||||
** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
|
||||
** returned SQLITE_DONE, the vacuum state is stored in the state database.
|
||||
** The vacuum can be resumed by calling this function to open a new RBU
|
||||
** handle specifying the same target and state databases.
|
||||
**
|
||||
** This function does not delete the state database after an RBU vacuum
|
||||
** is completed, even if it created it. However, if the call to
|
||||
** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
|
||||
** of the state tables within the state database are zeroed. This way,
|
||||
** the next call to sqlite3rbu_vacuum() opens a handle that starts a
|
||||
** new RBU vacuum operation.
|
||||
**
|
||||
** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
|
||||
** describing the sqlite3rbu_create_vfs() API function below for
|
||||
** a description of the complications associated with using RBU with
|
||||
** zipvfs databases.
|
||||
*/
|
||||
sqlite3rbu *sqlite3rbu_vacuum(
|
||||
const char *zTarget,
|
||||
const char *zState
|
||||
);
|
||||
|
||||
/*
|
||||
** Internally, each RBU connection uses a separate SQLite database
|
||||
** connection to access the target and rbu update databases. This
|
||||
|
||||
+49
-2
@@ -20,8 +20,9 @@
|
||||
#include <tcl.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* From main.c (apparently...) */
|
||||
/* From main.c */
|
||||
extern const char *sqlite3ErrName(int);
|
||||
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
|
||||
|
||||
void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){
|
||||
Tcl_Interp *interp = (Tcl_Interp*)sqlite3_user_data(pCtx);
|
||||
@@ -66,7 +67,8 @@ static int test_sqlite3rbu_cmd(
|
||||
{"create_rbu_delta", 2, ""}, /* 2 */
|
||||
{"savestate", 2, ""}, /* 3 */
|
||||
{"dbMain_eval", 3, "SQL"}, /* 4 */
|
||||
{"bp_progress", 2, ""}, /* 5 */
|
||||
{"bp_progress", 2, ""}, /* 5 */
|
||||
{"db", 3, "RBU"}, /* 6 */
|
||||
{0,0,0}
|
||||
};
|
||||
int iCmd;
|
||||
@@ -149,6 +151,22 @@ static int test_sqlite3rbu_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: /* db */ {
|
||||
int bArg;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[2], &bArg) ){
|
||||
ret = TCL_ERROR;
|
||||
}else{
|
||||
char zBuf[50];
|
||||
sqlite3 *db = sqlite3rbu_db(pRbu, bArg);
|
||||
if( sqlite3TestMakePointerStr(interp, zBuf, (void*)db) ){
|
||||
ret = TCL_ERROR;
|
||||
}else{
|
||||
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: /* seems unlikely */
|
||||
assert( !"cannot happen" );
|
||||
break;
|
||||
@@ -187,6 +205,34 @@ static int test_sqlite3rbu(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: sqlite3rbu_vacuum CMD <target-db> <state-db>
|
||||
*/
|
||||
static int test_sqlite3rbu_vacuum(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3rbu *pRbu = 0;
|
||||
const char *zCmd;
|
||||
const char *zTarget;
|
||||
const char *zStateDb = 0;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB STATE-DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zCmd = Tcl_GetString(objv[1]);
|
||||
zTarget = Tcl_GetString(objv[2]);
|
||||
zStateDb = Tcl_GetString(objv[3]);
|
||||
|
||||
pRbu = sqlite3rbu_vacuum(zTarget, zStateDb);
|
||||
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
|
||||
*/
|
||||
@@ -274,6 +320,7 @@ int SqliteRbu_Init(Tcl_Interp *interp){
|
||||
Tcl_ObjCmdProc *xProc;
|
||||
} aObjCmd[] = {
|
||||
{ "sqlite3rbu", test_sqlite3rbu },
|
||||
{ "sqlite3rbu_vacuum", test_sqlite3rbu_vacuum },
|
||||
{ "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs },
|
||||
{ "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs },
|
||||
{ "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test },
|
||||
|
||||
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
|
||||
set testprefix sessionfault
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
set testprefix sessionfault2
|
||||
|
||||
do_execsql_test 1.0.0 {
|
||||
|
||||
@@ -592,14 +592,19 @@ static int sessionChangeEqual(
|
||||
int iCol; /* Used to iterate through table columns */
|
||||
|
||||
for(iCol=0; iCol<pTab->nCol; iCol++){
|
||||
int n1 = sessionSerialLen(a1);
|
||||
int n2 = sessionSerialLen(a2);
|
||||
if( pTab->abPK[iCol] ){
|
||||
int n1 = sessionSerialLen(a1);
|
||||
int n2 = sessionSerialLen(a2);
|
||||
|
||||
if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
|
||||
return 0;
|
||||
if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
|
||||
return 0;
|
||||
}
|
||||
a1 += n1;
|
||||
a2 += n2;
|
||||
}else{
|
||||
if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
|
||||
if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
|
||||
}
|
||||
if( pTab->abPK[iCol] || bLeftPkOnly==0 ) a1 += n1;
|
||||
if( pTab->abPK[iCol] || bRightPkOnly==0 ) a2 += n2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -935,9 +940,9 @@ static int sessionTableInfo(
|
||||
int nDbCol = 0;
|
||||
int nThis;
|
||||
int i;
|
||||
u8 *pAlloc;
|
||||
u8 *pAlloc = 0;
|
||||
char **azCol = 0;
|
||||
u8 *abPK;
|
||||
u8 *abPK = 0;
|
||||
|
||||
assert( pazCol && pabPK );
|
||||
|
||||
@@ -1593,9 +1598,9 @@ static void sessionDeleteTable(SessionTable *pList){
|
||||
pNext = pTab->pNext;
|
||||
for(i=0; i<pTab->nChange; i++){
|
||||
SessionChange *p;
|
||||
SessionChange *pNext;
|
||||
for(p=pTab->apChange[i]; p; p=pNext){
|
||||
pNext = p->pNext;
|
||||
SessionChange *pNextChange;
|
||||
for(p=pTab->apChange[i]; p; p=pNextChange){
|
||||
pNextChange = p->pNext;
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
@@ -2882,7 +2887,6 @@ static int sessionChangesetNext(
|
||||
** modified fields are present in the new.* record. The old.* record
|
||||
** is currently completely empty. This block shifts the PK fields from
|
||||
** new.* to old.*, to accommodate the code that reads these arrays. */
|
||||
int i;
|
||||
for(i=0; i<p->nCol; i++){
|
||||
assert( p->apValue[i]==0 );
|
||||
assert( p->abPK[i]==0 || p->apValue[i+p->nCol] );
|
||||
@@ -3655,7 +3659,7 @@ static int sessionConflictHandler(
|
||||
void *pCtx, /* First argument for conflict handler */
|
||||
int *pbReplace /* OUT: Set to true if PK row is found */
|
||||
){
|
||||
int res; /* Value returned by conflict handler */
|
||||
int res = 0; /* Value returned by conflict handler */
|
||||
int rc;
|
||||
int nCol;
|
||||
int op;
|
||||
|
||||
@@ -314,7 +314,8 @@ static void test_append_value(Tcl_Obj *pList, sqlite3_value *pVal){
|
||||
pObj = Tcl_NewStringObj(z, n);
|
||||
break;
|
||||
}
|
||||
case SQLITE_BLOB:
|
||||
default:
|
||||
assert( sqlite3_value_type(pVal)==SQLITE_BLOB );
|
||||
Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("b", 1));
|
||||
pObj = Tcl_NewByteArrayObj(
|
||||
sqlite3_value_blob(pVal),
|
||||
@@ -871,7 +872,6 @@ static int test_sqlite3session_foreach(
|
||||
|
||||
pOld = Tcl_NewObj();
|
||||
if( op!=SQLITE_INSERT ){
|
||||
int i;
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3_value *pVal;
|
||||
sqlite3changeset_old(pIter, i, &pVal);
|
||||
@@ -880,7 +880,6 @@ static int test_sqlite3session_foreach(
|
||||
}
|
||||
pNew = Tcl_NewObj();
|
||||
if( op!=SQLITE_DELETE ){
|
||||
int i;
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3_value *pVal;
|
||||
sqlite3changeset_new(pIter, i, &pVal);
|
||||
|
||||
@@ -905,7 +905,6 @@ clean:
|
||||
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
|
||||
rm -f $(PUBLISH)
|
||||
rm -f *.da *.bb *.bbg gmon.out
|
||||
rm -rf quota2a quota2b quota2c
|
||||
rm -rf tsrc target_source
|
||||
rm -f testloadext.dll libtestloadext.so
|
||||
rm -f amalgamation-testfixture amalgamation-testfixture.exe
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
C Add\sanother\sOOM\stest\sto\sthis\sbranch.
|
||||
D 2016-03-31T15:08:10.284
|
||||
F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449
|
||||
C Fix\san\salmost\sentirely\sharmless\sbuffer\soverread\sin\sthe\ssessions\smodule.
|
||||
D 2016-04-29T10:13:22.999
|
||||
F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998
|
||||
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
@@ -81,7 +81,7 @@ F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e
|
||||
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
|
||||
F ext/fts3/fts3_test.c 11e36437b0f3f2266acea5b4787f615e4337a237
|
||||
F ext/fts3/fts3_test.c a940cf104d545ad1abf926956ce65db2aa5af0cf
|
||||
F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
|
||||
F ext/fts3/fts3_tokenizer.c 3cf21cd2212db17a88d4ef7da0fd8a80275979a1
|
||||
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
@@ -91,7 +91,7 @@ F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
|
||||
F ext/fts3/fts3_write.c c3863f23b6b4623c8b9d5cf31c12ce4469f78ca9
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3view.c 5d78b668f4e9598af9147f8999632599fb0d9dd5
|
||||
F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677
|
||||
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
|
||||
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
|
||||
@@ -103,8 +103,8 @@ F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f
|
||||
F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337
|
||||
F ext/fts5/fts5_index.c fdd82bb421a5d1e64d004acb43f4dd9970c8d2b3
|
||||
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
|
||||
F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97
|
||||
F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55
|
||||
F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c
|
||||
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
||||
@@ -201,28 +201,28 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
|
||||
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
|
||||
F ext/icu/icu.c 4bdf4c5daedabcd8e6eb6e6a377657f7b978f9f7
|
||||
F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/misc/amatch.c a1a8f66c29d40bd71b075546ddeddb477b17a2bb
|
||||
F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234
|
||||
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c b9c88d5c3b6ecd8c731ffdd7f5b3d902857f8c96
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
||||
F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
|
||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c 598bbc45516227701558becdd38f4e6fe8e97cc2
|
||||
F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be
|
||||
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rbu/rbu.c ba3983dceffa0938532e79142f391737513de023
|
||||
F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4
|
||||
F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1
|
||||
F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d
|
||||
F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
|
||||
@@ -243,12 +243,14 @@ F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
|
||||
F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091
|
||||
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
|
||||
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
||||
F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
|
||||
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
||||
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
|
||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/sqlite3rbu.c 007fc4db8c0b95c7ef10162b5864921ef5cc8106
|
||||
F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2
|
||||
F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d
|
||||
F ext/rbu/rbuvacuum.test 66e02cf299836770e718e95c36686be0b26dbda3
|
||||
F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958
|
||||
F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930
|
||||
F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
@@ -289,18 +291,18 @@ F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26
|
||||
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
|
||||
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
|
||||
F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596
|
||||
F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40
|
||||
F ext/session/sessionfault2.test ac1dfd77a0fb0ea310aee40a16645ef1b66d3f88
|
||||
F ext/session/sqlite3session.c 2fc72bd989c424a15802da766c7ebd8eed47bcf6
|
||||
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
|
||||
F ext/session/sqlite3session.c beb43b6b888801bb006320bc236baa95f4cc32ae
|
||||
F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d
|
||||
F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce
|
||||
F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15
|
||||
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 942e1fd30eb352492cf599aa7fcb5334783e4cbf
|
||||
F main.mk a283660f75c3c4b75d8c9d12a40fa38a066eee9d
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -313,41 +315,41 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 1bb0709b3048e24217b80ec6bd78a3e99a47c01b
|
||||
F src/analyze.c ab57b6763dd4c6170a20673d14882c033affd188
|
||||
F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe
|
||||
F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
|
||||
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
|
||||
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||
F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0
|
||||
F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf
|
||||
F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
|
||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||
F src/build.c 39faaaeecb77eb3936d4bd5024e865e3836ca323
|
||||
F src/build.c 42e8ee74dfa3a4b99bfb2c201f8a66ab50688d95
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||
F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1
|
||||
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
|
||||
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
|
||||
F src/delete.c eeac28b3d3d88e3541bdf93e91ea7492a7b67842
|
||||
F src/expr.c 289ffac5240b60fee0a824d3d5ab2d7bd2630c94
|
||||
F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e
|
||||
F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
|
||||
F src/func.c 552d300265aed09eea21f68ac742a440550c0062
|
||||
F src/global.c 884d4c7eba9f5fc25c96a23b21520da19b7713e2
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1
|
||||
F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
|
||||
F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
|
||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||
F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002
|
||||
F src/main.c 5ac9dccc03faadd6f867f67b9018ff41eeeadb46
|
||||
F src/loadext.c 8b3a73f0624c5f7cadbd5cb89940783bee1d39a6
|
||||
F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca
|
||||
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memjournal.c 5253fd4335a8d9c64e5df25cb9da6329af5242c7
|
||||
F src/memjournal.c 95752936c11dc6995672d1dd783cd633eea0cc95
|
||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
@@ -355,19 +357,19 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
|
||||
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e
|
||||
F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1
|
||||
F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905
|
||||
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec
|
||||
F src/os_win.c ff870d89f4cb088a04cbf5ea0cbd9ff1b089ff4a
|
||||
F src/os_unix.c 8422fba2eb592fbbb2d4006b6f2a67cad8951495
|
||||
F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d
|
||||
F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
|
||||
F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821
|
||||
F src/pager.c d20fa46d5beda38095be6070dd4c59e502817c72
|
||||
F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681
|
||||
F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e
|
||||
F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
|
||||
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
|
||||
F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05
|
||||
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
|
||||
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
|
||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
|
||||
@@ -375,22 +377,22 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
|
||||
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
||||
F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143
|
||||
F src/shell.c cd3f82fdc5c895b817a375b7ab8319cb41f447ce
|
||||
F src/sqlite.h.in 843a0dfcf8c5e961cfafa62009fed0867b88241e
|
||||
F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d
|
||||
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
|
||||
F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
|
||||
F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904
|
||||
F src/sqliteInt.h ec538389481a3d093f07fb344c5a9dc988042304
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
F src/tclsqlite.c 56569acc73d36e836b64aefecbbb709a92ba0077
|
||||
F src/test1.c 7187b7e924bfc97780e6fd2a40dad94a32bddca0
|
||||
F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060
|
||||
F src/test1.c ee8fd5c32acb93fb6fe885ca4801cfab85f5563f
|
||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
|
||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
|
||||
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
|
||||
F src/test6.c 2c014d4977efd6107ec9eef3dfdec56ac516f824
|
||||
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
|
||||
F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75
|
||||
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||
@@ -402,21 +404,21 @@ F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239
|
||||
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||
F src/test_config.c 7003f6f35134de6f19c6588f44783e43390ea277
|
||||
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58
|
||||
F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b
|
||||
F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254
|
||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
|
||||
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
|
||||
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
|
||||
F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa
|
||||
F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c 96df9381a1ff1f6d3805ff7231b9baf1386aaabf
|
||||
F src/test_multiplex.c 6a9de820fcaaf506c59aa14bc8693822333cea48
|
||||
F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950
|
||||
F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9
|
||||
F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3
|
||||
F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c
|
||||
F src/test_onefile.c 38f7cbe79d5bafe95bde683cc3a53b8ca16daf10
|
||||
F src/test_osinst.c 5423dc1d355f594371f27dd292ca54bd320b8196
|
||||
F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f
|
||||
F src/test_osinst.c ad0233b1dabb0390e25edded4ebd79a2a61538c6
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d
|
||||
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
|
||||
@@ -425,40 +427,40 @@ F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
|
||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b
|
||||
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
|
||||
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
|
||||
F src/test_syscall.c 268c072541162564a882c57f54a6fee12ef4a4d2
|
||||
F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
|
||||
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
|
||||
F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
|
||||
F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c
|
||||
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61
|
||||
F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 3d338cdd00d916ce8a05c397001d64ed58e6fe1c
|
||||
F src/tokenize.c 3b29883b0ce4a6c6f643965b66b5ca6613178e59
|
||||
F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
|
||||
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
||||
F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a
|
||||
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
|
||||
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
|
||||
F src/vdbe.c 0f0e4a6255f9a5272857a818314d081db26bcd90
|
||||
F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863
|
||||
F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c
|
||||
F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
|
||||
F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd
|
||||
F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
|
||||
F src/vdbeaux.c fa06ba5441714160ab5f64422660ee286968672f
|
||||
F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f
|
||||
F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77
|
||||
F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb
|
||||
F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062
|
||||
F src/vdbesort.c 0a8f98366ae794442e6d1ef71d9553226d885d19
|
||||
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
|
||||
F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b
|
||||
F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302
|
||||
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
||||
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
|
||||
F src/where.c fe7925faafbe9a458972035c0bb4753d672f04ed
|
||||
F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34
|
||||
F src/wherecode.c 863aedf086131743763c1960637fde904eadc442
|
||||
F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a
|
||||
F src/where.c bae50f2f18f9e8584549a77363858623b07e4915
|
||||
F src/whereInt.h 7de94b751f088fe3fdc8cc04a491376f0900a059
|
||||
F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340
|
||||
F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@@ -497,7 +499,7 @@ F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d
|
||||
F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
|
||||
F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360
|
||||
F test/auth.test 872a122b3977c1d1bb9fd637dc20016e5c01880f
|
||||
F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
|
||||
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
|
||||
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
|
||||
@@ -519,7 +521,7 @@ F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
|
||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
|
||||
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
|
||||
F test/bestindex1.test d5ba89a7941a941476d8d69be39b146aaed3614c
|
||||
F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee
|
||||
F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060
|
||||
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
@@ -610,12 +612,12 @@ F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
|
||||
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
|
||||
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
|
||||
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
|
||||
F test/delete4.test 3ac0b8d23689ba764c2e8b78c1b56b8f1b942fa2
|
||||
F test/delete4.test 738044ee892ee0c84e0848e36ba92c55f907d52b
|
||||
F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
|
||||
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
|
||||
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
||||
@@ -642,7 +644,7 @@ F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
|
||||
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
||||
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
||||
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
|
||||
F test/e_vacuum.test 4d5b391384bb7d56bb9337d956f08035332421fc
|
||||
F test/e_vacuum.test 120f29ea56bdce4d43279527ece894ab5d1729d3
|
||||
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
||||
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
||||
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
||||
@@ -657,7 +659,7 @@ F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
|
||||
F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9
|
||||
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
|
||||
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
|
||||
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
|
||||
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
||||
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||
@@ -806,7 +808,7 @@ F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21
|
||||
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
|
||||
F test/hook.test 40523db3aa76d62bda71c26f824fa0eabc420f0e
|
||||
F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e
|
||||
F test/icu.test 73956798bace8982909c00476b216714a6d0559a
|
||||
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
|
||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||
@@ -823,7 +825,7 @@ F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
|
||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 676c41428765d58f1da7dbe659ef27726d3d30ac
|
||||
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
|
||||
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
|
||||
@@ -845,7 +847,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
|
||||
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
|
||||
F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
|
||||
F test/intpkey.test 70aab09756b9bd3bcb6b0358f971d7bbace46522
|
||||
F test/intpkey.test 153b70e32d008f4f4b2dff8daf448a6110b62a9c
|
||||
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
|
||||
F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d
|
||||
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
|
||||
@@ -860,7 +862,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
F test/join5.test 8a5c0be6f0c260a5c7177c3b8f07c7856141038a
|
||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
@@ -875,7 +877,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a
|
||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||
F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
|
||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
|
||||
F test/loadext.test 42a3b8166dfcadcb0e0c8710dc520d97c31a8b98
|
||||
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
|
||||
F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5
|
||||
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
|
||||
@@ -975,10 +977,10 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test cd1fa041074ed08eeaa563e4d1bacb0c69337ec1
|
||||
F test/pragma.test afbf028be1c35b68f57db8eb015c4a3c59d8f28e
|
||||
F test/permutations.test b6b3e165fdc1b8c82a820033646dbfc6a7a01746
|
||||
F test/pragma.test dd5313eee9c6d9d4726593a68ede8768d3b50ccc
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 3f1984a04657331f838df5c519b443c2088df922
|
||||
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
@@ -986,7 +988,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
|
||||
F test/quota.test 36cd78b178c4eb0401d4f25754ef410fbd9df2a7
|
||||
F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a
|
||||
F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
|
||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
||||
@@ -1011,7 +1013,7 @@ F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7
|
||||
F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
|
||||
F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
|
||||
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3
|
||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||
F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285
|
||||
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
|
||||
@@ -1024,7 +1026,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
||||
F test/select4.test d926792a5e4d88fef0ddcddeb45d27ce75f7296c
|
||||
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
|
||||
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61
|
||||
@@ -1051,7 +1053,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test dff5b20ad989770aface6d714491121172dfe8b0
|
||||
F test/shell1.test 023657b3f8ba108dbd5ff2ebc8fceb3cf6d4ff9f
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd
|
||||
F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9
|
||||
@@ -1065,7 +1067,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
|
||||
F test/snapshot.test 9ed24c792fb05382814258daf68b2256f23de57f
|
||||
F test/snapshot.test 3adc4ef09d407b501f899a6c329bdf45dc725c1b
|
||||
F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73
|
||||
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
||||
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
|
||||
@@ -1073,7 +1075,7 @@ F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b
|
||||
F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0
|
||||
F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5
|
||||
F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c
|
||||
F test/sort5.test d3041ce3c475aa04142a959ae56ef6593f98a99f
|
||||
F test/sort5.test e47ec7a490b9b36787755874175d8f413a3883d9
|
||||
F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66
|
||||
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
|
||||
F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
|
||||
@@ -1083,14 +1085,14 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c 21af8db2492a903835b654517ac8d90aed0af91f
|
||||
F test/speedtest1.c 4476f7030775507f060d27b789e1f4123c5a5866
|
||||
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e
|
||||
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
||||
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
|
||||
F test/stat.test b65bad7120c52583b8f0054d99eff80718119a77
|
||||
F test/stat.test 66e95f97b9f724f9ab921d054ee0db3c2689f1ee
|
||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
|
||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||
@@ -1100,7 +1102,7 @@ F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
|
||||
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||
F test/sync.test 2f607e1821aa3af3c5c53b58835c05e511c95899
|
||||
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
|
||||
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906
|
||||
@@ -1111,7 +1113,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa
|
||||
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||
F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553
|
||||
F test/tester.tcl 30c7a9be8601d1c1c9c93d013545ebcb28d64254
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1127,10 +1129,10 @@ F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
|
||||
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
||||
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
|
||||
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
|
||||
F test/tkt-2d1a5c67d.test d371279946622698ab393ff88cad9f5f6d82960b
|
||||
F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0
|
||||
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
||||
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
|
||||
F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac
|
||||
F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d
|
||||
F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e
|
||||
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
|
||||
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
||||
@@ -1141,7 +1143,7 @@ F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
|
||||
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
|
||||
F test/tkt-4ef7e3cfca.test 3965ae11cc9cf6e334f9d7d3c1e20bf8d56254b1
|
||||
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
|
||||
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
|
||||
F test/tkt-5d863f876e.test 726e76d725f6fe0eb2fc8a522b721b79807380ee
|
||||
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
|
||||
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
|
||||
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
|
||||
@@ -1157,7 +1159,7 @@ F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed
|
||||
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
|
||||
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
|
||||
F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
|
||||
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
|
||||
F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6
|
||||
F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8
|
||||
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
|
||||
F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9
|
||||
@@ -1308,7 +1310,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
|
||||
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9
|
||||
F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
|
||||
F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda
|
||||
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
@@ -1396,7 +1398,7 @@ F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
|
||||
F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
|
||||
F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf
|
||||
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
|
||||
F test/zerodamage.test 2d725c214b883e25ae6bb85ef228ecdfa03c6a7b
|
||||
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
|
||||
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
||||
F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372
|
||||
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
|
||||
@@ -1415,12 +1417,12 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/lemon.c cfbfe061a4b2766512f6b484882eee2c86a14506
|
||||
F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7
|
||||
F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22
|
||||
F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d
|
||||
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
@@ -1436,7 +1438,7 @@ F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0
|
||||
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
|
||||
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
|
||||
F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076
|
||||
F tool/showdb.c 82dca79a999b2701c62417636345e9974151fdad
|
||||
F tool/showdb.c c695a5d5c8110640e0d9fadf5e254da90c79c36e
|
||||
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
|
||||
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
|
||||
F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b
|
||||
@@ -1482,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 195f3340ee4d870420e4f58d44300bab5436b920
|
||||
R 553c882c4eb73691c7e02bdd576b9d70
|
||||
P 45467ee49872f495d5276cf830f10c3cf4ac8e3c
|
||||
R 50a6a2b7911c16c6704703bf8b17ce71
|
||||
U dan
|
||||
Z 5ef40d72349254975dc55c844d6daff8
|
||||
Z da972510c8d8b75cf481b4f80618fa01
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
49763fc3ae2fb6117b0443ea28661568467f9bf2
|
||||
89b0ee3351381f7bc666cb206f77a56f2e0d4a0e
|
||||
+17
-14
@@ -1826,7 +1826,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
analysisInfo sInfo;
|
||||
HashElem *i;
|
||||
char *zSql;
|
||||
int rc;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( iDb>=0 && iDb<db->nDb );
|
||||
assert( db->aDb[iDb].pBt!=0 );
|
||||
@@ -1835,31 +1835,34 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
|
||||
Index *pIdx = sqliteHashData(i);
|
||||
sqlite3DefaultRowEst(pIdx);
|
||||
pIdx->aiRowLogEst[0] = 0;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
sqlite3DeleteIndexSamples(db, pIdx);
|
||||
pIdx->aSample = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check to make sure the sqlite_stat1 table exists */
|
||||
/* Load new statistics out of the sqlite_stat1 table */
|
||||
sInfo.db = db;
|
||||
sInfo.zDatabase = db->aDb[iDb].zName;
|
||||
if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
|
||||
return SQLITE_ERROR;
|
||||
if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
|
||||
zSql = sqlite3MPrintf(db,
|
||||
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}else{
|
||||
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
|
||||
sqlite3DbFree(db, zSql);
|
||||
}
|
||||
}
|
||||
|
||||
/* Load new statistics out of the sqlite_stat1 table */
|
||||
zSql = sqlite3MPrintf(db,
|
||||
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}else{
|
||||
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
|
||||
sqlite3DbFree(db, zSql);
|
||||
/* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
|
||||
Index *pIdx = sqliteHashData(i);
|
||||
if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
|
||||
}
|
||||
|
||||
|
||||
/* Load the statistics from the sqlite_stat4 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
|
||||
|
||||
+24
-24
@@ -6545,8 +6545,8 @@ static int pageInsertArray(
|
||||
u8 *pSlot;
|
||||
sz = cachedCellSize(pCArray, i);
|
||||
if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
|
||||
if( (pData - pBegin)<sz ) return 1;
|
||||
pData -= sz;
|
||||
if( pData<pBegin ) return 1;
|
||||
pSlot = pData;
|
||||
}
|
||||
/* pSlot and pCArray->apCell[i] will never overlap on a well-formed
|
||||
@@ -6708,7 +6708,7 @@ static int editPage(
|
||||
for(i=0; i<nNew && !CORRUPT_DB; i++){
|
||||
u8 *pCell = pCArray->apCell[i+iNew];
|
||||
int iOff = get2byteAligned(&pPg->aCellIdx[i*2]);
|
||||
if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
|
||||
if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){
|
||||
pCell = &pTmp[pCell - aData];
|
||||
}
|
||||
assert( 0==memcmp(pCell, &aData[iOff],
|
||||
@@ -8140,6 +8140,28 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
pPage = pCur->apPage[iCellDepth];
|
||||
pCell = findCell(pPage, iCellIdx);
|
||||
|
||||
/* If the bPreserve flag is set to true, then the cursor position must
|
||||
** be preserved following this delete operation. If the current delete
|
||||
** will cause a b-tree rebalance, then this is done by saving the cursor
|
||||
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
|
||||
** returning.
|
||||
**
|
||||
** Or, if the current delete will not cause a rebalance, then the cursor
|
||||
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
|
||||
** before or after the deleted entry. In this case set bSkipnext to true. */
|
||||
if( bPreserve ){
|
||||
if( !pPage->leaf
|
||||
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
|
||||
){
|
||||
/* A b-tree rebalance will be required after deleting this entry.
|
||||
** Save the cursor key. */
|
||||
rc = saveCursorKey(pCur);
|
||||
if( rc ) return rc;
|
||||
}else{
|
||||
bSkipnext = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the page containing the entry to delete is not a leaf page, move
|
||||
** the cursor to the largest entry in the tree that is smaller than
|
||||
** the entry being deleted. This cell will replace the cell being deleted
|
||||
@@ -8166,28 +8188,6 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
invalidateIncrblobCursors(p, pCur->info.nKey, 0);
|
||||
}
|
||||
|
||||
/* If the bPreserve flag is set to true, then the cursor position must
|
||||
** be preserved following this delete operation. If the current delete
|
||||
** will cause a b-tree rebalance, then this is done by saving the cursor
|
||||
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
|
||||
** returning.
|
||||
**
|
||||
** Or, if the current delete will not cause a rebalance, then the cursor
|
||||
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
|
||||
** before or after the deleted entry. In this case set bSkipnext to true. */
|
||||
if( bPreserve ){
|
||||
if( !pPage->leaf
|
||||
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
|
||||
){
|
||||
/* A b-tree rebalance will be required after deleting this entry.
|
||||
** Save the cursor key. */
|
||||
rc = saveCursorKey(pCur);
|
||||
if( rc ) return rc;
|
||||
}else{
|
||||
bSkipnext = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make the page containing the entry to be deleted writable. Then free any
|
||||
** overflow pages associated with the entry and finally remove the cell
|
||||
** itself from within the page. */
|
||||
|
||||
+45
-33
@@ -1086,6 +1086,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
|
||||
zType = z + sqlite3Strlen30(z) + 1;
|
||||
memcpy(zType, pType->z, pType->n);
|
||||
zType[pType->n] = 0;
|
||||
sqlite3Dequote(zType);
|
||||
pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
|
||||
pCol->colFlags |= COLFLAG_HASTYPE;
|
||||
}
|
||||
@@ -2176,44 +2177,55 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
** statement that defines the view.
|
||||
*/
|
||||
assert( pTable->pSelect );
|
||||
if( pTable->pCheck ){
|
||||
pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
|
||||
if( pSel ){
|
||||
n = pParse->nTab;
|
||||
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
|
||||
pTable->nCol = -1;
|
||||
db->lookaside.bDisable++;
|
||||
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
|
||||
&pTable->nCol, &pTable->aCol);
|
||||
db->lookaside.bDisable--;
|
||||
}else{
|
||||
pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
|
||||
if( pSel ){
|
||||
n = pParse->nTab;
|
||||
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
|
||||
pTable->nCol = -1;
|
||||
db->lookaside.bDisable++;
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
xAuth = db->xAuth;
|
||||
db->xAuth = 0;
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
||||
db->xAuth = xAuth;
|
||||
xAuth = db->xAuth;
|
||||
db->xAuth = 0;
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
||||
db->xAuth = xAuth;
|
||||
#else
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
||||
#endif
|
||||
db->lookaside.bDisable--;
|
||||
pParse->nTab = n;
|
||||
if( pSelTab ){
|
||||
assert( pTable->aCol==0 );
|
||||
pTable->nCol = pSelTab->nCol;
|
||||
pTable->aCol = pSelTab->aCol;
|
||||
pSelTab->nCol = 0;
|
||||
pSelTab->aCol = 0;
|
||||
sqlite3DeleteTable(db, pSelTab);
|
||||
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
|
||||
}else{
|
||||
pTable->nCol = 0;
|
||||
nErr++;
|
||||
pParse->nTab = n;
|
||||
if( pTable->pCheck ){
|
||||
/* CREATE VIEW name(arglist) AS ...
|
||||
** The names of the columns in the table are taken from
|
||||
** arglist which is stored in pTable->pCheck. The pCheck field
|
||||
** normally holds CHECK constraints on an ordinary table, but for
|
||||
** a VIEW it holds the list of column names.
|
||||
*/
|
||||
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
|
||||
&pTable->nCol, &pTable->aCol);
|
||||
if( db->mallocFailed==0
|
||||
&& pParse->nErr==0
|
||||
&& pTable->nCol==pSel->pEList->nExpr
|
||||
){
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
|
||||
}
|
||||
sqlite3SelectDelete(db, pSel);
|
||||
} else {
|
||||
}else if( pSelTab ){
|
||||
/* CREATE VIEW name AS... without an argument list. Construct
|
||||
** the column names from the SELECT statement that defines the view.
|
||||
*/
|
||||
assert( pTable->aCol==0 );
|
||||
pTable->nCol = pSelTab->nCol;
|
||||
pTable->aCol = pSelTab->aCol;
|
||||
pSelTab->nCol = 0;
|
||||
pSelTab->aCol = 0;
|
||||
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
|
||||
}else{
|
||||
pTable->nCol = 0;
|
||||
nErr++;
|
||||
}
|
||||
if( pSelTab ) sqlite3DeleteTable(db, pSelTab);
|
||||
sqlite3SelectDelete(db, pSel);
|
||||
db->lookaside.bDisable--;
|
||||
} else {
|
||||
nErr++;
|
||||
}
|
||||
pTable->pSchema->schemaFlags |= DB_UnresetViews;
|
||||
#endif /* SQLITE_OMIT_VIEW */
|
||||
@@ -2762,6 +2774,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
tnum = pIndex->tnum;
|
||||
}
|
||||
pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
|
||||
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
||||
|
||||
/* Open the sorter cursor if we are to use one. */
|
||||
iSorter = pParse->nTab++;
|
||||
@@ -2785,8 +2798,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
|
||||
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
|
||||
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
||||
if( IsUniqueIndex(pIndex) && pKey!=0 ){
|
||||
if( IsUniqueIndex(pIndex) ){
|
||||
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
|
||||
sqlite3VdbeGoto(v, j2);
|
||||
addr2 = sqlite3VdbeCurrentAddr(v);
|
||||
|
||||
+10
-1
@@ -50,6 +50,15 @@
|
||||
|
||||
#ifndef SQLITE_OMIT_DATETIME_FUNCS
|
||||
|
||||
/*
|
||||
** The MSVC CRT on Windows CE may not have a localtime() function.
|
||||
** So declare a substitute. The substitute function itself is
|
||||
** defined in "os_win.c".
|
||||
*/
|
||||
#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
|
||||
(!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
|
||||
struct tm *__cdecl localtime(const time_t *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** A structure for holding a single date and time.
|
||||
@@ -418,6 +427,7 @@ static void clearYMD_HMS_TZ(DateTime *p){
|
||||
p->validTZ = 0;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_LOCALTIME
|
||||
/*
|
||||
** On recent Windows platforms, the localtime_s() function is available
|
||||
** as part of the "Secure CRT". It is essentially equivalent to
|
||||
@@ -436,7 +446,6 @@ static void clearYMD_HMS_TZ(DateTime *p){
|
||||
#define HAVE_LOCALTIME_S 1
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_LOCALTIME
|
||||
/*
|
||||
** The following routine implements the rough equivalent of localtime_r()
|
||||
** using whatever operating-system specific localtime facility that
|
||||
|
||||
+7
-17
@@ -143,7 +143,7 @@ Expr *sqlite3LimitWhere(
|
||||
*/
|
||||
if( pOrderBy && (pLimit == 0) ) {
|
||||
sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
|
||||
goto limit_where_cleanup_2;
|
||||
goto limit_where_cleanup;
|
||||
}
|
||||
|
||||
/* We only need to generate a select expression if there
|
||||
@@ -165,16 +165,16 @@ Expr *sqlite3LimitWhere(
|
||||
*/
|
||||
|
||||
pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
|
||||
if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
|
||||
if( pSelectRowid == 0 ) goto limit_where_cleanup;
|
||||
pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
|
||||
if( pEList == 0 ) goto limit_where_cleanup_2;
|
||||
if( pEList == 0 ) goto limit_where_cleanup;
|
||||
|
||||
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
|
||||
** and the SELECT subtree. */
|
||||
pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
|
||||
if( pSelectSrc == 0 ) {
|
||||
sqlite3ExprListDelete(pParse->db, pEList);
|
||||
goto limit_where_cleanup_2;
|
||||
goto limit_where_cleanup;
|
||||
}
|
||||
|
||||
/* generate the SELECT expression tree. */
|
||||
@@ -184,21 +184,11 @@ Expr *sqlite3LimitWhere(
|
||||
|
||||
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
|
||||
pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
|
||||
if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
|
||||
pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
|
||||
if( pInClause == 0 ) goto limit_where_cleanup_1;
|
||||
|
||||
pInClause->x.pSelect = pSelect;
|
||||
pInClause->flags |= EP_xIsSelect;
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pInClause);
|
||||
pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0;
|
||||
sqlite3PExprAddSelect(pParse, pInClause, pSelect);
|
||||
return pInClause;
|
||||
|
||||
/* something went wrong. clean up anything allocated. */
|
||||
limit_where_cleanup_1:
|
||||
sqlite3SelectDelete(pParse->db, pSelect);
|
||||
return 0;
|
||||
|
||||
limit_where_cleanup_2:
|
||||
limit_where_cleanup:
|
||||
sqlite3ExprDelete(pParse->db, pWhere);
|
||||
sqlite3ExprListDelete(pParse->db, pOrderBy);
|
||||
sqlite3ExprDelete(pParse->db, pLimit);
|
||||
|
||||
+127
-92
@@ -471,15 +471,13 @@ Expr *sqlite3ExprAlloc(
|
||||
pNew->flags |= EP_IntValue;
|
||||
pNew->u.iValue = iValue;
|
||||
}else{
|
||||
int c;
|
||||
pNew->u.zToken = (char*)&pNew[1];
|
||||
assert( pToken->z!=0 || pToken->n==0 );
|
||||
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
|
||||
pNew->u.zToken[pToken->n] = 0;
|
||||
if( dequote && nExtra>=3
|
||||
&& ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
|
||||
if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
|
||||
if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
|
||||
sqlite3Dequote(pNew->u.zToken);
|
||||
if( c=='"' ) pNew->flags |= EP_DblQuoted;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -562,6 +560,22 @@ Expr *sqlite3PExpr(
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due
|
||||
** do a memory allocation failure) then delete the pSelect object.
|
||||
*/
|
||||
void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
|
||||
if( pExpr ){
|
||||
pExpr->x.pSelect = pSelect;
|
||||
ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pExpr);
|
||||
}else{
|
||||
assert( pParse->db->mallocFailed );
|
||||
sqlite3SelectDelete(pParse->db, pSelect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** If the expression is always either TRUE or FALSE (respectively),
|
||||
** then return 1. If one cannot determine the truth value of the
|
||||
@@ -722,8 +736,8 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
|
||||
/*
|
||||
** Recursively delete an expression tree.
|
||||
*/
|
||||
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
|
||||
if( p==0 ) return;
|
||||
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
|
||||
assert( p!=0 );
|
||||
/* Sanity check: Assert that the IntValue is non-negative if it exists */
|
||||
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
|
||||
if( !ExprHasProperty(p, EP_TokenOnly) ){
|
||||
@@ -742,6 +756,9 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
}
|
||||
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
|
||||
if( p ) sqlite3ExprDeleteNN(db, p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of bytes allocated for the expression structure
|
||||
@@ -793,7 +810,7 @@ static int dupedExprStructSize(Expr *p, int flags){
|
||||
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
|
||||
assert( EXPR_FULLSIZE<=0xfff );
|
||||
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
|
||||
if( 0==(flags&EXPRDUP_REDUCE) ){
|
||||
if( 0==flags ){
|
||||
nSize = EXPR_FULLSIZE;
|
||||
}else{
|
||||
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
|
||||
@@ -855,88 +872,88 @@ static int dupedExprSize(Expr *p, int flags){
|
||||
** if any. Before returning, *pzBuffer is set to the first byte past the
|
||||
** portion of the buffer copied into by this function.
|
||||
*/
|
||||
static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
|
||||
Expr *pNew = 0; /* Value to return */
|
||||
assert( flags==0 || flags==EXPRDUP_REDUCE );
|
||||
static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
|
||||
Expr *pNew; /* Value to return */
|
||||
u8 *zAlloc; /* Memory space from which to build Expr object */
|
||||
u32 staticFlag; /* EP_Static if space not obtained from malloc */
|
||||
|
||||
assert( db!=0 );
|
||||
if( p ){
|
||||
const int isReduced = (flags&EXPRDUP_REDUCE);
|
||||
u8 *zAlloc;
|
||||
u32 staticFlag = 0;
|
||||
assert( p );
|
||||
assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
|
||||
assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
|
||||
|
||||
assert( pzBuffer==0 || isReduced );
|
||||
/* Figure out where to write the new Expr structure. */
|
||||
if( pzBuffer ){
|
||||
zAlloc = *pzBuffer;
|
||||
staticFlag = EP_Static;
|
||||
}else{
|
||||
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
|
||||
staticFlag = 0;
|
||||
}
|
||||
pNew = (Expr *)zAlloc;
|
||||
|
||||
/* Figure out where to write the new Expr structure. */
|
||||
if( pzBuffer ){
|
||||
zAlloc = *pzBuffer;
|
||||
staticFlag = EP_Static;
|
||||
if( pNew ){
|
||||
/* Set nNewSize to the size allocated for the structure pointed to
|
||||
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
|
||||
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
|
||||
** by the copy of the p->u.zToken string (if any).
|
||||
*/
|
||||
const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
|
||||
const int nNewSize = nStructSize & 0xfff;
|
||||
int nToken;
|
||||
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
|
||||
nToken = sqlite3Strlen30(p->u.zToken) + 1;
|
||||
}else{
|
||||
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, flags));
|
||||
nToken = 0;
|
||||
}
|
||||
if( dupFlags ){
|
||||
assert( ExprHasProperty(p, EP_Reduced)==0 );
|
||||
memcpy(zAlloc, p, nNewSize);
|
||||
}else{
|
||||
u32 nSize = (u32)exprStructSize(p);
|
||||
memcpy(zAlloc, p, nSize);
|
||||
if( nSize<EXPR_FULLSIZE ){
|
||||
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
|
||||
}
|
||||
}
|
||||
pNew = (Expr *)zAlloc;
|
||||
|
||||
if( pNew ){
|
||||
/* Set nNewSize to the size allocated for the structure pointed to
|
||||
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
|
||||
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
|
||||
** by the copy of the p->u.zToken string (if any).
|
||||
*/
|
||||
const unsigned nStructSize = dupedExprStructSize(p, flags);
|
||||
const int nNewSize = nStructSize & 0xfff;
|
||||
int nToken;
|
||||
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
|
||||
nToken = sqlite3Strlen30(p->u.zToken) + 1;
|
||||
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
|
||||
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
|
||||
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
|
||||
pNew->flags |= staticFlag;
|
||||
|
||||
/* Copy the p->u.zToken string, if any. */
|
||||
if( nToken ){
|
||||
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
|
||||
memcpy(zToken, p->u.zToken, nToken);
|
||||
}
|
||||
|
||||
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
|
||||
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
|
||||
if( ExprHasProperty(p, EP_xIsSelect) ){
|
||||
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
|
||||
}else{
|
||||
nToken = 0;
|
||||
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
|
||||
}
|
||||
if( isReduced ){
|
||||
assert( ExprHasProperty(p, EP_Reduced)==0 );
|
||||
memcpy(zAlloc, p, nNewSize);
|
||||
}else{
|
||||
u32 nSize = (u32)exprStructSize(p);
|
||||
memcpy(zAlloc, p, nSize);
|
||||
if( nSize<EXPR_FULLSIZE ){
|
||||
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in pNew->pLeft and pNew->pRight. */
|
||||
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
|
||||
zAlloc += dupedExprNodeSize(p, dupFlags);
|
||||
if( ExprHasProperty(pNew, EP_Reduced) ){
|
||||
pNew->pLeft = p->pLeft ?
|
||||
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
|
||||
pNew->pRight = p->pRight ?
|
||||
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
|
||||
}
|
||||
|
||||
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
|
||||
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
|
||||
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
|
||||
pNew->flags |= staticFlag;
|
||||
|
||||
/* Copy the p->u.zToken string, if any. */
|
||||
if( nToken ){
|
||||
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
|
||||
memcpy(zToken, p->u.zToken, nToken);
|
||||
if( pzBuffer ){
|
||||
*pzBuffer = zAlloc;
|
||||
}
|
||||
|
||||
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
|
||||
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
|
||||
if( ExprHasProperty(p, EP_xIsSelect) ){
|
||||
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
|
||||
}else{
|
||||
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
|
||||
}
|
||||
}else{
|
||||
if( !ExprHasProperty(p, EP_TokenOnly) ){
|
||||
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
|
||||
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
|
||||
}
|
||||
|
||||
/* Fill in pNew->pLeft and pNew->pRight. */
|
||||
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
|
||||
zAlloc += dupedExprNodeSize(p, flags);
|
||||
if( ExprHasProperty(pNew, EP_Reduced) ){
|
||||
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
|
||||
pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
|
||||
}
|
||||
if( pzBuffer ){
|
||||
*pzBuffer = zAlloc;
|
||||
}
|
||||
}else{
|
||||
if( !ExprHasProperty(p, EP_TokenOnly) ){
|
||||
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
|
||||
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return pNew;
|
||||
@@ -988,7 +1005,7 @@ static With *withDup(sqlite3 *db, With *p){
|
||||
*/
|
||||
Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
|
||||
assert( flags==0 || flags==EXPRDUP_REDUCE );
|
||||
return exprDup(db, p, flags, 0);
|
||||
return p ? exprDup(db, p, flags, 0) : 0;
|
||||
}
|
||||
ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
|
||||
ExprList *pNew;
|
||||
@@ -1210,7 +1227,7 @@ void sqlite3ExprListSetName(
|
||||
pItem = &pList->a[pList->nExpr-1];
|
||||
assert( pItem->zName==0 );
|
||||
pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
|
||||
if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
|
||||
if( dequote ) sqlite3Dequote(pItem->zName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,10 +1276,9 @@ void sqlite3ExprListCheckLength(
|
||||
/*
|
||||
** Delete an entire expression list.
|
||||
*/
|
||||
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
|
||||
int i;
|
||||
struct ExprList_item *pItem;
|
||||
if( pList==0 ) return;
|
||||
assert( pList->a!=0 || pList->nExpr==0 );
|
||||
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
|
||||
sqlite3ExprDelete(db, pItem->pExpr);
|
||||
@@ -1272,6 +1288,9 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
sqlite3DbFree(db, pList->a);
|
||||
sqlite3DbFree(db, pList);
|
||||
}
|
||||
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
if( pList ) exprListDeleteNN(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the bitwise-OR of all Expr.flags fields in the given
|
||||
@@ -2316,6 +2335,19 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SQLITE_DEBUG)
|
||||
/*
|
||||
** Verify the consistency of the column cache
|
||||
*/
|
||||
static int cacheIsValid(Parse *pParse){
|
||||
int i, n;
|
||||
for(i=n=0; i<SQLITE_N_COLCACHE; i++){
|
||||
if( pParse->aColCache[i].iReg>0 ) n++;
|
||||
}
|
||||
return n==pParse->nColCache;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Clear a cache entry.
|
||||
*/
|
||||
@@ -2326,6 +2358,9 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){
|
||||
}
|
||||
p->tempReg = 0;
|
||||
}
|
||||
p->iReg = 0;
|
||||
pParse->nColCache--;
|
||||
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
|
||||
}
|
||||
|
||||
|
||||
@@ -2369,6 +2404,8 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
|
||||
p->iReg = iReg;
|
||||
p->tempReg = 0;
|
||||
p->lru = pParse->iCacheCnt++;
|
||||
pParse->nColCache++;
|
||||
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2390,6 +2427,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
|
||||
p->iReg = iReg;
|
||||
p->tempReg = 0;
|
||||
p->lru = pParse->iCacheCnt++;
|
||||
assert( cacheIsValid(pParse) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2399,15 +2437,13 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
|
||||
** Purge the range of registers from the column cache.
|
||||
*/
|
||||
void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
|
||||
int i;
|
||||
int iLast = iReg + nReg - 1;
|
||||
struct yColCache *p;
|
||||
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
|
||||
int r = p->iReg;
|
||||
if( r>=iReg && r<=iLast ){
|
||||
cacheEntryClear(pParse, p);
|
||||
p->iReg = 0;
|
||||
}
|
||||
if( iReg<=0 || pParse->nColCache==0 ) return;
|
||||
p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
|
||||
while(1){
|
||||
if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);
|
||||
if( p==pParse->aColCache ) break;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2443,7 +2479,6 @@ void sqlite3ExprCachePop(Parse *pParse){
|
||||
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
|
||||
if( p->iReg && p->iLevel>pParse->iCacheLevel ){
|
||||
cacheEntryClear(pParse, p);
|
||||
p->iReg = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2578,7 +2613,6 @@ void sqlite3ExprCacheClear(Parse *pParse){
|
||||
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
|
||||
if( p->iReg ){
|
||||
cacheEntryClear(pParse, p);
|
||||
p->iReg = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2620,6 +2654,7 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
|
||||
}
|
||||
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
|
||||
|
||||
|
||||
/*
|
||||
** Convert an expression node to a TK_REGISTER
|
||||
*/
|
||||
|
||||
@@ -1386,6 +1386,14 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
char *zErrMsg = 0;
|
||||
|
||||
/* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
|
||||
** flag is set. See the sqlite3_enable_load_extension() API.
|
||||
*/
|
||||
if( (db->flags & SQLITE_LoadExtFunc)==0 ){
|
||||
sqlite3_result_error(context, "not authorized", -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if( argc==2 ){
|
||||
zProc = (const char *)sqlite3_value_text(argv[1]);
|
||||
}else{
|
||||
|
||||
+4
-3
@@ -70,6 +70,7 @@ const unsigned char sqlite3UpperToLower[] = {
|
||||
** isxdigit() 0x08
|
||||
** toupper() 0x20
|
||||
** SQLite identifier character 0x40
|
||||
** Quote character 0x80
|
||||
**
|
||||
** Bit 0x20 is set if the mapped character requires translation to upper
|
||||
** case. i.e. if the character is a lower-case ASCII character.
|
||||
@@ -95,7 +96,7 @@ const unsigned char sqlite3CtypeMap[256] = {
|
||||
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
|
||||
0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */
|
||||
0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
|
||||
0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
|
||||
@@ -103,8 +104,8 @@ const unsigned char sqlite3CtypeMap[256] = {
|
||||
0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
|
||||
0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
|
||||
0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
|
||||
0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
|
||||
0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
|
||||
0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */
|
||||
|
||||
+2
-2
@@ -55,7 +55,7 @@ void sqlite3HashClear(Hash *pH){
|
||||
static unsigned int strHash(const char *z){
|
||||
unsigned int h = 0;
|
||||
unsigned char c;
|
||||
while( (c = (unsigned char)*z++)!=0 ){
|
||||
while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
|
||||
}
|
||||
return h;
|
||||
@@ -148,7 +148,7 @@ static HashElem *findElementWithHash(
|
||||
int count; /* Number of elements left to test */
|
||||
unsigned int h; /* The computed hash */
|
||||
|
||||
if( pH->ht ){
|
||||
if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
struct _ht *pEntry;
|
||||
h = strHash(pKey) % pH->htsize;
|
||||
pEntry = &pH->ht[h];
|
||||
|
||||
+5
-4
@@ -464,8 +464,9 @@ static int sqlite3LoadExtension(
|
||||
/* Ticket #1863. To avoid a creating security problems for older
|
||||
** applications that relink against newer versions of SQLite, the
|
||||
** ability to run load_extension is turned off by default. One
|
||||
** must call sqlite3_enable_load_extension() to turn on extension
|
||||
** loading. Otherwise you get the following error.
|
||||
** must call either sqlite3_enable_load_extension(db) or
|
||||
** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
|
||||
** to turn on extension loading.
|
||||
*/
|
||||
if( (db->flags & SQLITE_LoadExtension)==0 ){
|
||||
if( pzErrMsg ){
|
||||
@@ -604,9 +605,9 @@ void sqlite3CloseExtensions(sqlite3 *db){
|
||||
int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( onoff ){
|
||||
db->flags |= SQLITE_LoadExtension;
|
||||
db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
|
||||
}else{
|
||||
db->flags &= ~SQLITE_LoadExtension;
|
||||
db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
|
||||
@@ -804,6 +804,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
|
||||
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
|
||||
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
|
||||
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
|
||||
};
|
||||
unsigned int i;
|
||||
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
|
||||
|
||||
+12
-1
@@ -13,6 +13,15 @@
|
||||
** This file contains code use to implement an in-memory rollback journal.
|
||||
** The in-memory rollback journal is used to journal transactions for
|
||||
** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
|
||||
**
|
||||
** Update: The in-memory journal is also used to temporarily cache
|
||||
** smaller journals that are not critical for power-loss recovery.
|
||||
** For example, statement journals that are not too big will be held
|
||||
** entirely in memory, thus reducing the number of file I/O calls, and
|
||||
** more importantly, reducing temporary file creation events. If these
|
||||
** journals become too large for memory, they are spilled to disk. But
|
||||
** in the common case, they are usually small and no file I/O needs to
|
||||
** occur.
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -94,6 +103,7 @@ static int memjrnlRead(
|
||||
#endif
|
||||
|
||||
assert( (iAmt+iOfst)<=p->endpoint.iOffset );
|
||||
assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
|
||||
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
|
||||
sqlite3_int64 iOff = 0;
|
||||
for(pChunk=p->pFirst;
|
||||
@@ -104,6 +114,7 @@ static int memjrnlRead(
|
||||
}
|
||||
}else{
|
||||
pChunk = p->readpoint.pChunk;
|
||||
assert( pChunk!=0 );
|
||||
}
|
||||
|
||||
iChunkOffset = (int)(iOfst%p->nChunkSize);
|
||||
@@ -115,7 +126,7 @@ static int memjrnlRead(
|
||||
nRead -= iSpace;
|
||||
iChunkOffset = 0;
|
||||
} while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
|
||||
p->readpoint.iOffset = iOfst+iAmt;
|
||||
p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0;
|
||||
p->readpoint.pChunk = pChunk;
|
||||
|
||||
return SQLITE_OK;
|
||||
|
||||
@@ -81,13 +81,11 @@ int sqlite3_memdebug_vfs_oom_test = 1;
|
||||
** of this would be completely automatic if SQLite were coded using
|
||||
** C++ instead of plain old C.
|
||||
*/
|
||||
int sqlite3OsClose(sqlite3_file *pId){
|
||||
int rc = SQLITE_OK;
|
||||
void sqlite3OsClose(sqlite3_file *pId){
|
||||
if( pId->pMethods ){
|
||||
rc = pId->pMethods->xClose(pId);
|
||||
pId->pMethods->xClose(pId);
|
||||
pId->pMethods = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
|
||||
DO_OS_MALLOC_TEST(id);
|
||||
@@ -305,12 +303,10 @@ int sqlite3OsOpenMalloc(
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
int sqlite3OsCloseFree(sqlite3_file *pFile){
|
||||
int rc = SQLITE_OK;
|
||||
void sqlite3OsCloseFree(sqlite3_file *pFile){
|
||||
assert( pFile );
|
||||
rc = sqlite3OsClose(pFile);
|
||||
sqlite3OsClose(pFile);
|
||||
sqlite3_free(pFile);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -160,7 +160,7 @@ int sqlite3OsInit(void);
|
||||
/*
|
||||
** Functions for accessing sqlite3_file methods
|
||||
*/
|
||||
int sqlite3OsClose(sqlite3_file*);
|
||||
void sqlite3OsClose(sqlite3_file*);
|
||||
int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
|
||||
int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
|
||||
int sqlite3OsTruncate(sqlite3_file*, i64 size);
|
||||
@@ -205,6 +205,6 @@ int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
|
||||
** sqlite3_malloc() to obtain space for the file-handle structure.
|
||||
*/
|
||||
int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
|
||||
int sqlite3OsCloseFree(sqlite3_file *);
|
||||
void sqlite3OsCloseFree(sqlite3_file *);
|
||||
|
||||
#endif /* _SQLITE_OS_H_ */
|
||||
|
||||
+23
-18
@@ -405,7 +405,7 @@ static struct unix_syscall {
|
||||
#else
|
||||
{ "pread64", (sqlite3_syscall_ptr)0, 0 },
|
||||
#endif
|
||||
#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
|
||||
#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
|
||||
|
||||
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
||||
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
|
||||
@@ -423,7 +423,7 @@ static struct unix_syscall {
|
||||
#else
|
||||
{ "pwrite64", (sqlite3_syscall_ptr)0, 0 },
|
||||
#endif
|
||||
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
|
||||
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
|
||||
aSyscall[13].pCurrent)
|
||||
|
||||
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
|
||||
@@ -1502,7 +1502,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
** lock transitions in terms of the POSIX advisory shared and exclusive
|
||||
** lock primitives (called read-locks and write-locks below, to avoid
|
||||
** confusion with SQLite lock names). The algorithms are complicated
|
||||
** slightly in order to be compatible with windows systems simultaneously
|
||||
** slightly in order to be compatible with Windows95 systems simultaneously
|
||||
** accessing the same database file, in case that is ever required.
|
||||
**
|
||||
** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
|
||||
@@ -1510,8 +1510,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
** range', a range of 510 bytes at a well known offset.
|
||||
**
|
||||
** To obtain a SHARED lock, a read-lock is obtained on the 'pending
|
||||
** byte'. If this is successful, a random byte from the 'shared byte
|
||||
** range' is read-locked and the lock on the 'pending byte' released.
|
||||
** byte'. If this is successful, 'shared byte range' is read-locked
|
||||
** and the lock on the 'pending byte' released. (Legacy note: When
|
||||
** SQLite was first developed, Windows95 systems were still very common,
|
||||
** and Widnows95 lacks a shared-lock capability. So on Windows95, a
|
||||
** single randomly selected by from the 'shared byte range' is locked.
|
||||
** Windows95 is now pretty much extinct, but this work-around for the
|
||||
** lack of shared-locks on Windows95 lives on, for backwards
|
||||
** compatibility.)
|
||||
**
|
||||
** A process may only obtain a RESERVED lock after it has a SHARED lock.
|
||||
** A RESERVED lock is implemented by grabbing a write-lock on the
|
||||
@@ -1530,11 +1536,6 @@ static int unixLock(sqlite3_file *id, int eFileLock){
|
||||
** range'. Since all other locks require a read-lock on one of the bytes
|
||||
** within this range, this ensures that no other locks are held on the
|
||||
** database.
|
||||
**
|
||||
** The reason a single byte cannot be used instead of the 'shared byte
|
||||
** range' is that some versions of windows do not support read-locks. By
|
||||
** locking a random byte from a range, concurrent SHARED locks may exist
|
||||
** even if the locking primitive used is always a write-lock.
|
||||
*/
|
||||
int rc = SQLITE_OK;
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
@@ -4287,10 +4288,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
pShmNode->h = -1;
|
||||
pDbFd->pInode->pShmNode = pShmNode;
|
||||
pShmNode->pInode = pDbFd->pInode;
|
||||
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
if( pShmNode->mutex==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto shm_open_err;
|
||||
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
if( pShmNode->mutex==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto shm_open_err;
|
||||
}
|
||||
}
|
||||
|
||||
if( pInode->bProcessLock==0 ){
|
||||
@@ -5415,14 +5418,14 @@ static const char *unixTempFileDir(void){
|
||||
|
||||
if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
|
||||
if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
|
||||
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
|
||||
for(i=0; i<=sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
|
||||
if( zDir==0 ) continue;
|
||||
if( osStat(zDir, &buf) ) continue;
|
||||
if( !S_ISDIR(buf.st_mode) ) continue;
|
||||
if( osAccess(zDir, 07) ) continue;
|
||||
break;
|
||||
if( osAccess(zDir, 03) ) continue;
|
||||
return zDir;
|
||||
}
|
||||
return zDir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5438,9 +5441,11 @@ static int unixGetTempname(int nBuf, char *zBuf){
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
** function failing.
|
||||
*/
|
||||
zBuf[0] = 0;
|
||||
SimulateIOError( return SQLITE_IOERR );
|
||||
|
||||
zDir = unixTempFileDir();
|
||||
if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
|
||||
do{
|
||||
u64 r;
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
|
||||
+195
-86
@@ -1260,8 +1260,8 @@ int sqlite3_win32_reset_heap(){
|
||||
int rc;
|
||||
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
|
||||
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
|
||||
MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
|
||||
MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
|
||||
MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
|
||||
MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
|
||||
sqlite3_mutex_enter(pMaster);
|
||||
sqlite3_mutex_enter(pMem);
|
||||
winMemAssertMagic();
|
||||
@@ -1306,6 +1306,12 @@ void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
|
||||
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
|
||||
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
|
||||
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !zBuf ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_WIN32_HAS_ANSI)
|
||||
if( nMin>0 ){
|
||||
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
|
||||
@@ -1631,147 +1637,244 @@ void sqlite3MemSetDefault(void){
|
||||
#endif /* SQLITE_WIN32_MALLOC */
|
||||
|
||||
/*
|
||||
** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
|
||||
** Convert a UTF-8 string to Microsoft Unicode.
|
||||
**
|
||||
** Space to hold the returned string is obtained from malloc.
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
static LPWSTR winUtf8ToUnicode(const char *zFilename){
|
||||
static LPWSTR winUtf8ToUnicode(const char *zText){
|
||||
int nChar;
|
||||
LPWSTR zWideFilename;
|
||||
LPWSTR zWideText;
|
||||
|
||||
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
|
||||
nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
|
||||
if( nChar==0 ){
|
||||
return 0;
|
||||
}
|
||||
zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
|
||||
if( zWideFilename==0 ){
|
||||
zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) );
|
||||
if( zWideText==0 ){
|
||||
return 0;
|
||||
}
|
||||
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
|
||||
nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
|
||||
nChar);
|
||||
if( nChar==0 ){
|
||||
sqlite3_free(zWideFilename);
|
||||
zWideFilename = 0;
|
||||
sqlite3_free(zWideText);
|
||||
zWideText = 0;
|
||||
}
|
||||
return zWideFilename;
|
||||
return zWideText;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is
|
||||
** obtained from sqlite3_malloc().
|
||||
** Convert a Microsoft Unicode string to UTF-8.
|
||||
**
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
|
||||
static char *winUnicodeToUtf8(LPCWSTR zWideText){
|
||||
int nByte;
|
||||
char *zFilename;
|
||||
char *zText;
|
||||
|
||||
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
|
||||
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
|
||||
if( nByte == 0 ){
|
||||
return 0;
|
||||
}
|
||||
zFilename = sqlite3MallocZero( nByte );
|
||||
if( zFilename==0 ){
|
||||
zText = sqlite3MallocZero( nByte );
|
||||
if( zText==0 ){
|
||||
return 0;
|
||||
}
|
||||
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
|
||||
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
|
||||
0, 0);
|
||||
if( nByte == 0 ){
|
||||
sqlite3_free(zFilename);
|
||||
zFilename = 0;
|
||||
sqlite3_free(zText);
|
||||
zText = 0;
|
||||
}
|
||||
return zFilename;
|
||||
return zText;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert an ANSI string to Microsoft Unicode, based on the
|
||||
** current codepage settings for file apis.
|
||||
** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM
|
||||
** code page.
|
||||
**
|
||||
** Space to hold the returned string is obtained
|
||||
** from sqlite3_malloc.
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
static LPWSTR winMbcsToUnicode(const char *zFilename){
|
||||
static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){
|
||||
int nByte;
|
||||
LPWSTR zMbcsFilename;
|
||||
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
||||
LPWSTR zMbcsText;
|
||||
int codepage = useAnsi ? CP_ACP : CP_OEMCP;
|
||||
|
||||
nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
|
||||
nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL,
|
||||
0)*sizeof(WCHAR);
|
||||
if( nByte==0 ){
|
||||
return 0;
|
||||
}
|
||||
zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
|
||||
if( zMbcsFilename==0 ){
|
||||
zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) );
|
||||
if( zMbcsText==0 ){
|
||||
return 0;
|
||||
}
|
||||
nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
|
||||
nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText,
|
||||
nByte);
|
||||
if( nByte==0 ){
|
||||
sqlite3_free(zMbcsFilename);
|
||||
zMbcsFilename = 0;
|
||||
sqlite3_free(zMbcsText);
|
||||
zMbcsText = 0;
|
||||
}
|
||||
return zMbcsFilename;
|
||||
return zMbcsText;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert Microsoft Unicode to multi-byte character string, based on the
|
||||
** user's ANSI codepage.
|
||||
** Convert a Microsoft Unicode string to a multi-byte character string,
|
||||
** using the ANSI or OEM code page.
|
||||
**
|
||||
** Space to hold the returned string is obtained from
|
||||
** sqlite3_malloc().
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
|
||||
static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){
|
||||
int nByte;
|
||||
char *zFilename;
|
||||
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
||||
char *zText;
|
||||
int codepage = useAnsi ? CP_ACP : CP_OEMCP;
|
||||
|
||||
nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
|
||||
nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0);
|
||||
if( nByte == 0 ){
|
||||
return 0;
|
||||
}
|
||||
zFilename = sqlite3MallocZero( nByte );
|
||||
if( zFilename==0 ){
|
||||
zText = sqlite3MallocZero( nByte );
|
||||
if( zText==0 ){
|
||||
return 0;
|
||||
}
|
||||
nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
|
||||
nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText,
|
||||
nByte, 0, 0);
|
||||
if( nByte == 0 ){
|
||||
sqlite3_free(zFilename);
|
||||
zFilename = 0;
|
||||
sqlite3_free(zText);
|
||||
zText = 0;
|
||||
}
|
||||
return zFilename;
|
||||
return zText;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert multibyte character string to UTF-8. Space to hold the
|
||||
** returned string is obtained from sqlite3_malloc().
|
||||
** Convert a multi-byte character string to UTF-8.
|
||||
**
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
|
||||
char *zFilenameUtf8;
|
||||
static char *winMbcsToUtf8(const char *zText, int useAnsi){
|
||||
char *zTextUtf8;
|
||||
LPWSTR zTmpWide;
|
||||
|
||||
zTmpWide = winMbcsToUnicode(zFilename);
|
||||
zTmpWide = winMbcsToUnicode(zText, useAnsi);
|
||||
if( zTmpWide==0 ){
|
||||
return 0;
|
||||
}
|
||||
zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
|
||||
zTextUtf8 = winUnicodeToUtf8(zTmpWide);
|
||||
sqlite3_free(zTmpWide);
|
||||
return zFilenameUtf8;
|
||||
return zTextUtf8;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert UTF-8 to multibyte character string. Space to hold the
|
||||
** returned string is obtained from sqlite3_malloc().
|
||||
** Convert a UTF-8 string to a multi-byte character string.
|
||||
**
|
||||
** Space to hold the returned string is obtained from sqlite3_malloc().
|
||||
*/
|
||||
char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
|
||||
char *zFilenameMbcs;
|
||||
static char *winUtf8ToMbcs(const char *zText, int useAnsi){
|
||||
char *zTextMbcs;
|
||||
LPWSTR zTmpWide;
|
||||
|
||||
zTmpWide = winUtf8ToUnicode(zFilename);
|
||||
zTmpWide = winUtf8ToUnicode(zText);
|
||||
if( zTmpWide==0 ){
|
||||
return 0;
|
||||
}
|
||||
zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
|
||||
zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi);
|
||||
sqlite3_free(zTmpWide);
|
||||
return zFilenameMbcs;
|
||||
return zTextMbcs;
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a public wrapper for the winUtf8ToUnicode() function.
|
||||
*/
|
||||
LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !zText ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
return winUtf8ToUnicode(zText);
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a public wrapper for the winUnicodeToUtf8() function.
|
||||
*/
|
||||
char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !zWideText ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
return winUnicodeToUtf8(zWideText);
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a public wrapper for the winMbcsToUtf8() function.
|
||||
*/
|
||||
char *sqlite3_win32_mbcs_to_utf8(const char *zText){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !zText ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
return winMbcsToUtf8(zText, osAreFileApisANSI());
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a public wrapper for the winMbcsToUtf8() function.
|
||||
*/
|
||||
char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !zText ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
return winMbcsToUtf8(zText, useAnsi);
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a public wrapper for the winUtf8ToMbcs() function.
|
||||
*/
|
||||
char *sqlite3_win32_utf8_to_mbcs(const char *zText){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !zText ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
return winUtf8ToMbcs(zText, osAreFileApisANSI());
|
||||
}
|
||||
|
||||
/*
|
||||
** This is a public wrapper for the winUtf8ToMbcs() function.
|
||||
*/
|
||||
char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !zText ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
return winUtf8ToMbcs(zText, useAnsi);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1873,7 +1976,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
|
||||
if( dwLen > 0 ){
|
||||
/* allocate a buffer and convert to UTF8 */
|
||||
sqlite3BeginBenignMalloc();
|
||||
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
|
||||
zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
|
||||
sqlite3EndBenignMalloc();
|
||||
/* free the system buffer allocated by FormatMessage */
|
||||
osLocalFree(zTemp);
|
||||
@@ -2015,16 +2118,17 @@ static void winLogIoerr(int nRetry, int lineno){
|
||||
}
|
||||
}
|
||||
|
||||
#if SQLITE_OS_WINCE
|
||||
/*************************************************************************
|
||||
** This section contains code for WinCE only.
|
||||
*/
|
||||
#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
|
||||
/*
|
||||
** The MSVC CRT on Windows CE may not have a localtime() function. So
|
||||
** create a substitute.
|
||||
** This #if does not rely on the SQLITE_OS_WINCE define because the
|
||||
** corresponding section in "date.c" cannot use it.
|
||||
*/
|
||||
#include <time.h>
|
||||
#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
|
||||
(!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
|
||||
/*
|
||||
** The MSVC CRT on Windows CE may not have a localtime() function.
|
||||
** So define a substitute.
|
||||
*/
|
||||
# include <time.h>
|
||||
struct tm *__cdecl localtime(const time_t *t)
|
||||
{
|
||||
static struct tm y;
|
||||
@@ -2048,6 +2152,10 @@ struct tm *__cdecl localtime(const time_t *t)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_OS_WINCE
|
||||
/*************************************************************************
|
||||
** This section contains code for WinCE only.
|
||||
*/
|
||||
#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
|
||||
|
||||
/*
|
||||
@@ -3061,9 +3169,8 @@ static int winLock(sqlite3_file *id, int locktype){
|
||||
** the PENDING_LOCK byte is temporary.
|
||||
*/
|
||||
newLocktype = pFile->locktype;
|
||||
if( (pFile->locktype==NO_LOCK)
|
||||
|| ( (locktype==EXCLUSIVE_LOCK)
|
||||
&& (pFile->locktype==RESERVED_LOCK))
|
||||
if( pFile->locktype==NO_LOCK
|
||||
|| (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
|
||||
){
|
||||
int cnt = 3;
|
||||
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
|
||||
@@ -3657,10 +3764,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
||||
pShmNode->pNext = winShmNodeList;
|
||||
winShmNodeList = pShmNode;
|
||||
|
||||
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
if( pShmNode->mutex==0 ){
|
||||
rc = SQLITE_IOERR_NOMEM_BKPT;
|
||||
goto shm_open_err;
|
||||
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
if( pShmNode->mutex==0 ){
|
||||
rc = SQLITE_IOERR_NOMEM_BKPT;
|
||||
goto shm_open_err;
|
||||
}
|
||||
}
|
||||
|
||||
rc = winOpen(pDbFd->pVfs,
|
||||
@@ -4318,7 +4427,7 @@ static char *winConvertToUtf8Filename(const void *zFilename){
|
||||
}
|
||||
#ifdef SQLITE_WIN32_HAS_ANSI
|
||||
else{
|
||||
zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
|
||||
zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
|
||||
}
|
||||
#endif
|
||||
/* caller will handle out of memory */
|
||||
@@ -4339,7 +4448,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){
|
||||
}
|
||||
#ifdef SQLITE_WIN32_HAS_ANSI
|
||||
else{
|
||||
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
|
||||
zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
|
||||
}
|
||||
#endif
|
||||
/* caller will handle out of memory */
|
||||
@@ -4540,7 +4649,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
|
||||
return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
|
||||
"winGetTempname3", 0);
|
||||
}
|
||||
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
|
||||
zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI());
|
||||
if( zUtf8 ){
|
||||
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
|
||||
sqlite3_free(zUtf8);
|
||||
@@ -5318,7 +5427,7 @@ static int winFullPathname(
|
||||
"winFullPathname4", zRelative);
|
||||
}
|
||||
sqlite3_free(zConverted);
|
||||
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
|
||||
zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
|
||||
sqlite3_free(zTemp);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7311,6 +7311,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
||||
pPager->pageSize, (u8*)pPager->pTmpSpace);
|
||||
pPager->pWal = 0;
|
||||
pagerFixMaplimit(pPager);
|
||||
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
+10
-1
@@ -68,7 +68,11 @@ typedef struct PgHdr DbPage;
|
||||
#define PAGER_LOCKINGMODE_EXCLUSIVE 1
|
||||
|
||||
/*
|
||||
** Numeric constants that encode the journalmode.
|
||||
** Numeric constants that encode the journalmode.
|
||||
**
|
||||
** The numeric values encoded here (other than PAGER_JOURNALMODE_QUERY)
|
||||
** are exposed in the API via the "PRAGMA journal_mode" command and
|
||||
** therefore cannot be changed without a compatibility break.
|
||||
*/
|
||||
#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */
|
||||
#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */
|
||||
@@ -86,6 +90,11 @@ typedef struct PgHdr DbPage;
|
||||
|
||||
/*
|
||||
** Flags for sqlite3PagerSetFlags()
|
||||
**
|
||||
** Value constraints (enforced via assert()):
|
||||
** PAGER_FULLFSYNC == SQLITE_FullFSync
|
||||
** PAGER_CKPT_FULLFSYNC == SQLITE_CkptFullFSync
|
||||
** PAGER_CACHE_SPILL == SQLITE_CacheSpill
|
||||
*/
|
||||
#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */
|
||||
#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */
|
||||
|
||||
+34
-55
@@ -194,28 +194,6 @@ columnlist ::= columnlist COMMA columnname carglist.
|
||||
columnlist ::= columnname carglist.
|
||||
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
|
||||
|
||||
// An IDENTIFIER can be a generic identifier, or one of several
|
||||
// keywords. Any non-standard keyword can also be an identifier.
|
||||
//
|
||||
%token_class id ID|INDEXED.
|
||||
|
||||
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
|
||||
// fallback to ID if they will not parse as their original value.
|
||||
// This obviates the need for the "id" nonterminal.
|
||||
//
|
||||
%fallback ID
|
||||
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
|
||||
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
|
||||
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
|
||||
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
|
||||
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
|
||||
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||
EXCEPT INTERSECT UNION
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
REINDEX RENAME CTIME_KW IF
|
||||
.
|
||||
%wildcard ANY.
|
||||
|
||||
// Define operator precedence early so that this is the first occurrence
|
||||
// of the operator tokens in the grammer. Keeping the operators together
|
||||
// causes them to be assigned integer values that are close together,
|
||||
@@ -240,6 +218,29 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
|
||||
%left COLLATE.
|
||||
%right BITNOT.
|
||||
|
||||
// An IDENTIFIER can be a generic identifier, or one of several
|
||||
// keywords. Any non-standard keyword can also be an identifier.
|
||||
//
|
||||
%token_class id ID|INDEXED.
|
||||
|
||||
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
|
||||
// fallback to ID if they will not parse as their original value.
|
||||
// This obviates the need for the "id" nonterminal.
|
||||
//
|
||||
%fallback ID
|
||||
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
|
||||
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
|
||||
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
|
||||
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
|
||||
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
|
||||
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||
EXCEPT INTERSECT UNION
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
REINDEX RENAME CTIME_KW IF
|
||||
.
|
||||
%wildcard ANY.
|
||||
|
||||
|
||||
// And "ids" is an identifer-or-string.
|
||||
//
|
||||
%token_class ids ID|STRING.
|
||||
@@ -871,11 +872,15 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
|
||||
term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
|
||||
term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
|
||||
expr(A) ::= VARIABLE(X). {
|
||||
Token t = X; /*A-overwrites-X*/
|
||||
if( t.n>=2 && t.z[0]=='#' && sqlite3Isdigit(t.z[1]) ){
|
||||
if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
|
||||
spanExpr(&A, pParse, TK_VARIABLE, X);
|
||||
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
|
||||
}else{
|
||||
/* When doing a nested parse, one can include terms in an expression
|
||||
** that look like this: #1 #2 ... These terms refer to registers
|
||||
** in the virtual machine. #N is the N-th register. */
|
||||
Token t = X; /*A-overwrites-X*/
|
||||
assert( t.n>=2 );
|
||||
spanSet(&A, &t, &t);
|
||||
if( pParse->nested==0 ){
|
||||
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
|
||||
@@ -884,9 +889,6 @@ expr(A) ::= VARIABLE(X). {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
|
||||
if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable);
|
||||
}
|
||||
}else{
|
||||
spanExpr(&A, pParse, TK_VARIABLE, t);
|
||||
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
|
||||
}
|
||||
}
|
||||
expr(A) ::= expr(A) COLLATE ids(C). {
|
||||
@@ -1122,36 +1124,19 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
expr(A) ::= LP(B) select(X) RP(E). {
|
||||
spanSet(&A,&B,&E); /*A-overwrites-B*/
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = X;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
}
|
||||
sqlite3PExprAddSelect(pParse, A.pExpr, X);
|
||||
}
|
||||
expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = Y;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
}
|
||||
sqlite3PExprAddSelect(pParse, A.pExpr, Y);
|
||||
exprNot(pParse, N, &A);
|
||||
A.zEnd = &E.z[E.n];
|
||||
}
|
||||
expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
|
||||
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
|
||||
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SrcListDelete(pParse->db, pSrc);
|
||||
}
|
||||
sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
|
||||
exprNot(pParse, N, &A);
|
||||
A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
|
||||
}
|
||||
@@ -1159,13 +1144,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
Expr *p;
|
||||
spanSet(&A,&B,&E); /*A-overwrites-B*/
|
||||
p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
|
||||
if( p ){
|
||||
p->x.pSelect = Y;
|
||||
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, p);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
}
|
||||
sqlite3PExprAddSelect(pParse, p, Y);
|
||||
}
|
||||
%endif SQLITE_OMIT_SUBQUERY
|
||||
|
||||
|
||||
+2
-2
@@ -690,8 +690,8 @@ static int pcache1Init(void *NotUsed){
|
||||
|
||||
#if SQLITE_THREADSAFE
|
||||
if( sqlite3GlobalConfig.bCoreMutex ){
|
||||
pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
|
||||
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
|
||||
pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU);
|
||||
pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM);
|
||||
}
|
||||
#endif
|
||||
if( pcache1.separateCache
|
||||
|
||||
+43
-20
@@ -74,7 +74,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
sqlite3ExprDelete(db, p->pLimit);
|
||||
sqlite3ExprDelete(db, p->pOffset);
|
||||
sqlite3WithDelete(db, p->pWith);
|
||||
if( p->pWith ) sqlite3WithDelete(db, p->pWith);
|
||||
if( bFree ) sqlite3DbFree(db, p);
|
||||
p = pPrior;
|
||||
bFree = 1;
|
||||
@@ -169,7 +169,7 @@ void sqlite3SelectSetName(Select *p, const char *zName){
|
||||
** Delete the given Select structure and all of its substructures.
|
||||
*/
|
||||
void sqlite3SelectDelete(sqlite3 *db, Select *p){
|
||||
clearSelect(db, p, 1);
|
||||
if( p ) clearSelect(db, p, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1704,7 +1704,7 @@ int sqlite3ColumnsFromExprList(
|
||||
** This routine requires that all identifiers in the SELECT
|
||||
** statement be resolved.
|
||||
*/
|
||||
static void selectAddColumnTypeAndCollation(
|
||||
void sqlite3SelectAddColumnTypeAndCollation(
|
||||
Parse *pParse, /* Parsing contexts */
|
||||
Table *pTab, /* Add column type information to this table */
|
||||
Select *pSelect /* SELECT used to determine types and collations */
|
||||
@@ -1726,10 +1726,20 @@ static void selectAddColumnTypeAndCollation(
|
||||
sNC.pSrcList = pSelect->pSrc;
|
||||
a = pSelect->pEList->a;
|
||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||
const char *zType;
|
||||
int n, m;
|
||||
p = a[i].pExpr;
|
||||
columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
|
||||
zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
|
||||
szAll += pCol->szEst;
|
||||
pCol->affinity = sqlite3ExprAffinity(p);
|
||||
if( zType && (m = sqlite3Strlen30(zType))>0 ){
|
||||
n = sqlite3Strlen30(pCol->zName);
|
||||
pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
|
||||
if( pCol->zName ){
|
||||
memcpy(&pCol->zName[n+1], zType, m+1);
|
||||
pCol->colFlags |= COLFLAG_HASTYPE;
|
||||
}
|
||||
}
|
||||
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
|
||||
pColl = sqlite3ExprCollSeq(pParse, p);
|
||||
if( pColl && pCol->zColl==0 ){
|
||||
@@ -1766,7 +1776,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
|
||||
pTab->zName = 0;
|
||||
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
|
||||
sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
|
||||
selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
|
||||
pTab->iPKey = -1;
|
||||
if( db->mallocFailed ){
|
||||
sqlite3DeleteTable(db, pTab);
|
||||
@@ -1779,20 +1789,20 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
|
||||
** Get a VDBE for the given parser context. Create a new one if necessary.
|
||||
** If an error occurs, return NULL and leave a message in pParse.
|
||||
*/
|
||||
Vdbe *sqlite3GetVdbe(Parse *pParse){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
if( v==0 ){
|
||||
v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
|
||||
if( v ) sqlite3VdbeAddOp0(v, OP_Init);
|
||||
if( pParse->pToplevel==0
|
||||
&& OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
|
||||
){
|
||||
pParse->okConstFactor = 1;
|
||||
}
|
||||
|
||||
static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
|
||||
Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
|
||||
if( v ) sqlite3VdbeAddOp0(v, OP_Init);
|
||||
if( pParse->pToplevel==0
|
||||
&& OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
|
||||
){
|
||||
pParse->okConstFactor = 1;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
Vdbe *sqlite3GetVdbe(Parse *pParse){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
return v ? v : allocVdbe(pParse);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -3775,12 +3785,18 @@ static int pushDownWhereTerms(
|
||||
){
|
||||
Expr *pNew;
|
||||
int nChng = 0;
|
||||
Select *pX; /* For looping over compound SELECTs in pSubq */
|
||||
if( pWhere==0 ) return 0;
|
||||
if( (pSubq->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
|
||||
return 0; /* restrictions (1) and (2) */
|
||||
for(pX=pSubq; pX; pX=pX->pPrior){
|
||||
if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
|
||||
testcase( pX->selFlags & SF_Aggregate );
|
||||
testcase( pX->selFlags & SF_Recursive );
|
||||
testcase( pX!=pSubq );
|
||||
return 0; /* restrictions (1) and (2) */
|
||||
}
|
||||
}
|
||||
if( pSubq->pLimit!=0 ){
|
||||
return 0; /* restriction (3) */
|
||||
return 0; /* restriction (3) */
|
||||
}
|
||||
while( pWhere->op==TK_AND ){
|
||||
nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
|
||||
@@ -4550,7 +4566,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
|
||||
Select *pSel = pFrom->pSelect;
|
||||
if( pSel ){
|
||||
while( pSel->pPrior ) pSel = pSel->pPrior;
|
||||
selectAddColumnTypeAndCollation(pParse, pTab, pSel);
|
||||
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5082,6 +5098,13 @@ int sqlite3Select(
|
||||
** the sDistinct.isTnct is still set. Hence, isTnct represents the
|
||||
** original setting of the SF_Distinct flag, not the current setting */
|
||||
assert( sDistinct.isTnct );
|
||||
|
||||
#if SELECTTRACE_ENABLED
|
||||
if( sqlite3SelectTrace & 0x400 ){
|
||||
SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If there is an ORDER BY clause, then create an ephemeral index to
|
||||
|
||||
+500
-248
File diff suppressed because it is too large
Load Diff
+93
-18
@@ -1932,12 +1932,30 @@ struct sqlite3_mem_methods {
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the new setting is not reported back. </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
|
||||
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
|
||||
** interface independently of the [load_extension()] SQL function.
|
||||
** The [sqlite3_enable_load_extension()] API enables or disables both the
|
||||
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
|
||||
** There should be two additional arguments.
|
||||
** When the first argument to this interface is 1, then only the C-API is
|
||||
** enabled and the SQL function remains disabled. If the first argment to
|
||||
** this interface is 0, then both the C-API and the SQL function are disabled.
|
||||
** If the first argument is -1, then no changes are made to state of either the
|
||||
** C-API or the SQL function.
|
||||
** The second parameter is a pointer to an integer into which
|
||||
** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
|
||||
** is disabled or enabled following this call. The second parameter may
|
||||
** be a NULL pointer, in which case the new setting is not reported back.
|
||||
** </dd>
|
||||
**
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
|
||||
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
|
||||
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
|
||||
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
|
||||
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
|
||||
|
||||
|
||||
/*
|
||||
@@ -5187,7 +5205,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
|
||||
** ^The sqlite3_update_hook() interface registers a callback function
|
||||
** with the [database connection] identified by the first argument
|
||||
** to be invoked whenever a row is updated, inserted or deleted in
|
||||
** a rowid table.
|
||||
** a [rowid table].
|
||||
** ^Any callback set by a previous call to this function
|
||||
** for the same database connection is overridden.
|
||||
**
|
||||
@@ -5474,9 +5492,18 @@ int sqlite3_table_column_metadata(
|
||||
** should free this memory by calling [sqlite3_free()].
|
||||
**
|
||||
** ^Extension loading must be enabled using
|
||||
** [sqlite3_enable_load_extension()] prior to calling this API,
|
||||
** [sqlite3_enable_load_extension()] or
|
||||
** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
|
||||
** prior to calling this API,
|
||||
** otherwise an error will be returned.
|
||||
**
|
||||
** <b>Security warning:</b> It is recommended that the
|
||||
** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
|
||||
** interface. The use of the [sqlite3_enable_load_extension()] interface
|
||||
** should be avoided. This will keep the SQL function [load_extension()]
|
||||
** disabled and prevent SQL injections from giving attackers
|
||||
** access to extension loading capabilities.
|
||||
**
|
||||
** See also the [load_extension() SQL function].
|
||||
*/
|
||||
int sqlite3_load_extension(
|
||||
@@ -5499,6 +5526,17 @@ int sqlite3_load_extension(
|
||||
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
|
||||
** to turn extension loading on and call it with onoff==0 to turn
|
||||
** it back off again.
|
||||
**
|
||||
** ^This interface enables or disables both the C-API
|
||||
** [sqlite3_load_extension()] and the SQL function [load_extension()].
|
||||
** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
|
||||
** to enable or disable only the C-API.
|
||||
**
|
||||
** <b>Security warning:</b> It is recommended that extension loading
|
||||
** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
|
||||
** rather than this interface, so the [load_extension()] SQL function
|
||||
** remains disabled. This will prevent SQL injections from giving attackers
|
||||
** access to extension loading capabilities.
|
||||
*/
|
||||
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
|
||||
|
||||
@@ -6761,7 +6799,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
** database file in rollback mode databases. Any pages written as part of
|
||||
** transaction rollback or database recovery operations are not included.
|
||||
** If an IO or other error occurs while writing a page to disk, the effect
|
||||
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined). ^The
|
||||
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
|
||||
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
|
||||
** </dd>
|
||||
**
|
||||
@@ -7137,7 +7175,7 @@ typedef struct sqlite3_backup sqlite3_backup;
|
||||
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
|
||||
** an error.
|
||||
**
|
||||
** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if
|
||||
** ^A call to sqlite3_backup_init() will fail, returning NULL, if
|
||||
** there is already a read or read-write transaction open on the
|
||||
** destination database.
|
||||
**
|
||||
@@ -7917,13 +7955,13 @@ int sqlite3_db_cacheflush(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: The pre-update hook.
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** ^These interfaces are only available if SQLite is compiled using the
|
||||
** [SQLITE_ENABLE_UPDATE_HOOK] compile-time option.
|
||||
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
|
||||
**
|
||||
** ^The [sqlite3_preupdate_hook()] interface registers a callback function
|
||||
** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation.
|
||||
** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
|
||||
** on a [rowid table].
|
||||
** ^At most one preupdate hook may be registered at a time on a single
|
||||
** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
|
||||
** the previous setting.
|
||||
@@ -7932,8 +7970,9 @@ int sqlite3_db_cacheflush(sqlite3*);
|
||||
** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
|
||||
** the first parameter to callbacks.
|
||||
**
|
||||
** ^The preupdate hook only fires for changes to real tables; the preupdate
|
||||
** hook is not invoked for changes to virtual tables.
|
||||
** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate
|
||||
** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID]
|
||||
** tables.
|
||||
**
|
||||
** ^The second parameter to the preupdate callback is a pointer to
|
||||
** the [database connection] that registered the preupdate hook.
|
||||
@@ -8080,20 +8119,29 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||
** CAPI3REF: Start a read transaction on an historical snapshot
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
|
||||
** read transaction that is currently open on schema S of
|
||||
** [database connection] D so that it refers to historical [snapshot] P.
|
||||
** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
|
||||
** read transaction for schema S of
|
||||
** [database connection] D such that the read transaction
|
||||
** refers to historical [snapshot] P, rather than the most
|
||||
** recent change to the database.
|
||||
** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
|
||||
** or an appropriate [error code] if it fails.
|
||||
**
|
||||
** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
|
||||
** the first operation, apart from other sqlite3_snapshot_open() calls,
|
||||
** following the [BEGIN] that starts a new read transaction.
|
||||
** ^A [snapshot] will fail to open if it has been overwritten by a
|
||||
** the first operation following the [BEGIN] that takes the schema S
|
||||
** out of [autocommit mode].
|
||||
** ^In other words, schema S must not currently be in
|
||||
** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
|
||||
** database connection D must be out of [autocommit mode].
|
||||
** ^A [snapshot] will fail to open if it has been overwritten by a
|
||||
** [checkpoint].
|
||||
** ^A [snapshot] will fail to open if the database connection D has not
|
||||
** previously completed at least one read operation against the database
|
||||
** file. (Hint: Run "[PRAGMA application_id]" against a newly opened
|
||||
** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
|
||||
** database connection D does not know that the database file for
|
||||
** schema S is in [WAL mode]. A database connection might not know
|
||||
** that the database file is in [WAL mode] if there has been no prior
|
||||
** I/O on that database connection, or if the database entered [WAL mode]
|
||||
** after the most recent I/O on the database connection.)^
|
||||
** (Hint: Run "[PRAGMA application_id]" against a newly opened
|
||||
** database connection in order to make it ready to use snapshots.)
|
||||
**
|
||||
** The [sqlite3_snapshot_open()] interface is only available when the
|
||||
@@ -8118,6 +8166,33 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compare the ages of two snapshot handles.
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
|
||||
** of two valid snapshot handles.
|
||||
**
|
||||
** If the two snapshot handles are not associated with the same database
|
||||
** file, the result of the comparison is undefined.
|
||||
**
|
||||
** Additionally, the result of the comparison is only valid if both of the
|
||||
** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
|
||||
** last time the wal file was deleted. The wal file is deleted when the
|
||||
** database is changed back to rollback mode or when the number of database
|
||||
** clients drops to zero. If either snapshot handle was obtained before the
|
||||
** wal file was last deleted, the value returned by this function
|
||||
** is undefined.
|
||||
**
|
||||
** Otherwise, this API returns a negative value if P1 refers to an older
|
||||
** snapshot than P2, zero if the two handles refer to the same database
|
||||
** snapshot, and a positive value if P1 is a newer snapshot than P2.
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||
sqlite3_snapshot *p1,
|
||||
sqlite3_snapshot *p2
|
||||
);
|
||||
|
||||
/*
|
||||
** Undo the hack that converts floating point types to integer for
|
||||
** builds on processors without floating point support.
|
||||
|
||||
+60
-23
@@ -1350,6 +1350,11 @@ struct sqlite3 {
|
||||
|
||||
/*
|
||||
** Possible values for the sqlite3.flags.
|
||||
**
|
||||
** Value constraints (enforced via assert()):
|
||||
** SQLITE_FullFSync == PAGER_FULLFSYNC
|
||||
** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
|
||||
** SQLITE_CacheSpill == PAGER_CACHE_SPILL
|
||||
*/
|
||||
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
|
||||
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
|
||||
@@ -1377,13 +1382,14 @@ struct sqlite3 {
|
||||
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
|
||||
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
|
||||
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
|
||||
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
|
||||
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
|
||||
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
|
||||
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
|
||||
#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */
|
||||
#define SQLITE_Fts3Tokenizer 0x20000000 /* Enable fts3_tokenizer(2) */
|
||||
#define SQLITE_LoadExtFunc 0x00800000 /* Enable load_extension() SQL func */
|
||||
#define SQLITE_EnableTrigger 0x01000000 /* True to enable triggers */
|
||||
#define SQLITE_DeferFKs 0x02000000 /* Defer all FK constraints */
|
||||
#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
|
||||
#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
|
||||
#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
|
||||
#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
|
||||
|
||||
|
||||
/*
|
||||
@@ -1484,6 +1490,13 @@ struct FuncDestructor {
|
||||
** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And
|
||||
** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There
|
||||
** are assert() statements in the code to verify this.
|
||||
**
|
||||
** Value constraints (enforced via assert()):
|
||||
** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg
|
||||
** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG
|
||||
** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG
|
||||
** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API
|
||||
** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API
|
||||
*/
|
||||
#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
|
||||
#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */
|
||||
@@ -2483,6 +2496,9 @@ struct SrcList {
|
||||
/*
|
||||
** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
|
||||
** and the WhereInfo.wctrlFlags member.
|
||||
**
|
||||
** Value constraints (enforced via assert()):
|
||||
** WHERE_USE_LIMIT == SF_FixedLimit
|
||||
*/
|
||||
#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
|
||||
#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
|
||||
@@ -2543,15 +2559,16 @@ struct NameContext {
|
||||
/*
|
||||
** Allowed values for the NameContext, ncFlags field.
|
||||
**
|
||||
** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
|
||||
** SQLITE_FUNC_MINMAX.
|
||||
** Value constraints (all checked via assert()):
|
||||
** NC_HasAgg == SF_HasAgg
|
||||
** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
|
||||
**
|
||||
*/
|
||||
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
|
||||
#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */
|
||||
#define NC_PartIdx 0x0002 /* True if resolving a partial index WHERE */
|
||||
#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */
|
||||
#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */
|
||||
#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */
|
||||
#define NC_HasAgg 0x0010 /* One or more aggregate functions seen */
|
||||
#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
|
||||
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
|
||||
|
||||
@@ -2600,24 +2617,30 @@ struct Select {
|
||||
/*
|
||||
** Allowed values for Select.selFlags. The "SF" prefix stands for
|
||||
** "Select Flag".
|
||||
**
|
||||
** Value constraints (all checked via assert())
|
||||
** SF_HasAgg == NC_HasAgg
|
||||
** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX
|
||||
** SF_FixedLimit == WHERE_USE_LIMIT
|
||||
*/
|
||||
#define SF_Distinct 0x00001 /* Output should be DISTINCT */
|
||||
#define SF_All 0x00002 /* Includes the ALL keyword */
|
||||
#define SF_Resolved 0x00004 /* Identifiers have been resolved */
|
||||
#define SF_Aggregate 0x00008 /* Contains aggregate functions */
|
||||
#define SF_UsesEphemeral 0x00010 /* Uses the OpenEphemeral opcode */
|
||||
#define SF_Expanded 0x00020 /* sqlite3SelectExpand() called on this */
|
||||
#define SF_HasTypeInfo 0x00040 /* FROM subqueries have Table metadata */
|
||||
#define SF_Compound 0x00080 /* Part of a compound query */
|
||||
#define SF_Values 0x00100 /* Synthesized from VALUES clause */
|
||||
#define SF_MultiValue 0x00200 /* Single VALUES term with multiple rows */
|
||||
#define SF_NestedFrom 0x00400 /* Part of a parenthesized FROM clause */
|
||||
#define SF_MaybeConvert 0x00800 /* Need convertCompoundSelectToSubquery() */
|
||||
#define SF_Aggregate 0x00008 /* Contains agg functions or a GROUP BY */
|
||||
#define SF_HasAgg 0x00010 /* Contains aggregate functions */
|
||||
#define SF_UsesEphemeral 0x00020 /* Uses the OpenEphemeral opcode */
|
||||
#define SF_Expanded 0x00040 /* sqlite3SelectExpand() called on this */
|
||||
#define SF_HasTypeInfo 0x00080 /* FROM subqueries have Table metadata */
|
||||
#define SF_Compound 0x00100 /* Part of a compound query */
|
||||
#define SF_Values 0x00200 /* Synthesized from VALUES clause */
|
||||
#define SF_MultiValue 0x00400 /* Single VALUES term with multiple rows */
|
||||
#define SF_NestedFrom 0x00800 /* Part of a parenthesized FROM clause */
|
||||
#define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */
|
||||
#define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */
|
||||
#define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */
|
||||
#define SF_Converted 0x08000 /* By convertCompoundSelectToSubquery() */
|
||||
#define SF_IncludeHidden 0x10000 /* Include hidden columns in output */
|
||||
#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */
|
||||
#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
|
||||
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
|
||||
|
||||
|
||||
/*
|
||||
@@ -2814,6 +2837,7 @@ struct Parse {
|
||||
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
|
||||
u8 okConstFactor; /* OK to factor out constants */
|
||||
u8 disableLookaside; /* Number of times lookaside has been disabled */
|
||||
u8 nColCache; /* Number of entries in aColCache[] */
|
||||
int aTempReg[8]; /* Holding area for temporary registers */
|
||||
int nRangeReg; /* Size of the temporary register block */
|
||||
int iRangeReg; /* First register in temporary register block */
|
||||
@@ -2927,6 +2951,15 @@ struct AuthContext {
|
||||
|
||||
/*
|
||||
** Bitfield flags for P5 value in various opcodes.
|
||||
**
|
||||
** Value constraints (enforced via assert()):
|
||||
** OPFLAG_LENGTHARG == SQLITE_FUNC_LENGTH
|
||||
** OPFLAG_TYPEOFARG == SQLITE_FUNC_TYPEOF
|
||||
** OPFLAG_BULKCSR == BTREE_BULKLOAD
|
||||
** OPFLAG_SEEKEQ == BTREE_SEEK_EQ
|
||||
** OPFLAG_FORDELETE == BTREE_FORDELETE
|
||||
** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
|
||||
** OPFLAG_AUXDELETE == BTREE_AUXDELETE
|
||||
*/
|
||||
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
|
||||
/* Also used in P2 (not P5) of OP_Delete */
|
||||
@@ -3301,6 +3334,7 @@ int sqlite3CantopenError(int);
|
||||
# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
|
||||
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
|
||||
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
|
||||
# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
|
||||
#else
|
||||
# define sqlite3Toupper(x) toupper((unsigned char)(x))
|
||||
# define sqlite3Isspace(x) isspace((unsigned char)(x))
|
||||
@@ -3309,6 +3343,7 @@ int sqlite3CantopenError(int);
|
||||
# define sqlite3Isdigit(x) isdigit((unsigned char)(x))
|
||||
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
|
||||
# define sqlite3Tolower(x) tolower((unsigned char)(x))
|
||||
# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
||||
int sqlite3IsIdChar(u8);
|
||||
@@ -3432,7 +3467,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||
|
||||
void sqlite3SetString(char **, sqlite3*, const char*);
|
||||
void sqlite3ErrorMsg(Parse*, const char*, ...);
|
||||
int sqlite3Dequote(char*);
|
||||
void sqlite3Dequote(char*);
|
||||
void sqlite3TokenInit(Token*,char*);
|
||||
int sqlite3KeywordCode(const unsigned char*, int);
|
||||
int sqlite3RunParser(Parse*, const char*, char **);
|
||||
@@ -3449,6 +3484,7 @@ Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
|
||||
Expr *sqlite3Expr(sqlite3*,int,const char*);
|
||||
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
|
||||
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
|
||||
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
|
||||
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
|
||||
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
|
||||
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
|
||||
@@ -3468,6 +3504,7 @@ void sqlite3CollapseDatabaseArray(sqlite3*);
|
||||
void sqlite3CommitInternalChanges(sqlite3*);
|
||||
void sqlite3DeleteColumnNames(sqlite3*,Table*);
|
||||
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
|
||||
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*);
|
||||
Table *sqlite3ResultSetOfSelect(Parse*,Select*);
|
||||
void sqlite3OpenMasterTable(Parse *, int);
|
||||
Index *sqlite3PrimaryKeyIndex(Table*);
|
||||
|
||||
+1
-1
@@ -3035,7 +3035,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
/* set ppHook to point at pUpdateHook or pRollbackHook, depending on
|
||||
** whether [$db update_hook] or [$db rollback_hook] was invoked.
|
||||
*/
|
||||
Tcl_Obj **ppHook;
|
||||
Tcl_Obj **ppHook = 0;
|
||||
if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
|
||||
if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
|
||||
if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
|
||||
|
||||
+33
-4
@@ -1271,7 +1271,7 @@ static int sqlite3_mprintf_int64(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for(i=2; i<5; i++){
|
||||
if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
|
||||
if( sqlite3Atoi64(argv[i], &a[i-2], sqlite3Strlen30(argv[i]), SQLITE_UTF8) ){
|
||||
Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2359,6 +2359,31 @@ static int test_snapshot_free(
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
/*
|
||||
** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2
|
||||
*/
|
||||
static int test_snapshot_cmp(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int res;
|
||||
sqlite3_snapshot *p1;
|
||||
sqlite3_snapshot *p2;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
p1 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
|
||||
p2 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[2]));
|
||||
res = sqlite3_snapshot_cmp(p1, p2);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_next_stmt DB STMT
|
||||
**
|
||||
@@ -5188,7 +5213,9 @@ static int vfs_unregister_all(
|
||||
/*
|
||||
** tclcmd: vfs_reregister_all
|
||||
**
|
||||
** Restore all VFSes that were removed using vfs_unregister_all
|
||||
** Restore all VFSes that were removed using vfs_unregister_all. Taking
|
||||
** care to put the linked list back together in the same order as it was
|
||||
** in before vfs_unregister_all was invoked.
|
||||
*/
|
||||
static int vfs_reregister_all(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
@@ -5197,8 +5224,8 @@ static int vfs_reregister_all(
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
int i;
|
||||
for(i=0; i<nVfs; i++){
|
||||
sqlite3_vfs_register(apVfs[i], i==0);
|
||||
for(i=nVfs-1; i>=0; i--){
|
||||
sqlite3_vfs_register(apVfs[i], 1);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -6963,6 +6990,7 @@ static int test_sqlite3_db_config(
|
||||
{ "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY },
|
||||
{ "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
||||
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||
{ "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
|
||||
};
|
||||
int i;
|
||||
int v;
|
||||
@@ -7249,6 +7277,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_snapshot_get", test_snapshot_get, 0 },
|
||||
{ "sqlite3_snapshot_open", test_snapshot_open, 0 },
|
||||
{ "sqlite3_snapshot_free", test_snapshot_free, 0 },
|
||||
{ "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 },
|
||||
#endif
|
||||
};
|
||||
static int bitmask_size = sizeof(Bitmask)*8;
|
||||
|
||||
+27
-1
@@ -701,6 +701,10 @@ static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xCurrentTime(pVfs, pTimeOut);
|
||||
}
|
||||
static int cfGetLastError(sqlite3_vfs *pCfVfs, int n, char *z){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xGetLastError(pVfs, n, z);
|
||||
}
|
||||
|
||||
static int processDevSymArgs(
|
||||
Tcl_Interp *interp,
|
||||
@@ -827,7 +831,7 @@ static int crashEnableCmd(
|
||||
cfRandomness, /* xRandomness */
|
||||
cfSleep, /* xSleep */
|
||||
cfCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetlastError */
|
||||
cfGetLastError, /* xGetLastError */
|
||||
0, /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
@@ -940,6 +944,27 @@ static int devSymObjCmd(
|
||||
devsym_register(iDc, iSectorSize);
|
||||
|
||||
return TCL_OK;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: unregister_devsim
|
||||
*/
|
||||
static int dsUnregisterObjCmd(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
void devsym_unregister(void);
|
||||
|
||||
if( objc!=1 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
devsym_unregister();
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1010,6 +1035,7 @@ int Sqlitetest6_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
|
||||
Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
|
||||
#endif
|
||||
|
||||
+9
-1
@@ -133,7 +133,8 @@ struct DevsymGlobal g = {0, 0, 512};
|
||||
*/
|
||||
static int devsymClose(sqlite3_file *pFile){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsClose(p->pReal);
|
||||
sqlite3OsClose(p->pReal);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -395,4 +396,11 @@ void devsym_register(int iDeviceChar, int iSectorSize){
|
||||
}
|
||||
}
|
||||
|
||||
void devsym_unregister(){
|
||||
sqlite3_vfs_unregister(&devsym_vfs);
|
||||
g.pVfs = 0;
|
||||
g.iDeviceChar = 0;
|
||||
g.iSectorSize = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+18
-12
@@ -160,6 +160,7 @@ static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut);
|
||||
static int jtSleep(sqlite3_vfs*, int microseconds);
|
||||
static int jtCurrentTime(sqlite3_vfs*, double*);
|
||||
static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
|
||||
static int jtGetLastError(sqlite3_vfs*, int, char*);
|
||||
|
||||
static sqlite3_vfs jt_vfs = {
|
||||
2, /* iVersion */
|
||||
@@ -179,7 +180,7 @@ static sqlite3_vfs jt_vfs = {
|
||||
jtRandomness, /* xRandomness */
|
||||
jtSleep, /* xSleep */
|
||||
jtCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
jtGetLastError, /* xGetLastError */
|
||||
jtCurrentTimeInt64 /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
@@ -256,7 +257,8 @@ static int jtClose(sqlite3_file *pFile){
|
||||
*pp = p->pNext;
|
||||
}
|
||||
leaveJtMutex();
|
||||
return sqlite3OsClose(p->pReal);
|
||||
sqlite3OsClose(p->pReal);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -284,9 +286,10 @@ static int jtRead(
|
||||
** b) The file-name specified when the file was opened matches
|
||||
** all but the final 8 characters of the journal file name.
|
||||
**
|
||||
** c) There is currently a reserved lock on the file.
|
||||
** c) There is currently a reserved lock on the file. This
|
||||
** condition is waived if the noLock argument is non-zero.
|
||||
**/
|
||||
static jt_file *locateDatabaseHandle(const char *zJournal){
|
||||
static jt_file *locateDatabaseHandle(const char *zJournal, int noLock){
|
||||
jt_file *pMain = 0;
|
||||
enterJtMutex();
|
||||
for(pMain=g.pList; pMain; pMain=pMain->pNext){
|
||||
@@ -294,7 +297,7 @@ static jt_file *locateDatabaseHandle(const char *zJournal){
|
||||
if( (pMain->flags&SQLITE_OPEN_MAIN_DB)
|
||||
&& ((int)strlen(pMain->zName)==nName)
|
||||
&& 0==memcmp(pMain->zName, zJournal, nName)
|
||||
&& (pMain->eLock>=SQLITE_LOCK_RESERVED)
|
||||
&& ((pMain->eLock>=SQLITE_LOCK_RESERVED) || noLock)
|
||||
){
|
||||
break;
|
||||
}
|
||||
@@ -516,7 +519,7 @@ static int jtWrite(
|
||||
jt_file *p = (jt_file *)pFile;
|
||||
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){
|
||||
if( iOfst==0 ){
|
||||
jt_file *pMain = locateDatabaseHandle(p->zName);
|
||||
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
|
||||
assert( pMain );
|
||||
|
||||
if( iAmt==28 ){
|
||||
@@ -561,7 +564,7 @@ static int jtWrite(
|
||||
|
||||
rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
|
||||
if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){
|
||||
jt_file *pMain = locateDatabaseHandle(p->zName);
|
||||
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
|
||||
int rc2 = readJournalFile(p, pMain);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
}
|
||||
@@ -575,7 +578,7 @@ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
jt_file *p = (jt_file *)pFile;
|
||||
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){
|
||||
/* Truncating a journal file. This is the end of a transaction. */
|
||||
jt_file *pMain = locateDatabaseHandle(p->zName);
|
||||
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
|
||||
closeTransaction(pMain);
|
||||
}
|
||||
if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
|
||||
@@ -603,11 +606,10 @@ static int jtSync(sqlite3_file *pFile, int flags){
|
||||
** jt_file.pWritable bitvec of the main database file associated with
|
||||
** this journal file.
|
||||
*/
|
||||
pMain = locateDatabaseHandle(p->zName);
|
||||
assert(pMain);
|
||||
pMain = locateDatabaseHandle(p->zName, 0);
|
||||
|
||||
/* Set the bitvec values */
|
||||
if( pMain->pWritable ){
|
||||
if( pMain && pMain->pWritable ){
|
||||
pMain->nSync++;
|
||||
rc = readJournalFile(p, pMain);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -729,7 +731,7 @@ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
||||
int nPath = (int)strlen(zPath);
|
||||
if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){
|
||||
/* Deleting a journal file. The end of a transaction. */
|
||||
jt_file *pMain = locateDatabaseHandle(zPath);
|
||||
jt_file *pMain = locateDatabaseHandle(zPath, 0);
|
||||
if( pMain ){
|
||||
closeTransaction(pMain);
|
||||
}
|
||||
@@ -824,6 +826,10 @@ static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
|
||||
return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut);
|
||||
}
|
||||
|
||||
static int jtGetLastError(sqlite3_vfs *pVfs, int n, char *z){
|
||||
return g.pVfs->xGetLastError(g.pVfs, n, z);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
** Start of public API.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -1093,7 +1093,7 @@ static int test_db_config_lookaside(
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR;
|
||||
if( bufid==0 ){
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, 0, sz, cnt);
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, (void*)0, sz, cnt);
|
||||
}else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt);
|
||||
}else{
|
||||
|
||||
@@ -539,7 +539,7 @@ static int multiplexOpen(
|
||||
memset(pGroup, 0, sz);
|
||||
pMultiplexOpen->pGroup = pGroup;
|
||||
pGroup->bEnabled = (unsigned char)-1;
|
||||
pGroup->bTruncate = sqlite3_uri_boolean(zUri, "truncate",
|
||||
pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate",
|
||||
(flags & SQLITE_OPEN_MAIN_DB)==0);
|
||||
pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize",
|
||||
SQLITE_MULTIPLEX_CHUNK_SIZE);
|
||||
@@ -978,7 +978,7 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
|
||||
case MULTIPLEX_CTRL_ENABLE:
|
||||
if( pArg ) {
|
||||
int bEnabled = *(int *)pArg;
|
||||
pGroup->bEnabled = bEnabled;
|
||||
pGroup->bEnabled = (unsigned char)bEnabled;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -508,7 +508,7 @@ static int fsSync(sqlite3_file *pFile, int flags){
|
||||
if( p->eType==DATABASE_FILE ){
|
||||
unsigned char zSize[4];
|
||||
zSize[0] = (pReal->nDatabase&0xFF000000)>>24;
|
||||
zSize[1] = (pReal->nDatabase&0x00FF0000)>>16;
|
||||
zSize[1] = (unsigned char)((pReal->nDatabase&0x00FF0000)>>16);
|
||||
zSize[2] = (pReal->nDatabase&0x0000FF00)>>8;
|
||||
zSize[3] = (pReal->nDatabase&0x000000FF);
|
||||
rc = pRealFile->pMethods->xWrite(pRealFile, zSize, 4, 0);
|
||||
|
||||
+3
-3
@@ -644,9 +644,9 @@ static void vfslog_flush(VfslogVfs *p){
|
||||
|
||||
static void put32bits(unsigned char *p, unsigned int v){
|
||||
p[0] = v>>24;
|
||||
p[1] = v>>16;
|
||||
p[2] = v>>8;
|
||||
p[3] = v;
|
||||
p[1] = (unsigned char)(v>>16);
|
||||
p[2] = (unsigned char)(v>>8);
|
||||
p[3] = (unsigned char)v;
|
||||
}
|
||||
|
||||
static void vfslog_call(
|
||||
|
||||
+18
-9
@@ -108,10 +108,13 @@ static int ts_ftruncate(int fd, off_t n);
|
||||
static int ts_fcntl(int fd, int cmd, ... );
|
||||
static int ts_read(int fd, void *aBuf, size_t nBuf);
|
||||
static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off);
|
||||
static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off);
|
||||
/* Note: pread64() and pwrite64() actually use off64_t as the type on their
|
||||
** last parameter. But that datatype is not defined on many systems
|
||||
** (ex: Mac, OpenBSD). So substitute a likely equivalent: sqlite3_uint64 */
|
||||
static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off);
|
||||
static int ts_write(int fd, const void *aBuf, size_t nBuf);
|
||||
static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off);
|
||||
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off);
|
||||
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off);
|
||||
static int ts_fchmod(int fd, mode_t mode);
|
||||
static int ts_fallocate(int fd, off_t off, off_t len);
|
||||
static void *ts_mmap(void *, size_t, int, int, int, off_t);
|
||||
@@ -155,11 +158,11 @@ struct TestSyscallArray {
|
||||
#define orig_fcntl ((int(*)(int,int,...))aSyscall[7].xOrig)
|
||||
#define orig_read ((ssize_t(*)(int,void*,size_t))aSyscall[8].xOrig)
|
||||
#define orig_pread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].xOrig)
|
||||
#define orig_pread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].xOrig)
|
||||
#define orig_pread64 ((ssize_t(*)(int,void*,size_t,sqlite3_uint64))aSyscall[10].xOrig)
|
||||
#define orig_write ((ssize_t(*)(int,const void*,size_t))aSyscall[11].xOrig)
|
||||
#define orig_pwrite ((ssize_t(*)(int,const void*,size_t,off_t))\
|
||||
aSyscall[12].xOrig)
|
||||
#define orig_pwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
|
||||
#define orig_pwrite64 ((ssize_t(*)(int,const void*,size_t,sqlite3_uint64))\
|
||||
aSyscall[13].xOrig)
|
||||
#define orig_fchmod ((int(*)(int,mode_t))aSyscall[14].xOrig)
|
||||
#define orig_fallocate ((int(*)(int,off_t,off_t))aSyscall[15].xOrig)
|
||||
@@ -326,7 +329,7 @@ static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off){
|
||||
/*
|
||||
** A wrapper around pread64().
|
||||
*/
|
||||
static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off){
|
||||
static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off){
|
||||
if( tsIsFailErrno("pread64") ){
|
||||
return -1;
|
||||
}
|
||||
@@ -357,7 +360,7 @@ static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off){
|
||||
/*
|
||||
** A wrapper around pwrite64().
|
||||
*/
|
||||
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off){
|
||||
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off){
|
||||
if( tsIsFailErrno("pwrite64") ){
|
||||
return -1;
|
||||
}
|
||||
@@ -719,14 +722,20 @@ static int test_syscall(
|
||||
};
|
||||
int iCmd;
|
||||
int rc;
|
||||
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
|
||||
|
||||
if( objc<2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = Tcl_GetIndexFromObjStruct(interp,
|
||||
objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
|
||||
);
|
||||
if( pVfs->iVersion<3 || pVfs->xSetSystemCall==0 ){
|
||||
Tcl_AppendResult(interp, "VFS does not support xSetSystemCall", 0);
|
||||
rc = TCL_ERROR;
|
||||
}else{
|
||||
rc = Tcl_GetIndexFromObjStruct(interp,
|
||||
objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
|
||||
);
|
||||
}
|
||||
if( rc!=TCL_OK ) return rc;
|
||||
return aCmd[iCmd].xCmd(clientData, interp, objc, objv);
|
||||
}
|
||||
|
||||
+2
-3
@@ -306,7 +306,6 @@ static void tvfsExecTcl(
|
||||
** Close an tvfs-file.
|
||||
*/
|
||||
static int tvfsClose(sqlite3_file *pFile){
|
||||
int rc;
|
||||
TestvfsFile *pTestfile = (TestvfsFile *)pFile;
|
||||
TestvfsFd *pFd = pTestfile->pFd;
|
||||
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
|
||||
@@ -324,10 +323,10 @@ static int tvfsClose(sqlite3_file *pFile){
|
||||
if( pFile->pMethods ){
|
||||
ckfree((char *)pFile->pMethods);
|
||||
}
|
||||
rc = sqlite3OsClose(pFd->pReal);
|
||||
sqlite3OsClose(pFd->pReal);
|
||||
ckfree((char *)pFd);
|
||||
pTestfile->pFd = 0;
|
||||
return rc;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -583,7 +583,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
sqlite3DeleteTable(db, pParse->pNewTable);
|
||||
}
|
||||
|
||||
sqlite3WithDelete(db, pParse->pWithToFree);
|
||||
if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
|
||||
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
|
||||
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
|
||||
sqlite3DbFree(db, pParse->azVar);
|
||||
|
||||
+65
-61
@@ -242,18 +242,13 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
|
||||
** brackets from around identifiers. For example: "[a-b-c]" becomes
|
||||
** "a-b-c".
|
||||
*/
|
||||
int sqlite3Dequote(char *z){
|
||||
void sqlite3Dequote(char *z){
|
||||
char quote;
|
||||
int i, j;
|
||||
if( z==0 ) return -1;
|
||||
if( z==0 ) return;
|
||||
quote = z[0];
|
||||
switch( quote ){
|
||||
case '\'': break;
|
||||
case '"': break;
|
||||
case '`': break; /* For MySQL compatibility */
|
||||
case '[': quote = ']'; break; /* For MS SqlServer compatibility */
|
||||
default: return -1;
|
||||
}
|
||||
if( !sqlite3Isquote(quote) ) return;
|
||||
if( quote=='[' ) quote = ']';
|
||||
for(i=1, j=0;; i++){
|
||||
assert( z[i] );
|
||||
if( z[i]==quote ){
|
||||
@@ -268,7 +263,6 @@ int sqlite3Dequote(char *z){
|
||||
}
|
||||
}
|
||||
z[j] = 0;
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -361,7 +355,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
int eValid = 1; /* True exponent is either not used or is well-formed */
|
||||
double result;
|
||||
int nDigits = 0;
|
||||
int nonNum = 0;
|
||||
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
|
||||
|
||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||
*pResult = 0.0; /* Default return value, in case of an error */
|
||||
@@ -374,7 +368,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
for(i=3-enc; i<length && z[i]==0; i+=2){}
|
||||
nonNum = i<length;
|
||||
zEnd = z+i+enc-3;
|
||||
zEnd = &z[i^1];
|
||||
z += (enc&1);
|
||||
}
|
||||
|
||||
@@ -390,9 +384,6 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
z+=incr;
|
||||
}
|
||||
|
||||
/* skip leading zeroes */
|
||||
while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
|
||||
|
||||
/* copy max significant digits to significand */
|
||||
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
|
||||
s = s*10 + (*z - '0');
|
||||
@@ -409,12 +400,13 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
z+=incr;
|
||||
/* copy digits from after decimal to significand
|
||||
** (decrease exponent by d to shift decimal right) */
|
||||
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
|
||||
s = s*10 + (*z - '0');
|
||||
z+=incr, nDigits++, d--;
|
||||
while( z<zEnd && sqlite3Isdigit(*z) ){
|
||||
if( s<((LARGEST_INT64-9)/10) ){
|
||||
s = s*10 + (*z - '0');
|
||||
d--;
|
||||
}
|
||||
z+=incr, nDigits++;
|
||||
}
|
||||
/* skip non-significant digits */
|
||||
while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
|
||||
}
|
||||
if( z>=zEnd ) goto do_atof_calc;
|
||||
|
||||
@@ -422,7 +414,12 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
if( *z=='e' || *z=='E' ){
|
||||
z+=incr;
|
||||
eValid = 0;
|
||||
if( z>=zEnd ) goto do_atof_calc;
|
||||
|
||||
/* This branch is needed to avoid a (harmless) buffer overread. The
|
||||
** special comment alerts the mutation tester that the correct answer
|
||||
** is obtained even if the branch is omitted */
|
||||
if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/
|
||||
|
||||
/* get sign of exponent */
|
||||
if( *z=='-' ){
|
||||
esign = -1;
|
||||
@@ -439,9 +436,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
|
||||
}
|
||||
|
||||
/* skip trailing spaces */
|
||||
if( nDigits && eValid ){
|
||||
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
||||
}
|
||||
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
|
||||
|
||||
do_atof_calc:
|
||||
/* adjust exponent by d, and update sign */
|
||||
@@ -453,41 +448,51 @@ do_atof_calc:
|
||||
esign = 1;
|
||||
}
|
||||
|
||||
/* if 0 significand */
|
||||
if( !s ) {
|
||||
/* In the IEEE 754 standard, zero is signed.
|
||||
** Add the sign if we've seen at least one digit */
|
||||
result = (sign<0 && nDigits) ? -(double)0 : (double)0;
|
||||
if( s==0 ) {
|
||||
/* In the IEEE 754 standard, zero is signed. */
|
||||
result = sign<0 ? -(double)0 : (double)0;
|
||||
} else {
|
||||
/* attempt to reduce exponent */
|
||||
if( esign>0 ){
|
||||
while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
|
||||
}else{
|
||||
while( !(s%10) && e>0 ) e--,s/=10;
|
||||
/* Attempt to reduce exponent.
|
||||
**
|
||||
** Branches that are not required for the correct answer but which only
|
||||
** help to obtain the correct answer faster are marked with special
|
||||
** comments, as a hint to the mutation tester.
|
||||
*/
|
||||
while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
if( esign>0 ){
|
||||
if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
|
||||
s *= 10;
|
||||
}else{
|
||||
if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
|
||||
s /= 10;
|
||||
}
|
||||
e--;
|
||||
}
|
||||
|
||||
/* adjust the sign of significand */
|
||||
s = sign<0 ? -s : s;
|
||||
|
||||
/* if exponent, scale significand as appropriate
|
||||
** and store in result. */
|
||||
if( e ){
|
||||
if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
result = (double)s;
|
||||
}else{
|
||||
LONGDOUBLE_TYPE scale = 1.0;
|
||||
/* attempt to handle extremely small/large numbers better */
|
||||
if( e>307 && e<342 ){
|
||||
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
|
||||
if( esign<0 ){
|
||||
result = s / scale;
|
||||
result /= 1.0e+308;
|
||||
}else{
|
||||
result = s * scale;
|
||||
result *= 1.0e+308;
|
||||
}
|
||||
}else if( e>=342 ){
|
||||
if( esign<0 ){
|
||||
result = 0.0*s;
|
||||
}else{
|
||||
result = 1e308*1e308*s; /* Infinity */
|
||||
if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
|
||||
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
|
||||
if( esign<0 ){
|
||||
result = s / scale;
|
||||
result /= 1.0e+308;
|
||||
}else{
|
||||
result = s * scale;
|
||||
result *= 1.0e+308;
|
||||
}
|
||||
}else{ assert( e>=342 );
|
||||
if( esign<0 ){
|
||||
result = 0.0*s;
|
||||
}else{
|
||||
result = 1e308*1e308*s; /* Infinity */
|
||||
}
|
||||
}
|
||||
}else{
|
||||
/* 1.0e+22 is the largest power of 10 than can be
|
||||
@@ -500,8 +505,6 @@ do_atof_calc:
|
||||
result = s * scale;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = (double)s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +512,7 @@ do_atof_calc:
|
||||
*pResult = result;
|
||||
|
||||
/* return true if number and no extra non-whitespace chracters after */
|
||||
return z>=zEnd && nDigits>0 && eValid && nonNum==0;
|
||||
return z==zEnd && nDigits>0 && eValid && nonNum==0;
|
||||
#else
|
||||
return !sqlite3Atoi64(z, pResult, length, enc);
|
||||
#endif /* SQLITE_OMIT_FLOATING_POINT */
|
||||
@@ -571,7 +574,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
||||
int neg = 0; /* assume positive */
|
||||
int i;
|
||||
int c = 0;
|
||||
int nonNum = 0;
|
||||
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
|
||||
const char *zStart;
|
||||
const char *zEnd = zNum + length;
|
||||
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
|
||||
@@ -582,7 +585,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
||||
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
|
||||
nonNum = i<length;
|
||||
zEnd = zNum+i+enc-3;
|
||||
zEnd = &zNum[i^1];
|
||||
zNum += (enc&1);
|
||||
}
|
||||
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
|
||||
@@ -609,8 +612,11 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
||||
testcase( i==18 );
|
||||
testcase( i==19 );
|
||||
testcase( i==20 );
|
||||
if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum)
|
||||
|| i>19*incr || nonNum ){
|
||||
if( &zNum[i]<zEnd /* Extra bytes at the end */
|
||||
|| (i==0 && zStart==zNum) /* No digits */
|
||||
|| i>19*incr /* Too many digits */
|
||||
|| nonNum /* UTF16 with high-order bytes non-zero */
|
||||
){
|
||||
/* zNum is empty or contains non-numeric text or is longer
|
||||
** than 19 digits (thus guaranteeing that it is too large) */
|
||||
return 1;
|
||||
@@ -652,7 +658,6 @@ 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;
|
||||
@@ -1414,7 +1419,7 @@ LogEst sqlite3LogEst(u64 x){
|
||||
if( x<2 ) return 0;
|
||||
while( x<8 ){ y -= 10; x <<= 1; }
|
||||
}else{
|
||||
while( x>255 ){ y += 40; x >>= 4; }
|
||||
while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/
|
||||
while( x>15 ){ y += 10; x >>= 1; }
|
||||
}
|
||||
return a[x&7] + y - 10;
|
||||
@@ -1448,7 +1453,6 @@ LogEst sqlite3LogEstFromDouble(double x){
|
||||
*/
|
||||
u64 sqlite3LogEstToInt(LogEst x){
|
||||
u64 n;
|
||||
if( x<10 ) return 1;
|
||||
n = x%10;
|
||||
x /= 10;
|
||||
if( n>=5 ) n -= 2;
|
||||
|
||||
+46
-39
@@ -674,37 +674,39 @@ int sqlite3VdbeExec(
|
||||
|
||||
/* Sanity checking on other operands */
|
||||
#ifdef SQLITE_DEBUG
|
||||
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
|
||||
if( (pOp->opflags & OPFLG_IN1)!=0 ){
|
||||
assert( pOp->p1>0 );
|
||||
assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p1]) );
|
||||
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
|
||||
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_IN2)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p2]) );
|
||||
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
|
||||
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_IN3)!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p3]) );
|
||||
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
|
||||
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
|
||||
memAboutToChange(p, &aMem[pOp->p2]);
|
||||
}
|
||||
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
|
||||
memAboutToChange(p, &aMem[pOp->p3]);
|
||||
{
|
||||
u8 opProperty = sqlite3OpcodeProperty[pOp->opcode];
|
||||
if( (opProperty & OPFLG_IN1)!=0 ){
|
||||
assert( pOp->p1>0 );
|
||||
assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p1]) );
|
||||
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
|
||||
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
|
||||
}
|
||||
if( (opProperty & OPFLG_IN2)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p2]) );
|
||||
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
|
||||
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
|
||||
}
|
||||
if( (opProperty & OPFLG_IN3)!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
|
||||
assert( memIsValid(&aMem[pOp->p3]) );
|
||||
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
|
||||
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
|
||||
}
|
||||
if( (opProperty & OPFLG_OUT2)!=0 ){
|
||||
assert( pOp->p2>0 );
|
||||
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
|
||||
memAboutToChange(p, &aMem[pOp->p2]);
|
||||
}
|
||||
if( (opProperty & OPFLG_OUT3)!=0 ){
|
||||
assert( pOp->p3>0 );
|
||||
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
|
||||
memAboutToChange(p, &aMem[pOp->p3]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||
@@ -2016,11 +2018,13 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
/* Neither operand is NULL. Do a comparison. */
|
||||
affinity = pOp->p5 & SQLITE_AFF_MASK;
|
||||
if( affinity>=SQLITE_AFF_NUMERIC ){
|
||||
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn1,0);
|
||||
}
|
||||
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn3,0);
|
||||
if( (flags1 | flags3)&MEM_Str ){
|
||||
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn1,0);
|
||||
}
|
||||
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn3,0);
|
||||
}
|
||||
}
|
||||
}else if( affinity==SQLITE_AFF_TEXT ){
|
||||
if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
|
||||
@@ -2753,7 +2757,9 @@ case OP_MakeRecord: {
|
||||
testcase( serial_type==127 );
|
||||
testcase( serial_type==128 );
|
||||
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
|
||||
}while( (--pRec)>=pData0 );
|
||||
if( pRec==pData0 ) break;
|
||||
pRec--;
|
||||
}while(1);
|
||||
|
||||
/* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
|
||||
** which determines the total number of bytes in the header. The varint
|
||||
@@ -6873,11 +6879,12 @@ default: { /* This is really OP_Noop and OP_Explain */
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags & SQLITE_VdbeTrace ){
|
||||
u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode];
|
||||
if( rc!=0 ) printf("rc=%d\n",rc);
|
||||
if( pOrigOp->opflags & (OPFLG_OUT2) ){
|
||||
if( opProperty & (OPFLG_OUT2) ){
|
||||
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
|
||||
}
|
||||
if( pOrigOp->opflags & OPFLG_OUT3 ){
|
||||
if( opProperty & OPFLG_OUT3 ){
|
||||
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ typedef struct SubProgram SubProgram;
|
||||
struct VdbeOp {
|
||||
u8 opcode; /* What operation to perform */
|
||||
signed char p4type; /* One of the P4_xxx constants for p4 */
|
||||
u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */
|
||||
u8 notUsed1;
|
||||
u8 p5; /* Fifth parameter is an unsigned character */
|
||||
int p1; /* First operand */
|
||||
int p2; /* Second parameter (often the jump destination) */
|
||||
|
||||
+103
-94
@@ -545,73 +545,84 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|
||||
** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
|
||||
**
|
||||
** (5) Reclaim the memory allocated for storing labels.
|
||||
**
|
||||
** This routine will only function correctly if the mkopcodeh.tcl generator
|
||||
** script numbers the opcodes correctly. Changes to this routine must be
|
||||
** coordinated with changes to mkopcodeh.tcl.
|
||||
*/
|
||||
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
||||
int i;
|
||||
int nMaxArgs = *pMaxFuncArgs;
|
||||
Op *pOp;
|
||||
Parse *pParse = p->pParse;
|
||||
int *aLabel = pParse->aLabel;
|
||||
p->readOnly = 1;
|
||||
p->bIsReader = 0;
|
||||
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
||||
u8 opcode = pOp->opcode;
|
||||
pOp = &p->aOp[p->nOp-1];
|
||||
while(1){
|
||||
|
||||
/* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
|
||||
** cases from this switch! */
|
||||
switch( opcode ){
|
||||
case OP_Transaction: {
|
||||
if( pOp->p2!=0 ) p->readOnly = 0;
|
||||
/* fall thru */
|
||||
}
|
||||
case OP_AutoCommit:
|
||||
case OP_Savepoint: {
|
||||
p->bIsReader = 1;
|
||||
break;
|
||||
}
|
||||
/* Only JUMP opcodes and the short list of special opcodes in the switch
|
||||
** below need to be considered. The mkopcodeh.tcl generator script groups
|
||||
** all these opcodes together near the front of the opcode list. Skip
|
||||
** any opcode that does not need processing by virtual of the fact that
|
||||
** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
|
||||
*/
|
||||
if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
|
||||
/* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
|
||||
** cases from this switch! */
|
||||
switch( pOp->opcode ){
|
||||
case OP_Transaction: {
|
||||
if( pOp->p2!=0 ) p->readOnly = 0;
|
||||
/* fall thru */
|
||||
}
|
||||
case OP_AutoCommit:
|
||||
case OP_Savepoint: {
|
||||
p->bIsReader = 1;
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
case OP_Checkpoint:
|
||||
case OP_Checkpoint:
|
||||
#endif
|
||||
case OP_Vacuum:
|
||||
case OP_JournalMode: {
|
||||
p->readOnly = 0;
|
||||
p->bIsReader = 1;
|
||||
break;
|
||||
}
|
||||
case OP_Vacuum:
|
||||
case OP_JournalMode: {
|
||||
p->readOnly = 0;
|
||||
p->bIsReader = 1;
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
case OP_VUpdate: {
|
||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||
break;
|
||||
}
|
||||
case OP_VFilter: {
|
||||
int n;
|
||||
assert( p->nOp - i >= 3 );
|
||||
assert( pOp[-1].opcode==OP_Integer );
|
||||
n = pOp[-1].p1;
|
||||
if( n>nMaxArgs ) nMaxArgs = n;
|
||||
break;
|
||||
}
|
||||
case OP_VUpdate: {
|
||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||
break;
|
||||
}
|
||||
case OP_VFilter: {
|
||||
int n;
|
||||
assert( (pOp - p->aOp) >= 3 );
|
||||
assert( pOp[-1].opcode==OP_Integer );
|
||||
n = pOp[-1].p1;
|
||||
if( n>nMaxArgs ) nMaxArgs = n;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case OP_Next:
|
||||
case OP_NextIfOpen:
|
||||
case OP_SorterNext: {
|
||||
pOp->p4.xAdvance = sqlite3BtreeNext;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
break;
|
||||
case OP_Next:
|
||||
case OP_NextIfOpen:
|
||||
case OP_SorterNext: {
|
||||
pOp->p4.xAdvance = sqlite3BtreeNext;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
break;
|
||||
}
|
||||
case OP_Prev:
|
||||
case OP_PrevIfOpen: {
|
||||
pOp->p4.xAdvance = sqlite3BtreePrevious;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case OP_Prev:
|
||||
case OP_PrevIfOpen: {
|
||||
pOp->p4.xAdvance = sqlite3BtreePrevious;
|
||||
pOp->p4type = P4_ADVANCE;
|
||||
break;
|
||||
if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
|
||||
assert( ADDR(pOp->p2)<pParse->nLabel );
|
||||
pOp->p2 = aLabel[ADDR(pOp->p2)];
|
||||
}
|
||||
}
|
||||
|
||||
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
||||
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
|
||||
assert( ADDR(pOp->p2)<pParse->nLabel );
|
||||
pOp->p2 = aLabel[ADDR(pOp->p2)];
|
||||
}
|
||||
if( pOp==p->aOp ) break;
|
||||
pOp--;
|
||||
}
|
||||
sqlite3DbFree(p->db, pParse->aLabel);
|
||||
pParse->aLabel = 0;
|
||||
@@ -791,52 +802,50 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
|
||||
** Delete a P4 value if necessary.
|
||||
*/
|
||||
static void freeP4(sqlite3 *db, int p4type, void *p4){
|
||||
if( p4 ){
|
||||
assert( db );
|
||||
switch( p4type ){
|
||||
case P4_FUNCCTX: {
|
||||
freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
|
||||
/* Fall through into the next case */
|
||||
}
|
||||
case P4_REAL:
|
||||
case P4_INT64:
|
||||
case P4_DYNAMIC:
|
||||
case P4_INTARRAY: {
|
||||
sqlite3DbFree(db, p4);
|
||||
break;
|
||||
}
|
||||
case P4_KEYINFO: {
|
||||
if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
|
||||
break;
|
||||
}
|
||||
assert( db );
|
||||
switch( p4type ){
|
||||
case P4_FUNCCTX: {
|
||||
freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
|
||||
/* Fall through into the next case */
|
||||
}
|
||||
case P4_REAL:
|
||||
case P4_INT64:
|
||||
case P4_DYNAMIC:
|
||||
case P4_INTARRAY: {
|
||||
sqlite3DbFree(db, p4);
|
||||
break;
|
||||
}
|
||||
case P4_KEYINFO: {
|
||||
if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
|
||||
break;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
case P4_EXPR: {
|
||||
sqlite3ExprDelete(db, (Expr*)p4);
|
||||
break;
|
||||
}
|
||||
case P4_EXPR: {
|
||||
sqlite3ExprDelete(db, (Expr*)p4);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case P4_MPRINTF: {
|
||||
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
|
||||
break;
|
||||
}
|
||||
case P4_FUNCDEF: {
|
||||
freeEphemeralFunction(db, (FuncDef*)p4);
|
||||
break;
|
||||
}
|
||||
case P4_MEM: {
|
||||
if( db->pnBytesFreed==0 ){
|
||||
sqlite3ValueFree((sqlite3_value*)p4);
|
||||
}else{
|
||||
Mem *p = (Mem*)p4;
|
||||
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case P4_VTAB : {
|
||||
if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
|
||||
break;
|
||||
case P4_MPRINTF: {
|
||||
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
|
||||
break;
|
||||
}
|
||||
case P4_FUNCDEF: {
|
||||
freeEphemeralFunction(db, (FuncDef*)p4);
|
||||
break;
|
||||
}
|
||||
case P4_MEM: {
|
||||
if( db->pnBytesFreed==0 ){
|
||||
sqlite3ValueFree((sqlite3_value*)p4);
|
||||
}else{
|
||||
Mem *p = (Mem*)p4;
|
||||
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
|
||||
sqlite3DbFree(db, p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case P4_VTAB : {
|
||||
if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-3
@@ -931,7 +931,6 @@ int sqlite3VdbeSorterInit(
|
||||
){
|
||||
int pgsz; /* Page size of main database */
|
||||
int i; /* Used to iterate through aTask[] */
|
||||
int mxCache; /* Cache size */
|
||||
VdbeSorter *pSorter; /* The new sorter */
|
||||
KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
|
||||
int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
|
||||
@@ -988,11 +987,20 @@ int sqlite3VdbeSorterInit(
|
||||
}
|
||||
|
||||
if( !sqlite3TempInMemory(db) ){
|
||||
i64 mxCache; /* Cache size in bytes*/
|
||||
u32 szPma = sqlite3GlobalConfig.szPma;
|
||||
pSorter->mnPmaSize = szPma * pgsz;
|
||||
|
||||
mxCache = db->aDb[0].pSchema->cache_size;
|
||||
if( mxCache<(int)szPma ) mxCache = (int)szPma;
|
||||
pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
|
||||
if( mxCache<0 ){
|
||||
/* A negative cache-size value C indicates that the cache is abs(C)
|
||||
** KiB in size. */
|
||||
mxCache = mxCache * -1024;
|
||||
}else{
|
||||
mxCache = mxCache * pgsz;
|
||||
}
|
||||
mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
|
||||
pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
|
||||
|
||||
/* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
|
||||
** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
|
||||
|
||||
@@ -3399,6 +3399,23 @@ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
|
||||
void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
|
||||
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
|
||||
** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
|
||||
*/
|
||||
int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
|
||||
WalIndexHdr *pHdr1 = (WalIndexHdr*)p1;
|
||||
WalIndexHdr *pHdr2 = (WalIndexHdr*)p2;
|
||||
|
||||
/* aSalt[0] is a copy of the value stored in the wal file header. It
|
||||
** is incremented each time the wal file is restarted. */
|
||||
if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1;
|
||||
if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1;
|
||||
if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1;
|
||||
if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SNAPSHOT */
|
||||
|
||||
#ifdef SQLITE_ENABLE_ZIPVFS
|
||||
|
||||
+30
-19
@@ -1651,11 +1651,12 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){
|
||||
*/
|
||||
static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
|
||||
WhereInfo *pWInfo = pWC->pWInfo;
|
||||
int nb = 1+(pWInfo->pTabList->nSrc+7)/8;
|
||||
int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
|
||||
struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
|
||||
Table *pTab = pItem->pTab;
|
||||
Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
|
||||
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
|
||||
p->iTab, nb, p->maskSelf, nb, p->prereq);
|
||||
p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
|
||||
sqlite3DebugPrintf(" %12s",
|
||||
pItem->zAlias ? pItem->zAlias : pTab->zName);
|
||||
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
|
||||
@@ -2201,8 +2202,6 @@ static int whereLoopAddBtreeIndex(
|
||||
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
|
||||
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
|
||||
opMask = WO_LT|WO_LE;
|
||||
}else if( /*pProbe->tnum<=0 ||*/ (pSrc->fg.jointype & JT_LEFT)!=0 ){
|
||||
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
|
||||
}else{
|
||||
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
|
||||
}
|
||||
@@ -2240,6 +2239,18 @@ static int whereLoopAddBtreeIndex(
|
||||
** to mix with a lower range bound from some other source */
|
||||
if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
|
||||
|
||||
/* Do not allow IS constraints from the WHERE clause to be used by the
|
||||
** right table of a LEFT JOIN. Only constraints in the ON clause are
|
||||
** allowed */
|
||||
if( (pSrc->fg.jointype & JT_LEFT)!=0
|
||||
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
|
||||
&& (eOp & (WO_IS|WO_ISNULL))!=0
|
||||
){
|
||||
testcase( eOp & WO_IS );
|
||||
testcase( eOp & WO_ISNULL );
|
||||
continue;
|
||||
}
|
||||
|
||||
pNew->wsFlags = saved_wsFlags;
|
||||
pNew->u.btree.nEq = saved_nEq;
|
||||
pNew->nLTerm = saved_nLTerm;
|
||||
@@ -3870,9 +3881,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
&& nRowEst
|
||||
){
|
||||
Bitmask notUsed;
|
||||
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
|
||||
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
|
||||
WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used);
|
||||
if( rc==pWInfo->pResultSet->nExpr ){
|
||||
if( rc==pWInfo->pDistinctSet->nExpr ){
|
||||
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
|
||||
}
|
||||
}
|
||||
@@ -4087,14 +4098,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
|
||||
** used.
|
||||
*/
|
||||
WhereInfo *sqlite3WhereBegin(
|
||||
Parse *pParse, /* The parser context */
|
||||
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
|
||||
ExprList *pResultSet, /* Result set of the query */
|
||||
u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
|
||||
int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number,
|
||||
** If WHERE_USE_LIMIT, then the limit amount */
|
||||
Parse *pParse, /* The parser context */
|
||||
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
|
||||
ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */
|
||||
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
|
||||
int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number
|
||||
** If WHERE_USE_LIMIT, then the limit amount */
|
||||
){
|
||||
int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
|
||||
int nTabList; /* Number of elements in pTabList */
|
||||
@@ -4169,7 +4180,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
pWInfo->pParse = pParse;
|
||||
pWInfo->pTabList = pTabList;
|
||||
pWInfo->pOrderBy = pOrderBy;
|
||||
pWInfo->pResultSet = pResultSet;
|
||||
pWInfo->pDistinctSet = pDistinctSet;
|
||||
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
|
||||
pWInfo->wctrlFlags = wctrlFlags;
|
||||
pWInfo->iLimit = iAuxArg;
|
||||
@@ -4242,13 +4253,13 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( db->mallocFailed ) goto whereBeginError;
|
||||
|
||||
if( wctrlFlags & WHERE_WANT_DISTINCT ){
|
||||
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
|
||||
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
|
||||
/* The DISTINCT marking is pointless. Ignore it. */
|
||||
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
|
||||
}else if( pOrderBy==0 ){
|
||||
/* Try to ORDER BY the result set to make distinct processing easier */
|
||||
pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
|
||||
pWInfo->pOrderBy = pResultSet;
|
||||
pWInfo->pOrderBy = pDistinctSet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4327,10 +4338,10 @@ WhereInfo *sqlite3WhereBegin(
|
||||
#endif
|
||||
/* Attempt to omit tables from the join that do not effect the result */
|
||||
if( pWInfo->nLevel>=2
|
||||
&& pResultSet!=0
|
||||
&& pDistinctSet!=0
|
||||
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
|
||||
){
|
||||
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
|
||||
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
|
||||
if( sWLB.pOrderBy ){
|
||||
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
|
||||
}
|
||||
|
||||
+9
-1
@@ -408,7 +408,7 @@ struct WhereInfo {
|
||||
Parse *pParse; /* Parsing and code generating context */
|
||||
SrcList *pTabList; /* List of tables in the join */
|
||||
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
|
||||
ExprList *pResultSet; /* Result set. DISTINCT operates on these */
|
||||
ExprList *pDistinctSet; /* DISTINCT over all these values */
|
||||
WhereLoop *pLoops; /* List of all WhereLoop objects */
|
||||
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
|
||||
LogEst nRowOut; /* Estimated number of output rows */
|
||||
@@ -492,6 +492,14 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
|
||||
** operators that are of interest to the query planner. An
|
||||
** OR-ed combination of these values can be used when searching for
|
||||
** particular WhereTerms within a WhereClause.
|
||||
**
|
||||
** Value constraints:
|
||||
** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ
|
||||
** WO_LT == SQLITE_INDEX_CONSTRAINT_LT
|
||||
** WO_LE == SQLITE_INDEX_CONSTRAINT_LE
|
||||
** WO_GT == SQLITE_INDEX_CONSTRAINT_GT
|
||||
** WO_GE == SQLITE_INDEX_CONSTRAINT_GE
|
||||
** WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH
|
||||
*/
|
||||
#define WO_IN 0x0001
|
||||
#define WO_EQ 0x0002
|
||||
|
||||
+7
-1
@@ -941,7 +941,13 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
|
||||
/* These registers need to be preserved in case there is an IN operator
|
||||
** loop. So we could deallocate the registers here (and potentially
|
||||
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
|
||||
** simpler and safer to simply not reuse the registers.
|
||||
**
|
||||
** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
|
||||
*/
|
||||
sqlite3ExprCachePop(pParse);
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
+2
-2
@@ -1282,10 +1282,10 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
|
||||
return mask;
|
||||
}
|
||||
mask = sqlite3WhereExprUsage(pMaskSet, p->pRight);
|
||||
mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
|
||||
if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
|
||||
if( ExprHasProperty(p, EP_xIsSelect) ){
|
||||
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
|
||||
}else{
|
||||
}else if( p->x.pList ){
|
||||
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
|
||||
}
|
||||
return mask;
|
||||
|
||||
+47
-2
@@ -2432,8 +2432,53 @@ do_test auth-6.3 {
|
||||
execsql {SELECT rowid, * FROM t6}
|
||||
} {101 1 2 3 4 5 6 7 8}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that view names are included as zArg4.
|
||||
#
|
||||
do_execsql_test auth-7.1 {
|
||||
CREATE TABLE t7(a, b, c);
|
||||
CREATE VIEW v7 AS SELECT * FROM t7;
|
||||
} {}
|
||||
set ::authargs [list]
|
||||
proc auth {args} {
|
||||
eval lappend ::authargs [lrange $args 0 4]
|
||||
return SQLITE_OK
|
||||
}
|
||||
|
||||
do_test auth-7.2 {
|
||||
execsql {SELECT a, c FROM v7}
|
||||
set ::authargs
|
||||
} [list \
|
||||
SQLITE_SELECT {} {} {} {} \
|
||||
SQLITE_READ t7 a main v7 \
|
||||
SQLITE_READ t7 b main v7 \
|
||||
SQLITE_READ t7 c main v7 \
|
||||
SQLITE_READ v7 a main {} \
|
||||
SQLITE_READ v7 c main {} \
|
||||
SQLITE_SELECT {} {} {} v7 \
|
||||
]
|
||||
|
||||
set ::authargs [list]
|
||||
do_test auth-7.3 {
|
||||
execsql {SELECT a, c FROM t7}
|
||||
set ::authargs
|
||||
} [list \
|
||||
SQLITE_SELECT {} {} {} {} \
|
||||
SQLITE_READ t7 a main {} \
|
||||
SQLITE_READ t7 c main {} \
|
||||
]
|
||||
|
||||
set ::authargs [list]
|
||||
do_test auth-7.4 {
|
||||
execsql {SELECT a, c FROM t7 AS v7}
|
||||
set ::authargs
|
||||
} [list \
|
||||
SQLITE_SELECT {} {} {} {} \
|
||||
SQLITE_READ t7 a main {} \
|
||||
SQLITE_READ t7 c main {} \
|
||||
]
|
||||
|
||||
|
||||
rename proc {}
|
||||
rename proc_real proc
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -165,4 +165,111 @@ foreach {tn mode} {
|
||||
} $plan($mode)
|
||||
}
|
||||
|
||||
# 2016-04-09.
|
||||
# Demonstrate a register overwrite problem when using two virtual
|
||||
# tables where the outer loop uses the IN operator.
|
||||
#
|
||||
set G(collist) [list PrimaryKey flagA columnA]
|
||||
set G(cols) [join $G(collist) ,]
|
||||
set G(nulls) "NULL"
|
||||
|
||||
proc vtab_command {method args} {
|
||||
global G
|
||||
|
||||
switch -- $method {
|
||||
xConnect {
|
||||
return "CREATE TABLE t1($G(cols))"
|
||||
}
|
||||
|
||||
xBestIndex {
|
||||
set clist [lindex $args 0]
|
||||
#puts $clist
|
||||
set W [list]
|
||||
set U [list]
|
||||
|
||||
set i 0
|
||||
for {set idx 0} {$idx < [llength $clist]} {incr idx} {
|
||||
array set c [lindex $clist $idx]
|
||||
if {$c(op)=="eq" && $c(usable)} {
|
||||
lappend W "[lindex $G(collist) $c(column)] = %$i%"
|
||||
lappend U use $idx
|
||||
incr i
|
||||
}
|
||||
}
|
||||
|
||||
if {$W==""} {
|
||||
set sql "SELECT rowid, * FROM t1"
|
||||
} else {
|
||||
set sql "SELECT rowid, * FROM t1 WHERE [join $W { AND }]"
|
||||
}
|
||||
|
||||
return [concat [list idxstr $sql] $U]
|
||||
}
|
||||
|
||||
xFilter {
|
||||
foreach {idxnum idxstr vals} $args {}
|
||||
|
||||
set map [list]
|
||||
for {set i 0} {$i < [llength $vals]} {incr i} {
|
||||
lappend map "%$i%"
|
||||
set v [lindex $vals $i]
|
||||
if {[string is integer $v]} {
|
||||
lappend map $v
|
||||
} else {
|
||||
lappend map "'$v'"
|
||||
}
|
||||
}
|
||||
set sql [string map $map $idxstr]
|
||||
|
||||
#puts "SQL: $sql"
|
||||
return [list sql $sql]
|
||||
}
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
register_tcl_module db
|
||||
|
||||
do_execsql_test 3.1 "
|
||||
CREATE TABLE t1($G(cols));
|
||||
INSERT INTO t1 VALUES(1, 0, 'ValueA');
|
||||
INSERT INTO t1 VALUES(2, 0, 'ValueA');
|
||||
INSERT INTO t1 VALUES(3, 0, 'ValueB');
|
||||
INSERT INTO t1 VALUES(4, 0, 'ValueB');
|
||||
"
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
CREATE VIRTUAL TABLE VirtualTableA USING tcl(vtab_command);
|
||||
CREATE VIRTUAL TABLE VirtualTableB USING tcl(vtab_command);
|
||||
}
|
||||
|
||||
do_execsql_test 3.3 { SELECT primarykey FROM VirtualTableA } {1 2 3 4}
|
||||
|
||||
do_execsql_test 3.4 {
|
||||
SELECT * FROM
|
||||
VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey
|
||||
WHERE a.ColumnA IN ('ValueA', 'ValueB') AND a.FlagA=0
|
||||
} {
|
||||
1 0 ValueA 1 0 ValueA
|
||||
2 0 ValueA 2 0 ValueA
|
||||
3 0 ValueB 3 0 ValueB
|
||||
4 0 ValueB 4 0 ValueB
|
||||
}
|
||||
|
||||
do_execsql_test 3.5 {
|
||||
SELECT * FROM
|
||||
VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey
|
||||
WHERE a.FlagA=0 AND a.ColumnA IN ('ValueA', 'ValueB')
|
||||
} {
|
||||
1 0 ValueA 1 0 ValueA
|
||||
2 0 ValueA 2 0 ValueA
|
||||
3 0 ValueB 3 0 ValueB
|
||||
4 0 ValueB 4 0 ValueB
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ do_test 2.3 { db_write db 1 } {0 4 0}
|
||||
do_test 2.4 { db_write db 0 } {0 0 0}
|
||||
do_test 2.5 { db_write db 1 } {0 0 0}
|
||||
|
||||
ifcapable wal {
|
||||
if {[wal_is_capable]} {
|
||||
do_test 2.6 {
|
||||
execsql { PRAGMA journal_mode = WAL }
|
||||
db_write db 1
|
||||
|
||||
+21
-2
@@ -139,7 +139,26 @@ do_execsql_test 4.12 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
|
||||
|
||||
# 2016-04-09
|
||||
# Ticket https://sqlite.org/src/info/a306e56ff68b8fa5
|
||||
# Failure to completely delete when reverse_unordered_selects is
|
||||
# engaged.
|
||||
#
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 5.0 {
|
||||
PRAGMA page_size=1024;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
CREATE INDEX x1 ON t1(b, c);
|
||||
INSERT INTO t1(a,b,c) VALUES(1, 1, zeroblob(80));
|
||||
INSERT INTO t1(a,b,c) SELECT a+1, 1, c FROM t1;
|
||||
INSERT INTO t1(a,b,c) SELECT a+2, 1, c FROM t1;
|
||||
INSERT INTO t1(a,b,c) SELECT a+10, 2, c FROM t1 WHERE b=1;
|
||||
INSERT INTO t1(a,b,c) SELECT a+20, 3, c FROM t1 WHERE b=1;
|
||||
PRAGMA reverse_unordered_selects = ON;
|
||||
DELETE FROM t1 WHERE b=2;
|
||||
SELECT a FROM t1 WHERE b=2;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ if {![nonzero_reserved_bytes]} {
|
||||
# EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
|
||||
# auto_vacuum support property can be changed using VACUUM.
|
||||
#
|
||||
ifcapable wal {
|
||||
if {[wal_is_capable]} {
|
||||
do_test e_vacuum-1.3.3.1 {
|
||||
execsql { PRAGMA journal_mode = wal }
|
||||
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
|
||||
|
||||
@@ -19,6 +19,7 @@ source $testdir/lock_common.tcl
|
||||
|
||||
|
||||
foreach jm {rollback wal} {
|
||||
if {![wal_is_capable] && $jm=="wal"} continue
|
||||
|
||||
set testprefix exists-$jm
|
||||
|
||||
|
||||
+1
-1
@@ -704,7 +704,7 @@ do_execsql_test 7.5.2.0 {
|
||||
ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';
|
||||
}
|
||||
|
||||
ifcapable !session {
|
||||
if 0 {
|
||||
# At time of writing, these two are broken. They demonstrate that the
|
||||
# sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
|
||||
# has been used to add a column with a default value other than NULL.
|
||||
|
||||
@@ -134,7 +134,7 @@ do_test incrvacuum2-3.2 {
|
||||
|
||||
integrity_check incrvacuum2-3.3
|
||||
|
||||
ifcapable wal {
|
||||
if {[wal_is_capable]} {
|
||||
# At one point, when a specific page was being extracted from the b-tree
|
||||
# free-list (e.g. during an incremental-vacuum), all trunk pages that
|
||||
# occurred before the specific page in the free-list trunk were being
|
||||
|
||||
@@ -604,5 +604,16 @@ do_test intpkey-15.7 {
|
||||
}
|
||||
} {}
|
||||
|
||||
# 2016-04-18 ticket https://www.sqlite.org/src/tktview/7d7525cb01b68712495d3a
|
||||
# Be sure to escape quoted typenames.
|
||||
#
|
||||
do_execsql_test intpkey-16.0 {
|
||||
CREATE TABLE t16a(id "INTEGER" PRIMARY KEY AUTOINCREMENT, b [TEXT], c `INT`);
|
||||
} {}
|
||||
do_execsql_test intpkey-16.1 {
|
||||
PRAGMA table_info=t16a;
|
||||
} {0 id INTEGER 0 {} 1 1 b TEXT 0 {} 0 2 c INT 0 {} 0}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -204,7 +204,7 @@ db close
|
||||
# delete the journal file when committing the transaction that switches
|
||||
# the system to WAL mode.
|
||||
#
|
||||
ifcapable wal {
|
||||
if {[wal_is_capable]} {
|
||||
do_test journal2-2.1 {
|
||||
faultsim_delete_and_reopen
|
||||
set ::oplog [list]
|
||||
|
||||
+11
-1
@@ -111,7 +111,7 @@ do_test loadext-1.2 {
|
||||
#
|
||||
do_test loadext-1.3 {
|
||||
sqlite3 db2 test.db
|
||||
sqlite3_enable_load_extension db2 1
|
||||
sqlite3_db_config db2 SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1
|
||||
catchsql {
|
||||
SELECT half(1.0);
|
||||
} db2
|
||||
@@ -256,6 +256,7 @@ do_test loadext-4.2 {
|
||||
}
|
||||
} {0 {{}}}
|
||||
|
||||
# disable all extension loading
|
||||
do_test loadext-4.3 {
|
||||
sqlite3_enable_load_extension db 0
|
||||
catchsql {
|
||||
@@ -263,6 +264,15 @@ do_test loadext-4.3 {
|
||||
}
|
||||
} {1 {not authorized}}
|
||||
|
||||
# enable C-api extension loading only. Show that the SQL function
|
||||
# still does not work.
|
||||
do_test loadext-4.4 {
|
||||
sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1
|
||||
catchsql {
|
||||
SELECT load_extension($::testextension,'testloadext_init')
|
||||
}
|
||||
} {1 {not authorized}}
|
||||
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
|
||||
|
||||
@@ -728,7 +728,7 @@ test_suite "inmemory_journal" -description {
|
||||
ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test
|
||||
vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test
|
||||
e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test
|
||||
fts3snippet.test mmapfault.test
|
||||
fts3snippet.test mmapfault.test sessionfault.test sessionfault2.test
|
||||
|
||||
# Exclude test scripts that use tcl IO to access journal files or count
|
||||
# the number of fsync() calls.
|
||||
@@ -942,7 +942,9 @@ test_suite "journaltest" -description {
|
||||
unregister_jt_vfs
|
||||
} -files [test_set $::allquicktests -exclude {
|
||||
wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test
|
||||
async4.test bigfile.test backcompat.test
|
||||
async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test
|
||||
pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock*
|
||||
pager2.test *fault* rowal* snapshot* superlock* symlink.test
|
||||
}]
|
||||
|
||||
if {[info commands register_demovfs] != ""} {
|
||||
@@ -1050,15 +1052,13 @@ proc run_tests {name args} {
|
||||
set ::G(isquick) 1
|
||||
set ::G(perm:dbconfig) $options(-dbconfig)
|
||||
|
||||
uplevel $options(-initialize)
|
||||
|
||||
foreach file [lsort $options(-files)] {
|
||||
uplevel $options(-initialize)
|
||||
if {[file tail $file] == $file} { set file [file join $::testdir $file] }
|
||||
slave_test_file $file
|
||||
uplevel $options(-shutdown)
|
||||
}
|
||||
|
||||
uplevel $options(-shutdown)
|
||||
|
||||
unset ::G(perm:name)
|
||||
unset ::G(perm:prefix)
|
||||
unset ::G(perm:presql)
|
||||
|
||||
+2
-2
@@ -628,10 +628,10 @@ ifcapable tempdb&&attach {
|
||||
}
|
||||
do_test pragma-6.2 {
|
||||
execsql {
|
||||
CREATE TABLE t2(a,b,c);
|
||||
CREATE TABLE t2(a TYPE_X, b [TYPE_Y], c "TYPE_Z");
|
||||
pragma table_info(t2)
|
||||
}
|
||||
} {0 a {} 0 {} 0 1 b {} 0 {} 0 2 c {} 0 {} 0}
|
||||
} {0 a TYPE_X 0 {} 0 1 b TYPE_Y 0 {} 0 2 c TYPE_Z 0 {} 0}
|
||||
do_test pragma-6.2.1 {
|
||||
execsql {
|
||||
pragma table_info;
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ ifcapable shared_cache {
|
||||
# This will not work with the in-memory journal permutation, as opening
|
||||
# [db2] switches the journal mode back to "memory"
|
||||
#
|
||||
ifcapable wal {
|
||||
if {[wal_is_capable]} {
|
||||
if {[permutation]!="inmemory_journal"} {
|
||||
|
||||
sqlite3 db test.db
|
||||
|
||||
@@ -527,4 +527,6 @@ do_faultsim_test quota-5.6 -prep {
|
||||
}
|
||||
|
||||
catch { sqlite3_quota_shutdown }
|
||||
catch { db close }
|
||||
forcedelete test.db
|
||||
finish_test
|
||||
|
||||
@@ -95,4 +95,38 @@ do_test savepoint7-2.2 {
|
||||
list $rc $msg [db eval {SELECT * FROM t2}]
|
||||
} {1 {abort due to ROLLBACK} {}}
|
||||
|
||||
# Ticket: https://www.sqlite.org/src/tktview/7f7f8026eda387d544b
|
||||
# Segfault in the in-memory journal logic triggered by a tricky
|
||||
# combination of SAVEPOINT operations.
|
||||
#
|
||||
unset -nocomplain i
|
||||
for {set i 248} {$i<=253} {incr i} {
|
||||
do_test savepoint7-3.$i {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
PRAGMA page_size=1024;
|
||||
PRAGMA temp_store=MEMORY;
|
||||
BEGIN;
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
|
||||
INSERT INTO t1(x,y) SELECT x*10, printf('%04d%.800c',x,'*') FROM c;
|
||||
SAVEPOINT one;
|
||||
SELECT count(*) FROM t1;
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
|
||||
INSERT INTO t1(x,y) SELECT x*10+1, printf('%04d%.800c',x,'*') FROM c;
|
||||
ROLLBACK TO one;
|
||||
SELECT count(*) FROM t1;
|
||||
SAVEPOINT twoB;
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<10)
|
||||
INSERT INTO t1(x,y) SELECT x*10+2, printf('%04d%.800c',x,'*') FROM c;
|
||||
ROLLBACK TO twoB;
|
||||
RELEASE one;
|
||||
COMMIT;
|
||||
}
|
||||
} [list $i $i]
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -968,6 +968,42 @@ do_execsql_test select4-16.3 {
|
||||
ORDER BY t3.a;
|
||||
} {95 96 97 98 99}
|
||||
|
||||
# Ticket https://www.sqlite.org/src/tktview/f7f8c97e975978d45 on 2016-04-25
|
||||
#
|
||||
# The where push-down optimization from 2015-06-02 is suppose to disable
|
||||
# on aggregate subqueries. But if the subquery is a compound where the
|
||||
# last SELECT is non-aggregate but some other SELECT is an aggregate, the
|
||||
# test is incomplete and the optimization is not properly disabled.
|
||||
#
|
||||
# The following test cases verify that the fix works.
|
||||
#
|
||||
do_execsql_test select4-17.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a int, b int);
|
||||
INSERT INTO t1 VALUES(1,2),(1,18),(2,19);
|
||||
SELECT x, y FROM (
|
||||
SELECT 98 AS x, 99 AS y
|
||||
UNION
|
||||
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a
|
||||
) AS w WHERE y>=20
|
||||
ORDER BY +x;
|
||||
} {1 20 98 99}
|
||||
do_execsql_test select4-17.2 {
|
||||
SELECT x, y FROM (
|
||||
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a
|
||||
UNION
|
||||
SELECT 98 AS x, 99 AS y
|
||||
) AS w WHERE y>=20
|
||||
ORDER BY +x;
|
||||
} {1 20 98 99}
|
||||
do_catchsql_test select4-17.3 {
|
||||
SELECT x, y FROM (
|
||||
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a LIMIT 3
|
||||
UNION
|
||||
SELECT 98 AS x, 99 AS y
|
||||
) AS w WHERE y>=20
|
||||
ORDER BY +x;
|
||||
} {1 {LIMIT clause should come after UNION not before}}
|
||||
|
||||
|
||||
|
||||
|
||||
+58
-16
@@ -76,20 +76,20 @@ do_test shell1-1.3.3 {
|
||||
|
||||
# -echo print commands before execution
|
||||
do_test shell1-1.4.1 {
|
||||
catchcmd "-echo test.db" ""
|
||||
catchcmd "-echo test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -[no]header turn headers on or off
|
||||
do_test shell1-1.5.1 {
|
||||
catchcmd "-header test.db" ""
|
||||
catchcmd "-header test.db" ""
|
||||
} {0 {}}
|
||||
do_test shell1-1.5.2 {
|
||||
catchcmd "-noheader test.db" ""
|
||||
catchcmd "-noheader test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -bail stop after hitting an error
|
||||
do_test shell1-1.6.1 {
|
||||
catchcmd "-bail test.db" ""
|
||||
catchcmd "-bail test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -interactive force interactive I/O
|
||||
@@ -103,40 +103,40 @@ do_test shell1-1.7.1 {
|
||||
|
||||
# -batch force batch I/O
|
||||
do_test shell1-1.8.1 {
|
||||
catchcmd "-batch test.db" ""
|
||||
catchcmd "-batch test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -column set output mode to 'column'
|
||||
do_test shell1-1.9.1 {
|
||||
catchcmd "-column test.db" ""
|
||||
catchcmd "-column test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -csv set output mode to 'csv'
|
||||
do_test shell1-1.10.1 {
|
||||
catchcmd "-csv test.db" ""
|
||||
catchcmd "-csv test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -html set output mode to HTML
|
||||
do_test shell1-1.11.1 {
|
||||
catchcmd "-html test.db" ""
|
||||
catchcmd "-html test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -line set output mode to 'line'
|
||||
do_test shell1-1.12.1 {
|
||||
catchcmd "-line test.db" ""
|
||||
catchcmd "-line test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -list set output mode to 'list'
|
||||
do_test shell1-1.13.1 {
|
||||
catchcmd "-list test.db" ""
|
||||
catchcmd "-list test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -separator 'x' set output field separator (|)
|
||||
do_test shell1-1.14.1 {
|
||||
catchcmd "-separator 'x' test.db" ""
|
||||
catchcmd "-separator 'x' test.db" ""
|
||||
} {0 {}}
|
||||
do_test shell1-1.14.2 {
|
||||
catchcmd "-separator x test.db" ""
|
||||
catchcmd "-separator x test.db" ""
|
||||
} {0 {}}
|
||||
do_test shell1-1.14.3 {
|
||||
set res [catchcmd "-separator" ""]
|
||||
@@ -147,7 +147,7 @@ do_test shell1-1.14.3 {
|
||||
|
||||
# -stats print memory stats before each finalize
|
||||
do_test shell1-1.14b.1 {
|
||||
catchcmd "-stats test.db" ""
|
||||
catchcmd "-stats test.db" ""
|
||||
} {0 {}}
|
||||
|
||||
# -nullvalue 'text' set text string for NULL values
|
||||
@@ -175,7 +175,7 @@ do_test shell1-1.16.1 {
|
||||
|
||||
# check first token handling
|
||||
do_test shell1-2.1.1 {
|
||||
catchcmd "test.db" ".foo"
|
||||
catchcmd "test.db" ".foo"
|
||||
} {1 {Error: unknown command or invalid arguments: "foo". Enter ".help" for help}}
|
||||
do_test shell1-2.1.2 {
|
||||
catchcmd "test.db" ".\"foo OFF\""
|
||||
@@ -568,7 +568,7 @@ do_test shell1-3.21.2 {
|
||||
do_test shell1-3.21.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".schema FOO BAD"
|
||||
} {1 {Usage: .schema ?LIKE-PATTERN?}}
|
||||
} {1 {Usage: .schema ?--indent? ?LIKE-PATTERN?}}
|
||||
|
||||
do_test shell1-3.21.4 {
|
||||
catchcmd "test.db" {
|
||||
@@ -905,9 +905,51 @@ do_test shell1-5.0 {
|
||||
error "failed with error: $res"
|
||||
}
|
||||
if {$res ne "$oldChar\n"} {
|
||||
error "failed with byte $hex mismatch"
|
||||
if {[llength $res] > 0} {
|
||||
set got [format %02X [scan $res %c]]
|
||||
} else {
|
||||
set got <empty>
|
||||
}
|
||||
error "failed with byte $hex mismatch, got $got"
|
||||
}
|
||||
}
|
||||
} {}
|
||||
|
||||
# The string used here is the word "test" in Chinese.
|
||||
# In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95
|
||||
set test \u6D4B\u8BD5
|
||||
|
||||
do_test shell1-6.0 {
|
||||
set fileName $test; append fileName .db
|
||||
catch {forcedelete $fileName}
|
||||
set x [catchcmdex $fileName "CREATE TABLE t1(x);\n.schema\n"]
|
||||
set code [lindex $x 0]
|
||||
set res [string trim [lindex $x 1]]
|
||||
if {$code ne "0"} {
|
||||
error "failed with error: $res"
|
||||
}
|
||||
if {$res ne "CREATE TABLE t1(x);"} {
|
||||
error "failed with mismatch: $res"
|
||||
}
|
||||
if {![file exists $fileName]} {
|
||||
error "file \"$fileName\" (Unicode) does not exist"
|
||||
}
|
||||
forcedelete $fileName
|
||||
} {}
|
||||
|
||||
do_test shell1-6.1 {
|
||||
catch {forcedelete test3.db}
|
||||
set x [catchcmdex test3.db \
|
||||
"CREATE TABLE [encoding convertto utf-8 $test](x);\n.schema\n"]
|
||||
set code [lindex $x 0]
|
||||
set res [string trim [lindex $x 1]]
|
||||
if {$code ne "0"} {
|
||||
error "failed with error: $res"
|
||||
}
|
||||
if {$res ne "CREATE TABLE ${test}(x);"} {
|
||||
error "failed with mismatch: $res"
|
||||
}
|
||||
forcedelete test3.db
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -365,4 +365,78 @@ do_test 6.5 {
|
||||
|
||||
sqlite3_snapshot_free $snapshot
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests investigate the sqlite3_snapshot_cmp() API.
|
||||
#
|
||||
|
||||
# Compare snapshots $p1 and $p2, checking that the result is $r.
|
||||
#
|
||||
proc do_snapshot_cmp_test {tn p1 p2 r} {
|
||||
uplevel [list do_test $tn.1 [list sqlite3_snapshot_cmp $p1 $p2] $r]
|
||||
uplevel [list do_test $tn.2 [list sqlite3_snapshot_cmp $p2 $p1] [expr $r*-1]]
|
||||
uplevel [list do_test $tn.3 [list sqlite3_snapshot_cmp $p1 $p1] 0]
|
||||
uplevel [list do_test $tn.4 [list sqlite3_snapshot_cmp $p2 $p2] 0]
|
||||
}
|
||||
|
||||
catch { db2 close }
|
||||
reset_db
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE t1(x);
|
||||
} wal
|
||||
|
||||
do_test 7.1.2 {
|
||||
execsql { BEGIN ; PRAGMA application_id }
|
||||
set p1 [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(10);
|
||||
COMMIT;
|
||||
}
|
||||
execsql { BEGIN ; PRAGMA application_id }
|
||||
set p2 [sqlite3_snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test 7.1.3 $p1 $p2 -1
|
||||
sqlite3_snapshot_free $p1
|
||||
sqlite3_snapshot_free $p2
|
||||
|
||||
do_execsql_test 7.2.1 {
|
||||
INSERT INTO t1 VALUES(11);
|
||||
INSERT INTO t1 VALUES(12);
|
||||
INSERT INTO t1 VALUES(13);
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
} {0}
|
||||
do_test 7.2.2 {
|
||||
set p1 [sqlite3_snapshot_get db main]
|
||||
execsql {
|
||||
COMMIT;
|
||||
INSERT INTO t1 VALUES(14);
|
||||
PRAGMA wal_checkpoint;
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
}
|
||||
set p2 [sqlite3_snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test 7.2.3 $p1 $p2 -1
|
||||
sqlite3_snapshot_free $p2
|
||||
|
||||
do_test 7.3.1 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(14);
|
||||
BEGIN;
|
||||
PRAGMA application_id;
|
||||
}
|
||||
set p2 [sqlite3_snapshot_get db main]
|
||||
execsql COMMIT
|
||||
} {}
|
||||
|
||||
do_snapshot_cmp_test 7.3.2 $p1 $p2 -1
|
||||
sqlite3_snapshot_free $p1
|
||||
sqlite3_snapshot_free $p2
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -41,4 +41,76 @@ do_execsql_test 1.2 {
|
||||
|
||||
db close
|
||||
tvfs delete
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that the PMA size is determined correctly. The PMA size should be
|
||||
# roughly the same amount of memory allocated to the main pager cache, or
|
||||
# 250 pages if this is larger.
|
||||
#
|
||||
testvfs tvfs
|
||||
tvfs script tv_callback
|
||||
tvfs filter {xOpen xWrite}
|
||||
|
||||
proc tv_callback {method args} {
|
||||
global iTemp
|
||||
global F
|
||||
switch $method {
|
||||
xOpen {
|
||||
if {[lindex $args 0]==""} { return "temp[incr iTemp]" }
|
||||
return "SQLITE_OK"
|
||||
}
|
||||
|
||||
xWrite {
|
||||
foreach {filename id off amt} $args {}
|
||||
if {[info exists F($id)]==0 || $F($id)<($off + $amt)} {
|
||||
set F($id) [expr $off+$amt]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch { db close }
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db -vfs tvfs
|
||||
execsql { CREATE TABLE t1(x) }
|
||||
|
||||
# Each iteration of the following loop attempts to sort 10001 records
|
||||
# each a bit over 100 bytes in size. In total a little more than 1MiB
|
||||
# of data.
|
||||
#
|
||||
breakpoint
|
||||
foreach {tn pgsz cachesz bTemp} {
|
||||
2 1024 1000 1
|
||||
|
||||
1 4096 1000 0
|
||||
2 1024 1000 1
|
||||
|
||||
3 4096 -1000 1
|
||||
4 1024 -1000 1
|
||||
|
||||
5 4096 -9000 0
|
||||
6 1024 -9000 0
|
||||
} {
|
||||
do_execsql_test 2.$tn.0 "
|
||||
PRAGMA page_size = $pgsz;
|
||||
VACUUM;
|
||||
PRAGMA cache_size = $cachesz;
|
||||
"
|
||||
|
||||
do_test 2.$tn.1 {
|
||||
set ::iTemp 0
|
||||
catch { array unset F }
|
||||
execsql {
|
||||
WITH x(i, j) AS (
|
||||
SELECT 1, randomblob(100)
|
||||
UNION ALL
|
||||
SELECT i+1, randomblob(100) FROM x WHERE i<10000
|
||||
)
|
||||
SELECT * FROM x ORDER BY j;
|
||||
}
|
||||
expr {[array names F]!=""}
|
||||
} $bTemp
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+27
-14
@@ -30,6 +30,7 @@ static const char zHelp[] =
|
||||
" --shrink-memory Invoke sqlite3_db_release_memory() frequently.\n"
|
||||
" --size N Relative test size. Default=100\n"
|
||||
" --stats Show statistics at the end\n"
|
||||
" --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n"
|
||||
" --testset T Run test-set T\n"
|
||||
" --trace Turn on SQL tracing\n"
|
||||
" --threads N Use up to N threads for sorting\n"
|
||||
@@ -69,6 +70,7 @@ static struct Global {
|
||||
int bExplain; /* Print SQL with EXPLAIN prefix */
|
||||
int bVerify; /* Try to verify that results are correct */
|
||||
int bMemShrink; /* Call sqlite3_db_release_memory() often */
|
||||
int eTemp; /* 0: no TEMP. 9: always TEMP. */
|
||||
int szTest; /* Scale factor for test iterations */
|
||||
const char *zWR; /* Might be WITHOUT ROWID */
|
||||
const char *zNN; /* Might be NOT NULL */
|
||||
@@ -78,6 +80,12 @@ static struct Global {
|
||||
char zResult[3000]; /* Text of the current result */
|
||||
} g;
|
||||
|
||||
/* Return " TEMP" or "", as appropriate for creating a table.
|
||||
*/
|
||||
static const char *isTemp(int N){
|
||||
return g.eTemp>=N ? " TEMP" : "";
|
||||
}
|
||||
|
||||
|
||||
/* Print an error message and exit */
|
||||
static void fatal_error(const char *zMsg, ...){
|
||||
@@ -459,8 +467,8 @@ void testset_main(void){
|
||||
maxb = roundup_allones(sz);
|
||||
speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
|
||||
speedtest1_exec("BEGIN");
|
||||
speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
|
||||
g.zNN, g.zNN, g.zNN);
|
||||
speedtest1_exec("CREATE%s TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
|
||||
isTemp(9), g.zNN, g.zNN, g.zNN);
|
||||
speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n);
|
||||
for(i=1; i<=n; i++){
|
||||
x1 = swizzle(i,maxb);
|
||||
@@ -477,8 +485,9 @@ void testset_main(void){
|
||||
n = sz;
|
||||
speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
|
||||
speedtest1_exec("BEGIN");
|
||||
speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
|
||||
g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
|
||||
speedtest1_exec(
|
||||
"CREATE%s TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
|
||||
isTemp(5), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
|
||||
speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n);
|
||||
for(i=1; i<=n; i++){
|
||||
x1 = swizzle(i,maxb);
|
||||
@@ -495,8 +504,9 @@ void testset_main(void){
|
||||
n = sz;
|
||||
speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n);
|
||||
speedtest1_exec("BEGIN");
|
||||
speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
|
||||
g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
|
||||
speedtest1_exec(
|
||||
"CREATE%s TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
|
||||
isTemp(3), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
|
||||
speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n);
|
||||
for(i=1; i<=n; i++){
|
||||
x1 = swizzle(i,maxb);
|
||||
@@ -654,12 +664,12 @@ void testset_main(void){
|
||||
speedtest1_begin_test(180, "%d INSERTS with three indexes", n);
|
||||
speedtest1_exec("BEGIN");
|
||||
speedtest1_exec(
|
||||
"CREATE TABLE t4(\n"
|
||||
"CREATE%s TABLE t4(\n"
|
||||
" a INTEGER %s %s,\n"
|
||||
" b INTEGER %s,\n"
|
||||
" c TEXT %s\n"
|
||||
") %s",
|
||||
g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
|
||||
isTemp(1), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
|
||||
speedtest1_exec("CREATE INDEX t4b ON t4(b)");
|
||||
speedtest1_exec("CREATE INDEX t4c ON t4(c)");
|
||||
speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
|
||||
@@ -1047,7 +1057,7 @@ void testset_rtree(int p1, int p2){
|
||||
speedtest1_end_test();
|
||||
|
||||
speedtest1_begin_test(101, "Copy from rtree to a regular table");
|
||||
speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
|
||||
speedtest1_exec(" TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
|
||||
speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
|
||||
speedtest1_end_test();
|
||||
|
||||
@@ -1321,6 +1331,13 @@ int main(int argc, char **argv){
|
||||
g.szTest = integerValue(argv[++i]);
|
||||
}else if( strcmp(z,"stats")==0 ){
|
||||
showStats = 1;
|
||||
}else if( strcmp(z,"temp")==0 ){
|
||||
if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
|
||||
i++;
|
||||
if( argv[i][0]<'0' || argv[i][0]>'9' || argv[i][1]!=0 ){
|
||||
fatal_error("argument to --temp should be integer between 0 and 9");
|
||||
}
|
||||
g.eTemp = argv[i][0] - '0';
|
||||
}else if( strcmp(z,"testset")==0 ){
|
||||
if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
|
||||
zTSet = argv[++i];
|
||||
@@ -1352,11 +1369,7 @@ int main(int argc, char **argv){
|
||||
argv[i], argv[0]);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if( zDbName==0 ){
|
||||
fatal_error(zHelp, argv[0]);
|
||||
}
|
||||
#endif
|
||||
if( zDbName!=0 ) unlink(zDbName);
|
||||
#if SQLITE_VERSION_NUMBER>=3006001
|
||||
if( nHeap>0 ){
|
||||
pHeap = malloc( nHeap );
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ do_execsql_test stat-0.0 {
|
||||
SELECT * FROM stat;
|
||||
} {}
|
||||
|
||||
ifcapable wal {
|
||||
if {[wal_is_capable]} {
|
||||
do_execsql_test stat-0.1 {
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA journal_mode = delete;
|
||||
|
||||
@@ -81,6 +81,7 @@ do_test sync-1.3 {
|
||||
set sqlite_sync_count
|
||||
} 11
|
||||
ifcapable pager_pragmas {
|
||||
if {[permutation]!="journaltest"} {
|
||||
do_test sync-1.4 {
|
||||
set sqlite_sync_count 0
|
||||
execsql {
|
||||
@@ -94,6 +95,7 @@ ifcapable pager_pragmas {
|
||||
set sqlite_sync_count
|
||||
} 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1944,6 +1944,12 @@ proc wal_check_journal_mode {testname {db db}} {
|
||||
}
|
||||
}
|
||||
|
||||
proc wal_is_capable {} {
|
||||
ifcapable !wal { return 0 }
|
||||
if {[permutation]=="journaltest"} { return 0 }
|
||||
return 1
|
||||
}
|
||||
|
||||
proc permutation {} {
|
||||
set perm ""
|
||||
catch {set perm $::G(perm:name)}
|
||||
|
||||
@@ -19,7 +19,8 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix tkt-2d1a5c67d
|
||||
|
||||
ifcapable {!wal || !vtab} {finish_test; return}
|
||||
ifcapable {!vtab} {finish_test; return}
|
||||
if {[wal_is_capable]==0} {finish_test; return}
|
||||
|
||||
for {set ii 1} {$ii<=10} {incr ii} {
|
||||
do_test tkt-2d1a5c67d.1.$ii {
|
||||
|
||||
@@ -18,7 +18,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
|
||||
ifcapable !wal { finish_test ; return }
|
||||
if {![wal_is_capable]} { finish_test ; return }
|
||||
|
||||
do_execsql_test tkt-313723c356.1 {
|
||||
PRAGMA page_size = 1024;
|
||||
|
||||
@@ -18,7 +18,7 @@ set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
set ::testprefix tkt-5d863f876e
|
||||
ifcapable !wal {finish_test ; return }
|
||||
if {![wal_is_capable]} {finish_test ; return }
|
||||
|
||||
do_multiclient_test tn {
|
||||
do_test $tn.1 {
|
||||
|
||||
@@ -50,4 +50,6 @@ for {set i 0} {$i < 100} {incr i} {
|
||||
} {ok}
|
||||
}
|
||||
|
||||
catch { db close }
|
||||
unregister_devsim
|
||||
finish_test
|
||||
|
||||
@@ -92,6 +92,26 @@ do_test view-1.8 {
|
||||
}
|
||||
} {2 3 5 6 8 9}
|
||||
|
||||
do_execsql_test view-1.10 {
|
||||
CREATE TABLE t9(x INTEGER);
|
||||
CREATE VIEW v9a AS SELECT x FROM t9;
|
||||
CREATE VIEW v9b AS SELECT * FROM t9;
|
||||
CREATE VIEW v9c(x) AS SELECT x FROM t9;
|
||||
CREATE VIEW v9d(x) AS SELECT * FROM t9;
|
||||
} {}
|
||||
do_execsql_test view-1.11 {
|
||||
PRAGMA table_info(v9a);
|
||||
} {0 x INTEGER 0 {} 0}
|
||||
do_execsql_test view-1.12 {
|
||||
PRAGMA table_info(v9b);
|
||||
} {0 x INTEGER 0 {} 0}
|
||||
do_execsql_test view-1.13 {
|
||||
PRAGMA table_info(v9c);
|
||||
} {0 x INTEGER 0 {} 0}
|
||||
do_execsql_test view-1.14 {
|
||||
PRAGMA table_info(v9d);
|
||||
} {0 x INTEGER 0 {} 0}
|
||||
|
||||
do_test view-2.1 {
|
||||
execsql {
|
||||
CREATE VIEW v2 AS SELECT * FROM t1 WHERE a>5
|
||||
|
||||
@@ -89,7 +89,7 @@ do_test zerodamage-2.1 {
|
||||
concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
|
||||
} {0 0 24704}
|
||||
|
||||
ifcapable wal {
|
||||
if {[wal_is_capable]} {
|
||||
# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
|
||||
# WAL file does not get too big.
|
||||
#
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user