Compare commits

...

43 Commits

Author SHA1 Message Date
drh 4a8a646723 Changing page size using VACUUM or backup is not allowed with a codec attached.
FossilOrigin-Name: 92be06c1a828d56652fa5269a3029f8cb029b2cd
2016-03-14 20:49:24 +00:00
drh 05586c3284 Merge test script fixes from trunk.
FossilOrigin-Name: ea1d2cddd59192251ee5fd912b190cded4959879
2016-03-14 18:42:04 +00:00
drh 7da56b4f65 Many more test cases fixed. Only a few remain.
FossilOrigin-Name: 99b9d7eef68fd6d5c9eecb5fbe3dfe002c1ca4a8
2016-03-14 18:34:42 +00:00
drh af3906a798 Many test cases fixed to work with encryption.
FossilOrigin-Name: d866fffb8b1af5003a8730ce7029d1edddb24d46
2016-03-14 17:05:04 +00:00
drh 7bd6b49a3e Test script changes to support testing the SQLite Encryption Extension.
FossilOrigin-Name: 1c70aa5c014fc48ab06215992a61c6f92490abe4
2016-03-14 16:16:43 +00:00
dan de503eb166 Fix the backcompat.test script so that it works with the --testdir test option.
FossilOrigin-Name: f7480e33eb82f2eae219d17ce46cd2d4edac07d2
2016-03-14 15:43:03 +00:00
drh 0d71eaa368 Run TCL tests in the "testdir" subdirectory.
FossilOrigin-Name: 90e0cc7b0be31ee2f155c2c053b0cbac584f6154
2016-03-14 15:03:54 +00:00
drh e500f65a2c More file pathname normalization.
FossilOrigin-Name: fa8c12921f8361f1889724bb7c5f7eca9c48b075
2016-03-14 14:59:35 +00:00
drh bea14132cf Normalize the $testdir and $argv0 paths so that they continue to work
in the testing subdirectory.

FossilOrigin-Name: 19225b8130f1640772fc54250583b571a89063b6
2016-03-14 14:28:43 +00:00
drh d5704a8961 Run TCL tests in a subdirectory "testdir".
FossilOrigin-Name: f632bba0d6ad3edc60f4127380ce8320378dac42
2016-03-14 13:42:29 +00:00
dan 7d85774da8 Fix a memory leak in fts5 that could occur following a syntax error in a query expression.
FossilOrigin-Name: 54b8968e335760105206b894672213c1d56771a4
2016-03-14 12:16:23 +00:00
dan 5cf98f101e Fix a problem handling 'NEAR("" token)' in fts5 found by fuzzing.
FossilOrigin-Name: 10a827ae5f3f322af836c15e581fdc958a433a5a
2016-03-12 19:33:47 +00:00
dan e8c20120ce Fix handling of strings that contain zero tokens in fts5. And other problems found by fuzzing.
FossilOrigin-Name: 72b3ff0f0df83e62adda6584b4281cf086d45e45
2016-03-12 16:32:16 +00:00
drh ffbb02a361 Do not allow the use of WAL mode with nolock=1 because it does not work.
FossilOrigin-Name: 74f5d3b07f6e5e977858c73957c6f9337ae3ca3e
2016-03-11 23:07:30 +00:00
dan e1f1ffa55a Tweak the amalgamation autoconf files so that the --disable-static-shell option works again.
FossilOrigin-Name: 83efcdebfa255cd0663ecc6b74eb99183e2f3a10
2016-03-11 15:25:13 +00:00
drh 811f17bac0 Update spellfix1_scriptcode() to output 215 (latin) for pure numeric text.
FossilOrigin-Name: df44308b862e932ff0ad25b6328d13be22047b96
2016-03-11 14:30:18 +00:00
mistachkin a0ca3bc854 Check for PDB files prior to attempting to copy them in the MSVC batch build tool.
FossilOrigin-Name: d7c20f04e69fb1848b2e2f3b04fbd56e06c7c854
2016-03-10 19:08:44 +00:00
dan 1bb85f3ed3 Add tests to cover untested branches in recent fts5 changes.
FossilOrigin-Name: fa0033edf6ddf3c6631fa95b343225dbc8ac9429
2016-03-10 15:12:47 +00:00
drh ecdf20d3a4 Use #ifdefs to remove code that is unreachable in some configurations, replacing
it with an assert().

FossilOrigin-Name: f96ec84d605fd73c323344a753acf35b76307af9
2016-03-10 14:28:24 +00:00
drh 6459ca0b8c Remove an unused local variable.
FossilOrigin-Name: 3c343c3d012367942037e64a9855b825cb459844
2016-03-10 14:22:42 +00:00
dan 4dbc65b29a Add an incremental optimize capability to fts5. Make the 'merge' command independent of the 'automerge' settings.
FossilOrigin-Name: 556671444c03e3afca072d0f5e9bea2657de6fd3
2016-03-09 20:54:14 +00:00
dan 57ebc84a6e Fix a problem in fts3/4 that was causing it to discard data cached in-memory if an 'optimize' command is run when there is no data on disk. The usual way this would happen is if the very first transaction that writes to the fts3/4 table also includes an 'optimize' command.
FossilOrigin-Name: 79338b991bf01e81d336790ca87a0fa747da4ff3
2016-03-09 18:17:42 +00:00
drh 69c355bd9a Slight simplification to the query optimizer logic associated with IN (SELECT).
FossilOrigin-Name: 2c55c3c2950cafdc256ab540f60dc4609b9c354b
2016-03-09 15:34:51 +00:00
dan ab8aa11b96 Add another test case for bug [5e3c8867].
FossilOrigin-Name: d91e57e49f23414ec9211b775eb11cd6230a4f96
2016-03-09 15:14:54 +00:00
drh 90730c9e68 When optimizing expressions of the form "x IN (SELECT ...)" make sure that
the subquery is not correlated.  Fix for ticket [5e3c886796e5512].

FossilOrigin-Name: 1ed6b06ea3c432f920fb2b66b6042be906c5d21c
2016-03-09 15:09:22 +00:00
drh 7c621fb967 Automatically disable SQLITE_ENABLE_EXPLAIN_COMMENTS if SQLITE_OMIT_EXPLAIN
is defined.

FossilOrigin-Name: 8d4b6b2b519a80f831d64345ac26db825b0e2ebe
2016-03-09 13:39:43 +00:00
drh bacbbccd16 In the query planner, make sure OOM errors are reported up into
whereLoopAddVirtual() so that it shuts down appropriately.

FossilOrigin-Name: a13c59d08bcbc6f26ce6ac761a892eff8f035201
2016-03-09 12:35:18 +00:00
drh c5644346b6 Disable the bestindex*.test modules when building without virtual table support.
FossilOrigin-Name: e0bac2f3eed900d3a26de339fb7d5963f9b47724
2016-03-09 11:59:16 +00:00
drh d93b2b840d Simplifications to the memjournal.c logic to facilitate testing.
FossilOrigin-Name: 8baa2c2c7698e03418531482a8314a5d7ae2c7d3
2016-03-09 04:17:17 +00:00
drh 769b4c95ca Move the write failure test in memjrnlCreateFile() to just after the
actual write, thus reducing the number of instances of the test by one.

FossilOrigin-Name: 7f00d80c63b15376391f661d872f2b29a970702d
2016-03-09 03:44:32 +00:00
drh c1fb2b87bd Update a comment in btree.c to account for WITHOUT ROWID tables. No code
changes.

FossilOrigin-Name: fa20dcb03b92be3bb32f8e3d6f88681ace3f6c84
2016-03-09 03:29:27 +00:00
drh 2f1e02e8a7 Change a branch made obsolete by recent parser enhancements into an assert().
FossilOrigin-Name: ee486ef742557244f532e8d3b3604ff04e024b8a
2016-03-09 02:12:44 +00:00
drh 273021d71a Add an #ifdef and an ALWAYS() for coverage.
FossilOrigin-Name: 069337a922867ad0d023f5bf36e13ea46e047000
2016-03-09 02:03:03 +00:00
drh d1cca3b721 Change an unreachable branch in the virtual table query planner into
an assert().

FossilOrigin-Name: 73b97b9ec3c39ab2828ae6353b5d7e04a27996c9
2016-03-08 23:44:48 +00:00
drh 3349d9bea9 Improved comments on virtual table query planning. Added many new
WHERETRACE() macros.

FossilOrigin-Name: 4c89c2534abcf67bc486d5a900a84a6c4f59537e
2016-03-08 23:18:51 +00:00
drh c629e63a55 In memjournal.c, reuse the same sqlite3_file object for both the in-memory
phase and the on-disk phase.

FossilOrigin-Name: e7fbbdc25c0991d4e58d78a5fcb7386e1aa7f3af
2016-03-08 17:59:19 +00:00
dan 7ed4020890 Modify the memjournal.c code to make it a bit smaller.
FossilOrigin-Name: d99ac4154812065eef26c298de52954d7ee0bd75
2016-03-08 17:44:08 +00:00
drh 33b104af08 Drop support for SQLITE_EXTRA_DURABLE. The new SQLITE_DEFAULT_SYNCHRONOUS
compile-time option is a more general replacement.

FossilOrigin-Name: f6d3156ba9af1da517dd77c1df03fa7869888463
2016-03-08 16:07:59 +00:00
drh 15d36c603d Remove an unused goto label in the RBU extension.
FossilOrigin-Name: 2179a106e8dd7943d4f37093e65ce7826720904e
2016-03-08 16:02:37 +00:00
dan d0b8b664bd Add a new row type to RBU (a peer of insert, update and delete) - "delete then insert".
FossilOrigin-Name: 1d9468d2427d2c9b7240b364554ac85a0b62fa44
2016-03-08 15:52:43 +00:00
drh 9219bf9839 Add the SQLITE_DEFAULT_SYNCHRONOUS and SQLITE_DEFAULT_WAL_SYNCHRONOUS
compile-time options.  Automatically switch to the WAL_SYNCHRONOUS setting
when first opening a WAL-mode database if the synchronous setting has not
been previously set by the application.

FossilOrigin-Name: 5a847a676e756bbe33436596d4279f339bfb247c
2016-03-08 15:47:47 +00:00
dan c7dbce0f2a Update fts3/4 so that the 'merge=X,Y' command merges at least, instead of exactly, Y segments from a single level. This matches the documentation. 'merge=X,0' is, as it was in 3.11, an error.
FossilOrigin-Name: 64b3cb29159491cbfab7e01844b54408541ece5e
2016-03-08 15:37:48 +00:00
dan e45216fd9d Add a new row type to RBU (a peer of insert, update and delete) - "delete then insert".
FossilOrigin-Name: 169311c85b30f625bdb6986c9cd11db70942d73b
2016-03-07 17:39:30 +00:00
83 changed files with 1556 additions and 730 deletions
+3 -2
View File
@@ -6,8 +6,9 @@ libsqlite3_la_SOURCES = sqlite3.c
libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
bin_PROGRAMS = sqlite3
sqlite3_SOURCES = shell.c sqlite3.c sqlite3.h
sqlite3_LDADD = @READLINE_LIBS@
sqlite3_SOURCES = shell.c sqlite3.h
EXTRA_sqlite3_SOURCES = sqlite3.c
sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@
sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS
+1 -1
View File
@@ -130,7 +130,7 @@ AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(
[statically link libsqlite3 into shell tool [default=yes]])],
[], [enable_static_shell=yes])
if test x"$enable_static_shell" == "xyes"; then
EXTRA_SHELL_OBJ=sqlite3.$OBJEXT
EXTRA_SHELL_OBJ=sqlite3-sqlite3.$OBJEXT
else
EXTRA_SHELL_OBJ=libsqlite3.la
fi
+4 -7
View File
@@ -3195,7 +3195,7 @@ static int fts3SegmentMerge(
** segment. The level of the new segment is equal to the numerically
** greatest segment level currently present in the database for this
** index. The idx of the new segment is always 0. */
if( csr.nSegment==1 ){
if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){
rc = SQLITE_DONE;
goto finished;
}
@@ -4840,11 +4840,8 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin));
if( sqlite3_step(pFindLevel)==SQLITE_ROW ){
iAbsLevel = sqlite3_column_int64(pFindLevel, 0);
if( nMin<2 ){
nSeg = sqlite3_column_int(pFindLevel, 1);
}else{
nSeg = nMin;
}
nSeg = sqlite3_column_int(pFindLevel, 1);
assert( nSeg>=2 );
}else{
nSeg = -1;
}
@@ -4996,7 +4993,7 @@ static int fts3DoIncrmerge(
nMin = fts3Getint(&z);
}
if( z[0]!='\0' || nMin<0 || nMin==1 ){
if( z[0]!='\0' || nMin<2 ){
rc = SQLITE_ERROR;
}else{
rc = SQLITE_OK;
+7
View File
@@ -172,6 +172,7 @@ struct Fts5Config {
int pgsz; /* Approximate page size used in %_data */
int nAutomerge; /* 'automerge' setting */
int nCrisisMerge; /* Maximum allowed segments per level */
int nUsermerge; /* 'usermerge' setting */
int nHashSize; /* Bytes of memory for in-memory hash */
char *zRank; /* Name of rank function */
char *zRankArgs; /* Arguments to rank function */
@@ -700,6 +701,12 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
Fts5ExprNearset *pNear
);
Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
Fts5Parse *pParse,
Fts5ExprNode *pLeft,
Fts5ExprNode *pRight
);
Fts5ExprPhrase *sqlite3Fts5ParseTerm(
Fts5Parse *pParse,
Fts5ExprPhrase *pPhrase,
+17 -1
View File
@@ -18,6 +18,7 @@
#define FTS5_DEFAULT_PAGE_SIZE 4050
#define FTS5_DEFAULT_AUTOMERGE 4
#define FTS5_DEFAULT_USERMERGE 4
#define FTS5_DEFAULT_CRISISMERGE 16
#define FTS5_DEFAULT_HASHSIZE (1024*1024)
@@ -441,7 +442,9 @@ static const char *fts5ConfigGobbleWord(
*pbQuoted = 1;
}else{
zRet = fts5ConfigSkipBareword(zIn);
zOut[zRet-zIn] = '\0';
if( zRet ){
zOut[zRet-zIn] = '\0';
}
}
}
@@ -857,6 +860,18 @@ int sqlite3Fts5ConfigSetValue(
}
}
else if( 0==sqlite3_stricmp(zKey, "usermerge") ){
int nUsermerge = -1;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
nUsermerge = sqlite3_value_int(pVal);
}
if( nUsermerge<2 || nUsermerge>16 ){
*pbBadkey = 1;
}else{
pConfig->nUsermerge = nUsermerge;
}
}
else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){
int nCrisisMerge = -1;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
@@ -903,6 +918,7 @@ int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
/* Set default values */
pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
+131 -36
View File
@@ -258,6 +258,8 @@ int sqlite3Fts5ExprNew(
pNew->nPhrase = sParse.nPhrase;
sParse.apPhrase = 0;
}
}else{
sqlite3Fts5ParseNodeFree(sParse.pExpr);
}
sqlite3_free(sParse.apPhrase);
@@ -1268,6 +1270,8 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
if( Fts5NodeIsString(pNode) ){
/* Initialize all term iterators in the NEAR object. */
rc = fts5ExprNearInitAll(pExpr, pNode);
}else if( pNode->xNext==0 ){
pNode->bEof = 1;
}else{
int i;
int nEof = 0;
@@ -1319,23 +1323,22 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
*/
int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
Fts5ExprNode *pRoot = p->pRoot;
int rc = SQLITE_OK;
if( pRoot->xNext ){
p->pIndex = pIdx;
p->bDesc = bDesc;
rc = fts5ExprNodeFirst(p, pRoot);
int rc; /* Return code */
/* If not at EOF but the current rowid occurs earlier than iFirst in
** the iteration order, move to document iFirst or later. */
if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
}
p->pIndex = pIdx;
p->bDesc = bDesc;
rc = fts5ExprNodeFirst(p, pRoot);
/* If the iterator is not at a real match, skip forward until it is. */
while( pRoot->bNomatch ){
assert( pRoot->bEof==0 && rc==SQLITE_OK );
rc = fts5ExprNodeNext(p, pRoot, 0, 0);
}
/* If not at EOF but the current rowid occurs earlier than iFirst in
** the iteration order, move to document iFirst or later. */
if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
}
/* If the iterator is not at a real match, skip forward until it is. */
while( pRoot->bNomatch ){
assert( pRoot->bEof==0 && rc==SQLITE_OK );
rc = fts5ExprNodeNext(p, pRoot, 0, 0);
}
return rc;
}
@@ -1444,6 +1447,21 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
sqlite3Fts5ParseNearsetFree(pNear);
sqlite3Fts5ParsePhraseFree(pPhrase);
}else{
if( pRet->nPhrase>0 ){
Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
if( pPhrase->nTerm==0 ){
fts5ExprPhraseFree(pPhrase);
pRet->nPhrase--;
pParse->nPhrase--;
pPhrase = pLast;
}else if( pLast->nTerm==0 ){
fts5ExprPhraseFree(pLast);
pParse->apPhrase[pParse->nPhrase-2] = pPhrase;
pParse->nPhrase--;
pRet->nPhrase--;
}
}
pRet->apPhrase[pRet->nPhrase++] = pPhrase;
}
return pRet;
@@ -1476,8 +1494,7 @@ static int fts5ParseTokenize(
/* If an error has already occurred, this is a no-op */
if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
assert( pPhrase==0 || pPhrase->nTerm>0 );
if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
Fts5ExprTerm *pSyn;
int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
@@ -1578,7 +1595,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
pParse->rc = rc;
fts5ExprPhraseFree(sCtx.pPhrase);
sCtx.pPhrase = 0;
}else if( sCtx.pPhrase ){
}else{
if( pAppend==0 ){
if( (pParse->nPhrase % 8)==0 ){
@@ -1595,9 +1612,14 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
pParse->nPhrase++;
}
if( sCtx.pPhrase==0 ){
/* This happens when parsing a token or quoted phrase that contains
** no token characters at all. (e.g ... MATCH '""'). */
sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
}else if( sCtx.pPhrase->nTerm ){
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
}
pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
assert( sCtx.pPhrase->nTerm>0 );
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
}
return sCtx.pPhrase;
@@ -1693,23 +1715,25 @@ void sqlite3Fts5ParseSetDistance(
Fts5ExprNearset *pNear,
Fts5Token *p
){
int nNear = 0;
int i;
if( p->n ){
for(i=0; i<p->n; i++){
char c = (char)p->p[i];
if( c<'0' || c>'9' ){
sqlite3Fts5ParseError(
pParse, "expected integer, got \"%.*s\"", p->n, p->p
);
return;
if( pNear ){
int nNear = 0;
int i;
if( p->n ){
for(i=0; i<p->n; i++){
char c = (char)p->p[i];
if( c<'0' || c>'9' ){
sqlite3Fts5ParseError(
pParse, "expected integer, got \"%.*s\"", p->n, p->p
);
return;
}
nNear = nNear * 10 + (p->p[i] - '0');
}
nNear = nNear * 10 + (p->p[i] - '0');
}else{
nNear = FTS5_DEFAULT_NEARDIST;
}
}else{
nNear = FTS5_DEFAULT_NEARDIST;
pNear->nNear = nNear;
}
pNear->nNear = nNear;
}
/*
@@ -1896,10 +1920,14 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
int iPhrase;
for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
pNear->apPhrase[iPhrase]->pNode = pRet;
if( pNear->apPhrase[iPhrase]->nTerm==0 ){
pRet->xNext = 0;
pRet->eType = FTS5_EOF;
}
}
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL
&& (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm!=1)
&& (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1)
){
assert( pParse->rc==SQLITE_OK );
pParse->rc = SQLITE_ERROR;
@@ -1928,6 +1956,70 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
return pRet;
}
Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
Fts5Parse *pParse, /* Parse context */
Fts5ExprNode *pLeft, /* Left hand child expression */
Fts5ExprNode *pRight /* Right hand child expression */
){
Fts5ExprNode *pRet = 0;
Fts5ExprNode *pPrev;
if( pParse->rc ){
sqlite3Fts5ParseNodeFree(pLeft);
sqlite3Fts5ParseNodeFree(pRight);
}else{
assert( pLeft->eType==FTS5_STRING
|| pLeft->eType==FTS5_TERM
|| pLeft->eType==FTS5_EOF
|| pLeft->eType==FTS5_AND
);
assert( pRight->eType==FTS5_STRING
|| pRight->eType==FTS5_TERM
|| pRight->eType==FTS5_EOF
);
if( pLeft->eType==FTS5_AND ){
pPrev = pLeft->apChild[pLeft->nChild-1];
}else{
pPrev = pLeft;
}
assert( pPrev->eType==FTS5_STRING
|| pPrev->eType==FTS5_TERM
|| pPrev->eType==FTS5_EOF
);
if( pRight->eType==FTS5_EOF ){
assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] );
sqlite3Fts5ParseNodeFree(pRight);
pRet = pLeft;
pParse->nPhrase--;
}
else if( pPrev->eType==FTS5_EOF ){
Fts5ExprPhrase **ap;
if( pPrev==pLeft ){
pRet = pRight;
}else{
pLeft->apChild[pLeft->nChild-1] = pRight;
pRet = pLeft;
}
ap = &pParse->apPhrase[pParse->nPhrase-1-pRight->pNear->nPhrase];
assert( ap[0]==pPrev->pNear->apPhrase[0] );
memmove(ap, &ap[1], sizeof(Fts5ExprPhrase*)*pRight->pNear->nPhrase);
pParse->nPhrase--;
sqlite3Fts5ParseNodeFree(pPrev);
}
else{
pRet = sqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0);
}
}
return pRet;
}
static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
int nByte = 0;
Fts5ExprTerm *p;
@@ -2062,6 +2154,9 @@ static char *fts5ExprPrintTcl(
static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
char *zRet = 0;
if( pExpr->eType==0 ){
return sqlite3_mprintf("\"\"");
}else
if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
Fts5ExprNearset *pNear = pExpr->pNear;
int i;
@@ -2122,7 +2217,7 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
zRet = 0;
}else{
int e = pExpr->apChild[i]->eType;
int b = (e!=FTS5_STRING && e!=FTS5_TERM);
int b = (e!=FTS5_STRING && e!=FTS5_TERM && e!=FTS5_EOF);
zRet = fts5PrintfAppend(zRet, "%s%s%z%s",
(i==0 ? "" : zOp),
(b?"(":""), z, (b?")":"")
+77 -31
View File
@@ -4179,13 +4179,17 @@ static void fts5IndexMergeLevel(
/*
** Do up to nPg pages of automerge work on the index.
**
** Return true if any changes were actually made, or false otherwise.
*/
static void fts5IndexMerge(
static int fts5IndexMerge(
Fts5Index *p, /* FTS5 backend object */
Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
int nPg /* Pages of work to do */
int nPg, /* Pages of work to do */
int nMin /* Minimum number of segments to merge */
){
int nRem = nPg;
int bRet = 0;
Fts5Structure *pStruct = *ppStruct;
while( nRem>0 && p->rc==SQLITE_OK ){
int iLvl; /* To iterate through levels */
@@ -4216,17 +4220,17 @@ static void fts5IndexMerge(
}
#endif
if( nBest<p->pConfig->nAutomerge
&& pStruct->aLevel[iBestLvl].nMerge==0
){
if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
break;
}
bRet = 1;
fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
fts5StructurePromote(p, iBestLvl+1, pStruct);
}
}
*ppStruct = pStruct;
return bRet;
}
/*
@@ -4254,7 +4258,7 @@ static void fts5IndexAutomerge(
pStruct->nWriteCounter += nLeaf;
nRem = (int)(p->nWorkUnit * nWork * pStruct->nLevel);
fts5IndexMerge(p, ppStruct, nRem);
fts5IndexMerge(p, ppStruct, nRem, p->pConfig->nAutomerge);
}
}
@@ -4474,25 +4478,38 @@ static void fts5IndexFlush(Fts5Index *p){
}
}
int sqlite3Fts5IndexOptimize(Fts5Index *p){
Fts5Structure *pStruct;
static Fts5Structure *fts5IndexOptimizeStruct(
Fts5Index *p,
Fts5Structure *pStruct
){
Fts5Structure *pNew = 0;
int nSeg = 0;
int nByte = sizeof(Fts5Structure);
int nSeg = pStruct->nSegment;
int i;
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
pStruct = fts5StructureRead(p);
if( pStruct ){
assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
nSeg = pStruct->nSegment;
if( nSeg>1 ){
int nByte = sizeof(Fts5Structure);
nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
/* Figure out if this structure requires optimization. A structure does
** not require optimization if either:
**
** + it consists of fewer than two segments, or
** + all segments are on the same level, or
** + all segments except one are currently inputs to a merge operation.
**
** In the first case, return NULL. In the second, increment the ref-count
** on *pStruct and return a copy of the pointer to it.
*/
if( nSeg<2 ) return 0;
for(i=0; i<pStruct->nLevel; i++){
int nThis = pStruct->aLevel[i].nSeg;
if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
fts5StructureRef(pStruct);
return pStruct;
}
assert( pStruct->aLevel[i].nMerge<=nThis );
}
nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
Fts5StructureLevel *pLvl;
int nByte = nSeg * sizeof(Fts5StructureSegment);
@@ -4520,8 +4537,26 @@ int sqlite3Fts5IndexOptimize(Fts5Index *p){
}
}
return pNew;
}
int sqlite3Fts5IndexOptimize(Fts5Index *p){
Fts5Structure *pStruct;
Fts5Structure *pNew = 0;
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
pStruct = fts5StructureRead(p);
if( pStruct ){
pNew = fts5IndexOptimizeStruct(p, pStruct);
}
fts5StructureRelease(pStruct);
assert( pNew==0 || pNew->nSegment>0 );
if( pNew ){
int iLvl = pNew->nLevel-1;
int iLvl;
for(iLvl=0; pNew->aLevel[iLvl].nSeg==0; iLvl++){}
while( p->rc==SQLITE_OK && pNew->aLevel[iLvl].nSeg>0 ){
int nRem = FTS5_OPT_WORK_UNIT;
fts5IndexMergeLevel(p, &pNew, iLvl, &nRem);
@@ -4531,20 +4566,31 @@ int sqlite3Fts5IndexOptimize(Fts5Index *p){
fts5StructureRelease(pNew);
}
fts5StructureRelease(pStruct);
return fts5IndexReturn(p);
}
/*
** This is called to implement the special "VALUES('merge', $nMerge)"
** INSERT command.
*/
int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
Fts5Structure *pStruct;
pStruct = fts5StructureRead(p);
if( pStruct && pStruct->nLevel ){
fts5IndexMerge(p, &pStruct, nMerge);
fts5StructureWrite(p, pStruct);
Fts5Structure *pStruct = fts5StructureRead(p);
if( pStruct ){
int nMin = p->pConfig->nUsermerge;
if( nMerge<0 ){
Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
fts5StructureRelease(pStruct);
pStruct = pNew;
nMin = 2;
nMerge = nMerge*-1;
}
if( pStruct && pStruct->nLevel ){
if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
fts5StructureWrite(p, pStruct);
}
}
fts5StructureRelease(pStruct);
}
fts5StructureRelease(pStruct);
return fts5IndexReturn(p);
}
+3 -3
View File
@@ -1511,13 +1511,13 @@ static int fts5UpdateMethod(
rc = SQLITE_ERROR;
}
/* Case 1: DELETE */
/* DELETE */
else if( nArg==1 ){
i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
}
/* Case 2: INSERT */
/* INSERT */
else if( eType0!=SQLITE_INTEGER ){
/* If this is a REPLACE, first remove the current entry (if any) */
if( eConflict==SQLITE_REPLACE
@@ -1529,7 +1529,7 @@ static int fts5UpdateMethod(
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
/* Case 2: UPDATE */
/* UPDATE */
else{
i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
+15 -10
View File
@@ -68,18 +68,22 @@ struct Fts5MatchinfoCtx {
** If an error occurs, return NULL and leave an error in the database
** handle (accessible using sqlite3_errcode()/errmsg()).
*/
static fts5_api *fts5_api_from_db(sqlite3 *db){
fts5_api *pRet = 0;
static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){
sqlite3_stmt *pStmt = 0;
int rc;
if( SQLITE_OK==sqlite3_prepare(db, "SELECT fts5()", -1, &pStmt, 0)
&& SQLITE_ROW==sqlite3_step(pStmt)
&& sizeof(pRet)==sqlite3_column_bytes(pStmt, 0)
){
memcpy(&pRet, sqlite3_column_blob(pStmt, 0), sizeof(pRet));
*ppApi = 0;
rc = sqlite3_prepare(db, "SELECT fts5()", -1, &pStmt, 0);
if( rc==SQLITE_OK ){
if( SQLITE_ROW==sqlite3_step(pStmt)
&& sizeof(fts5_api*)==sqlite3_column_bytes(pStmt, 0)
){
memcpy(ppApi, sqlite3_column_blob(pStmt, 0), sizeof(fts5_api*));
}
rc = sqlite3_finalize(pStmt);
}
sqlite3_finalize(pStmt);
return pRet;
return rc;
}
@@ -399,7 +403,8 @@ int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
/* Extract the FTS5 API pointer from the database handle. The
** fts5_api_from_db() function above is copied verbatim from the
** FTS5 documentation. Refer there for details. */
pApi = fts5_api_from_db(db);
rc = fts5_api_from_db(db, &pApi);
if( rc!=SQLITE_OK ) return rc;
/* If fts5_api_from_db() returns NULL, then either FTS5 is not registered
** with this database handle, or an error (OOM perhaps?) has occurred.
+1 -1
View File
@@ -104,7 +104,7 @@ expr(A) ::= exprlist(X). {A = X;}
exprlist(A) ::= cnearset(X). {A = X;}
exprlist(A) ::= exprlist(X) cnearset(Y). {
A = sqlite3Fts5ParseNode(pParse, FTS5_AND, X, Y, 0);
A = sqlite3Fts5ParseImplicitAnd(pParse, X, Y);
}
cnearset(A) ::= nearset(X). {
+6
View File
@@ -159,6 +159,12 @@ proc fts5_aux_test_functions {db} {
}
}
proc fts5_segcount {tbl} {
set N 0
foreach n [fts5_level_segs $tbl] { incr N $n }
set N
}
proc fts5_level_segs {tbl} {
set sql "SELECT fts5_decode(rowid,block) aS r FROM ${tbl}_data WHERE rowid=10"
set ret [list]
+16
View File
@@ -247,5 +247,21 @@ do_catchsql_test 12.1 {
INSERT INTO t1(t1, rank) VALUES('rank', NULL);;
} {1 {SQL logic error or missing database}}
#-------------------------------------------------------------------------
# errors in the 'usermerge' option
#
do_execsql_test 13.0 {
CREATE VIRTUAL TABLE tt USING fts5(ttt);
}
foreach {tn val} {
1 -1
2 4.2
3 17
4 1
} {
set sql "INSERT INTO tt(tt, rank) VALUES('usermerge', $val)"
do_catchsql_test 13.$tn $sql {1 {SQL logic error or missing database}}
}
finish_test
+6 -6
View File
@@ -33,12 +33,12 @@ foreach {tn expr res} {
1 {abc} {"abc"}
2 {abc ""} {"abc"}
3 {""} {}
4 {abc OR ""} {"abc"}
5 {abc NOT ""} {"abc"}
6 {abc AND ""} {"abc"}
7 {"" OR abc} {"abc"}
8 {"" NOT abc} {"abc"}
9 {"" AND abc} {"abc"}
4 {abc OR ""} {"abc" OR ""}
5 {abc NOT ""} {"abc" NOT ""}
6 {abc AND ""} {"abc" AND ""}
7 {"" OR abc} {"" OR "abc"}
8 {"" NOT abc} {"" NOT "abc"}
9 {"" AND abc} {"" AND "abc"}
10 {abc + "" + def} {"abc" + "def"}
11 {abc "" def} {"abc" AND "def"}
12 {r+e OR w} {"r" + "e" OR "w"}
+25
View File
@@ -54,7 +54,32 @@ foreach_detail_mode $testprefix {
faultsim_test_result {0 {1 3}} {1 SQLITE_NOMEM}
}
}
} ;# foreach_detail_mode...
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE x2 USING fts5(a);
INSERT INTO x2(x2, rank) VALUES('crisismerge', 2);
INSERT INTO x2(x2, rank) VALUES('pgsz', 32);
INSERT INTO x2 VALUES('a b c d');
INSERT INTO x2 VALUES('e f g h');
INSERT INTO x2 VALUES('i j k l');
INSERT INTO x2 VALUES('m n o p');
INSERT INTO x2 VALUES('q r s t');
INSERT INTO x2 VALUES('u v w x');
INSERT INTO x2 VALUES('y z a b');
}
faultsim_save_and_close
do_faultsim_test 4 -faults oom-* -prep {
faultsim_restore_and_reopen
} -body {
execsql { INSERT INTO x2(x2) VALUES('optimize') }
} -test {
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
}
finish_test
+93
View File
@@ -0,0 +1,93 @@
# 2014 June 17
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
return_if_no_fts5
set testprefix fts5fuzz1
#-------------------------------------------------------------------------
reset_db
do_catchsql_test 1.1 {
CREATE VIRTUAL TABLE f1 USING fts5(a b);
} {/1 {parse error in.*}/}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE f1 USING fts5(a, b);
INSERT INTO f1 VALUES('a b', 'c d');
INSERT INTO f1 VALUES('e f', 'a b');
}
do_execsql_test 2.2.1 {
SELECT rowid FROM f1('""');
} {}
do_execsql_test 2.2.2 {
SELECT rowid FROM f1('"" AND a');
} {}
do_execsql_test 2.2.3 {
SELECT rowid FROM f1('"" a');
} {1 2}
do_execsql_test 2.2.4 {
SELECT rowid FROM f1('"" OR a');
} {1 2}
do_execsql_test 2.3 {
SELECT a, b FROM f1('NEAR("")');
} {}
do_execsql_test 2.4 {
SELECT a, b FROM f1('NEAR("", 5)');
} {}
do_execsql_test 2.5 {
SELECT a, b FROM f1('NEAR("" c, 5)');
} {{a b} {c d}}
do_execsql_test 2.6 {
SELECT a, b FROM f1('NEAR("" c d, 5)');
} {{a b} {c d}}
do_execsql_test 2.7 {
SELECT a, b FROM f1('NEAR(c d, 5)');
} {{a b} {c d}}
do_execsql_test 2.8 {
SELECT rowid FROM f1('NEAR("a" "b", 5)');
} {1 2}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.2 {
CREATE VIRTUAL TABLE f2 USING fts5(o, t, tokenize="ascii separators abc");
SELECT * FROM f2('a+4');
} {}
#-------------------------------------------------------------------------
reset_db
do_catchsql_test 4.1 {
CREATE VIRTUAL TABLE f2 USING fts5(o, t);
SELECT * FROM f2('(8 AND 9)`AND 10');
} {1 {fts5: syntax error near "`"}}
finish_test
+59 -9
View File
@@ -45,7 +45,7 @@ proc do_merge1_test {testname nRowPerSeg} {
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<$::nRowPerSeg)
INSERT INTO x8 SELECT repeat('x y ', i % 16) FROM ii;
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
}
for {set tn 1} {[lindex [fts5_level_segs x8] 0]>0} {incr tn} {
@@ -84,9 +84,9 @@ proc do_merge2_test {testname nRow} {
execsql { INSERT INTO x8 VALUES( rnddoc(($i%16) + 5) ) }
while {[not_merged x8]} {
execsql {
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
INSERT INTO x8(x8, rank) VALUES('merge', 1);
INSERT INTO x8(x8, rank) VALUES('automerge', 16);
INSERT INTO x8(x8, rank) VALUES('usermerge', 16);
INSERT INTO x8(x8) VALUES('integrity-check');
}
}
@@ -104,9 +104,9 @@ do_merge2_test 2.2 10
do_merge2_test 2.3 20
#-------------------------------------------------------------------------
# Test that an auto-merge will complete any merge that has already been
# Test that a merge will complete any merge that has already been
# started, even if the number of input segments is less than the current
# value of the 'automerge' configuration parameter.
# value of the 'usermerge' configuration parameter.
#
db func rnddoc fts5_rnddoc
@@ -119,7 +119,7 @@ do_execsql_test 3.1 {
}
do_test 3.2 {
execsql {
INSERT INTO x8(x8, rank) VALUES('automerge', 4);
INSERT INTO x8(x8, rank) VALUES('usermerge', 4);
INSERT INTO x8(x8, rank) VALUES('merge', 1);
}
fts5_level_segs x8
@@ -127,14 +127,14 @@ do_test 3.2 {
do_test 3.3 {
execsql {
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
INSERT INTO x8(x8, rank) VALUES('merge', 1);
}
fts5_level_segs x8
} {2 1}
do_test 3.4 {
execsql { INSERT INTO x8(x8, rank) VALUES('automerge', 4) }
execsql { INSERT INTO x8(x8, rank) VALUES('usermerge', 4) }
while {[not_merged x8]} {
execsql { INSERT INTO x8(x8, rank) VALUES('merge', 1) }
}
@@ -176,7 +176,7 @@ foreach {tn pgsz} {
INSERT INTO x8 SELECT mydoc() FROM ii;
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
INSERT INTO x8 SELECT mydoc() FROM ii;
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
}
set expect [mycount]
@@ -190,5 +190,55 @@ foreach {tn pgsz} {
# db eval {SELECT fts5_decode(rowid, block) AS r FROM x8_data} { puts $r }
}
#-------------------------------------------------------------------------
# Test that the 'merge' command does not modify the database if there is
# no work to do.
do_execsql_test 5.1 {
CREATE VIRTUAL TABLE x9 USING fts5(one, two);
INSERT INTO x9(x9, rank) VALUES('pgsz', 32);
INSERT INTO x9(x9, rank) VALUES('automerge', 2);
INSERT INTO x9(x9, rank) VALUES('usermerge', 2);
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
}
do_test 5.2 {
while 1 {
set nChange [db total_changes]
execsql { INSERT INTO x9(x9, rank) VALUES('merge', 1); }
set nChange [expr [db total_changes] - $nChange]
#puts $nChange
if {$nChange<2} break
}
} {}
#--------------------------------------------------------------------------
# Test that running 'merge' on an empty database does not cause a
# problem.
#
reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE g1 USING fts5(a, b);
}
do_execsql_test 6.1 {
INSERT INTO g1(g1, rank) VALUES('merge', 10);
}
do_execsql_test 6.2 {
INSERT INTO g1(g1, rank) VALUES('merge', -10);
}
do_execsql_test 6.3 {
INSERT INTO g1(g1) VALUES('integrity-check');
}
finish_test
+45 -2
View File
@@ -20,6 +20,12 @@ ifcapable !fts5 {
return
}
#
# 1.* - Warm body tests for index optimization using ('optimize')
#
# 2.* - Warm body tests for index optimization using ('merge', -1)
#
proc rnddoc {nWord} {
set vocab {a b c d e f g h i j k l m n o p q r s t u v w x y z}
set nVocab [llength $vocab]
@@ -30,14 +36,12 @@ proc rnddoc {nWord} {
return $ret
}
foreach {tn nStep} {
1 2
2 10
3 50
4 500
} {
if {$tn!=4} continue
reset_db
db func rnddoc rnddoc
do_execsql_test 1.$tn.1 {
@@ -60,7 +64,46 @@ if {$tn!=4} continue
do_execsql_test 1.$tn.5 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
do_test 1.$tn.6 { fts5_segcount t1 } 1
}
foreach {tn nStep} {
1 2
2 10
3 50
4 500
} {
reset_db
db func rnddoc rnddoc
do_execsql_test 1.$tn.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y);
}
do_test 2.$tn.2 {
for {set i 0} {$i < $nStep} {incr i} {
execsql { INSERT INTO t1 VALUES( rnddoc(5), rnddoc(5) ) }
}
} {}
do_execsql_test 2.$tn.3 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
do_test 2.$tn.4 {
execsql { INSERT INTO t1(t1, rank) VALUES('merge', -1) }
while 1 {
set c [db total_changes]
execsql { INSERT INTO t1(t1, rank) VALUES('merge', 1) }
set c [expr [db total_changes]-$c]
if {$c<2} break
}
} {}
do_execsql_test 2.$tn.5 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
do_test 2.$tn.6 { fts5_segcount t1 } 1
}
finish_test
+8 -2
View File
@@ -1734,6 +1734,7 @@ static void scriptCodeSqlFunc(
int c, sz;
int scriptMask = 0;
int res;
int seenDigit = 0;
# define SCRIPT_LATIN 0x0001
# define SCRIPT_CYRILLIC 0x0002
# define SCRIPT_GREEK 0x0004
@@ -1744,8 +1745,12 @@ static void scriptCodeSqlFunc(
c = utf8Read(zIn, nIn, &sz);
zIn += sz;
nIn -= sz;
if( c<0x02af && (c>=0x80 || midClass[c&0x7f]<CCLASS_DIGIT) ){
scriptMask |= SCRIPT_LATIN;
if( c<0x02af ){
if( c>=0x80 || midClass[c&0x7f]<CCLASS_DIGIT ){
scriptMask |= SCRIPT_LATIN;
}else if( c>='0' && c<='9' ){
seenDigit = 1;
}
}else if( c>=0x0400 && c<=0x04ff ){
scriptMask |= SCRIPT_CYRILLIC;
}else if( c>=0x0386 && c<=0x03ce ){
@@ -1756,6 +1761,7 @@ static void scriptCodeSqlFunc(
scriptMask |= SCRIPT_ARABIC;
}
}
if( scriptMask==0 && seenDigit ) scriptMask = SCRIPT_LATIN;
switch( scriptMask ){
case 0: res = 999; break;
case SCRIPT_LATIN: res = 215; break;
+142
View File
@@ -0,0 +1,142 @@
# 2016 March 7
#
# 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.
#
#***********************************************************************
# Tests for RBU focused on the REPLACE operation (rbu_control column
# contains integer value 2).
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbuC
#-------------------------------------------------------------------------
# This test is actually of an UPDATE directive. Just to establish that
# these work with UNIQUE indexes before preceding to REPLACE.
#
do_execsql_test 1.0 {
CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b, c UNIQUE);
INSERT INTO t1 VALUES(1, 'a', 'b', 'c');
}
forcedelete rbu.db
do_execsql_test 1.1 {
ATTACH 'rbu.db' AS rbu;
CREATE TABLE rbu.data_t1(i, a, b, c, rbu_control);
INSERT INTO data_t1 VALUES(1, 'a', 'b', 'c', '.xxx');
}
do_test 1.2 {
step_rbu test.db rbu.db
} {SQLITE_DONE}
do_execsql_test 1.3 {
SELECT * FROM t1
} {
1 a b c
}
#-------------------------------------------------------------------------
#
foreach {tn schema} {
1 {
CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b, c UNIQUE);
CREATE INDEX t1a ON t1(a);
}
2 {
CREATE TABLE t1(i PRIMARY KEY, a, b, c UNIQUE);
CREATE INDEX t1a ON t1(a);
}
3 {
CREATE TABLE t1(i PRIMARY KEY, a, b, c UNIQUE) WITHOUT ROWID;
CREATE INDEX t1a ON t1(a);
}
} {
reset_db
forcedelete rbu.db
execsql $schema
do_execsql_test 2.$tn.0 {
INSERT INTO t1 VALUES(1, 'a', 'b', 'c');
INSERT INTO t1 VALUES(2, 'b', 'c', 'd');
INSERT INTO t1 VALUES(3, 'c', 'd', 'e');
}
do_execsql_test 2.$tn.1 {
ATTACH 'rbu.db' AS rbu;
CREATE TABLE rbu.data_t1(i, a, b, c, rbu_control);
INSERT INTO data_t1 VALUES(1, 1, 2, 3, 2);
INSERT INTO data_t1 VALUES(3, 'c', 'd', 'e', 2);
INSERT INTO data_t1 VALUES(4, 'd', 'e', 'f', 2);
}
do_test 2.$tn.2 {
step_rbu test.db rbu.db
} {SQLITE_DONE}
do_execsql_test 2.$tn.3 {
SELECT * FROM t1 ORDER BY i
} {
1 1 2 3
2 b c d
3 c d e
4 d e f
}
integrity_check 2.$tn.4
}
foreach {tn schema} {
1 {
CREATE TABLE t1(a, b, c UNIQUE);
CREATE INDEX t1a ON t1(a);
}
2 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c);
}
} {
if {$tn==2} { ifcapable !fts5 break }
reset_db
forcedelete rbu.db
execsql $schema
do_execsql_test 3.$tn.0 {
INSERT INTO t1 VALUES('a', 'b', 'c');
INSERT INTO t1 VALUES('b', 'c', 'd');
INSERT INTO t1 VALUES('c', 'd', 'e');
}
do_execsql_test 3.$tn.1 {
ATTACH 'rbu.db' AS rbu;
CREATE TABLE rbu.data_t1(rbu_rowid, a, b, c, rbu_control);
INSERT INTO data_t1 VALUES(1, 1, 2, 3, 2);
INSERT INTO data_t1 VALUES(3, 'c', 'd', 'e', 2);
INSERT INTO data_t1 VALUES(4, 'd', 'e', 'f', 2);
}
do_test 3.$tn.2 {
step_rbu test.db rbu.db
} {SQLITE_DONE}
do_execsql_test 3.$tn.3 {
SELECT rowid, * FROM t1 ORDER BY 1
} {
1 1 2 3
2 b c d
3 c d e
4 d e f
}
integrity_check 3.$tn.4
}
finish_test
+90 -78
View File
@@ -280,10 +280,11 @@ struct RbuObjIter {
*/
#define RBU_INSERT 1 /* Insert on a main table b-tree */
#define RBU_DELETE 2 /* Delete a row from a main table b-tree */
#define RBU_IDX_DELETE 3 /* Delete a row from an aux. index b-tree */
#define RBU_IDX_INSERT 4 /* Insert on an aux. index b-tree */
#define RBU_UPDATE 5 /* Update a row in a main table b-tree */
#define RBU_REPLACE 3 /* Delete and then insert a row */
#define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */
#define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */
#define RBU_UPDATE 6 /* Update a row in a main table b-tree */
/*
** A single step of an incremental checkpoint - frame iWalFrame of the wal
@@ -1909,13 +1910,13 @@ static int rbuObjIterPrepareAll(
);
}else{
zSql = sqlite3_mprintf(
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
"UNION ALL "
"SELECT %s, rbu_control FROM '%q' "
"WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
"UNION ALL "
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
"ORDER BY %s%s",
zCollist, pIter->zDataTbl,
zCollist, p->zStateDb, pIter->zDataTbl,
zCollist, pIter->zDataTbl,
zCollist, zLimit
);
}
@@ -1981,17 +1982,17 @@ static int rbuObjIterPrepareAll(
rbuMPrintfExec(p, p->dbMain,
"CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" "
"BEGIN "
" SELECT rbu_tmp_insert(2, %s);"
" SELECT rbu_tmp_insert(3, %s);"
"END;"
"CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" "
"BEGIN "
" SELECT rbu_tmp_insert(2, %s);"
" SELECT rbu_tmp_insert(3, %s);"
"END;"
"CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" "
"BEGIN "
" SELECT rbu_tmp_insert(3, %s);"
" SELECT rbu_tmp_insert(4, %s);"
"END;",
zWrite, zTbl, zOldlist,
zWrite, zTbl, zOldlist,
@@ -2509,14 +2510,12 @@ static int rbuStepType(sqlite3rbu *p, const char **pzMask){
switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
case SQLITE_INTEGER: {
int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
if( iVal==0 ){
res = RBU_INSERT;
}else if( iVal==1 ){
res = RBU_DELETE;
}else if( iVal==2 ){
res = RBU_IDX_DELETE;
}else if( iVal==3 ){
res = RBU_IDX_INSERT;
switch( iVal ){
case 0: res = RBU_INSERT; break;
case 1: res = RBU_DELETE; break;
case 2: res = RBU_REPLACE; break;
case 3: res = RBU_IDX_DELETE; break;
case 4: res = RBU_IDX_INSERT; break;
}
break;
}
@@ -2555,6 +2554,67 @@ static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
# define assertColumnName(x,y,z)
#endif
/*
** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or
** RBU_IDX_DELETE. This function performs the work of a single
** sqlite3rbu_step() call for the type of operation specified by eType.
*/
static void rbuStepOneOp(sqlite3rbu *p, int eType){
RbuObjIter *pIter = &p->objiter;
sqlite3_value *pVal;
sqlite3_stmt *pWriter;
int i;
assert( p->rc==SQLITE_OK );
assert( eType!=RBU_DELETE || pIter->zIdx==0 );
if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
pWriter = pIter->pDelete;
}else{
pWriter = pIter->pInsert;
}
for(i=0; i<pIter->nCol; i++){
/* If this is an INSERT into a table b-tree and the table has an
** explicit INTEGER PRIMARY KEY, check that this is not an attempt
** to write a NULL into the IPK column. That is not permitted. */
if( eType==RBU_INSERT
&& pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i]
&& sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
){
p->rc = SQLITE_MISMATCH;
p->zErrmsg = sqlite3_mprintf("datatype mismatch");
return;
}
if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
continue;
}
pVal = sqlite3_column_value(pIter->pSelect, i);
p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
if( p->rc ) return;
}
if( pIter->zIdx==0
&& (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
){
/* For a virtual table, or a table with no primary key, the
** SELECT statement is:
**
** SELECT <cols>, rbu_control, rbu_rowid FROM ....
**
** Hence column_value(pIter->nCol+1).
*/
assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
}
if( p->rc==SQLITE_OK ){
sqlite3_step(pWriter);
p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
}
}
/*
** This function does the work for an sqlite3rbu_step() call.
**
@@ -2569,78 +2629,32 @@ static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
static int rbuStep(sqlite3rbu *p){
RbuObjIter *pIter = &p->objiter;
const char *zMask = 0;
int i;
int eType = rbuStepType(p, &zMask);
if( eType ){
assert( eType==RBU_INSERT || eType==RBU_DELETE
|| eType==RBU_REPLACE || eType==RBU_IDX_DELETE
|| eType==RBU_IDX_INSERT || eType==RBU_UPDATE
);
assert( eType!=RBU_UPDATE || pIter->zIdx==0 );
if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){
rbuBadControlError(p);
}
else if(
eType==RBU_INSERT
|| eType==RBU_DELETE
|| eType==RBU_IDX_DELETE
|| eType==RBU_IDX_INSERT
){
sqlite3_value *pVal;
sqlite3_stmt *pWriter;
assert( eType!=RBU_UPDATE );
assert( eType!=RBU_DELETE || pIter->zIdx==0 );
if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
pWriter = pIter->pDelete;
}else{
pWriter = pIter->pInsert;
}
for(i=0; i<pIter->nCol; i++){
/* If this is an INSERT into a table b-tree and the table has an
** explicit INTEGER PRIMARY KEY, check that this is not an attempt
** to write a NULL into the IPK column. That is not permitted. */
if( eType==RBU_INSERT
&& pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i]
&& sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
){
p->rc = SQLITE_MISMATCH;
p->zErrmsg = sqlite3_mprintf("datatype mismatch");
goto step_out;
}
if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
continue;
}
pVal = sqlite3_column_value(pIter->pSelect, i);
p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
if( p->rc ) goto step_out;
}
if( pIter->zIdx==0
&& (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
){
/* For a virtual table, or a table with no primary key, the
** SELECT statement is:
**
** SELECT <cols>, rbu_control, rbu_rowid FROM ....
**
** Hence column_value(pIter->nCol+1).
*/
assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
}
if( p->rc==SQLITE_OK ){
sqlite3_step(pWriter);
p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
}
}else{
else if( eType==RBU_REPLACE ){
if( pIter->zIdx==0 ) rbuStepOneOp(p, RBU_DELETE);
if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT);
}
else if( eType!=RBU_UPDATE ){
rbuStepOneOp(p, eType);
}
else{
sqlite3_value *pVal;
sqlite3_stmt *pUpdate = 0;
assert( eType==RBU_UPDATE );
rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
if( pUpdate ){
int i;
for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
char c = zMask[pIter->aiSrcOrder[i]];
pVal = sqlite3_column_value(pIter->pSelect, i);
@@ -2663,8 +2677,6 @@ static int rbuStep(sqlite3rbu *p){
}
}
}
step_out:
return p->rc;
}
+86 -84
View File
@@ -1,5 +1,5 @@
C Make\sthe\sSQLITE_DEFAULT_SYNCHRONOUS\sand\sSQLITE_DEFAULT_WAL_SYNCHRONOUS\nvalues\szero-based\sto\sagree\swith\sPRAGMA\ssynchronous.
D 2016-03-08T15:30:01.003
C Changing\spage\ssize\susing\sVACUUM\sor\sbackup\sis\snot\sallowed\swith\sa\scodec\sattached.
D 2016-03-14T20:49:24.177
F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
@@ -10,11 +10,11 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am 4b8bd7896fffb6b22a57747f1f98cba1da9108ae
F autoconf/Makefile.am 42f7eb1fb2b06ddd6c6adab3e4388cc0a237ba40
F autoconf/Makefile.msc b8ada5177e6f39c126a88295af5ad0255e08d280
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
F autoconf/configure.ac 72a5e42beb090b32bca580285dc0ab3c4670adb8
F autoconf/configure.ac d807b567f73a2b0986ccdd206b782cecb4d08fff
F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
@@ -88,7 +88,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145
F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
F ext/fts3/fts3_write.c f56345c64387ca30bf91b91511082fa83d9b5178
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
@@ -98,25 +98,25 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
F ext/fts5/fts5Int.h fa7c17e5c3ec9c8690387ff962f9dc6aee75e114
F ext/fts5/fts5Int.h 4060504b7979601d99e1385c2b5713036854979a
F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
F ext/fts5/fts5_config.c 35c5173cae4eb17e82164a7f5aeef56a48903079
F ext/fts5/fts5_expr.c 8e8e4635f655133eb39018072fc0f0942a2c4337
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
F ext/fts5/fts5_expr.c be309fb227003c931107bfcc12d5be4f2fd2bb8c
F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337
F ext/fts5/fts5_index.c 26a4a6112864feb599a6f6144d06a78bb179736a
F ext/fts5/fts5_main.c db24ac714c6c4a1b3c24a1f8c25889f2952148c1
F ext/fts5/fts5_index.c d4f0c12e4f04bbc3a06b6da052039f2ce3e45438
F ext/fts5/fts5_main.c b8501e1a6a11591c53b18ce7aea7e5386cfb0421
F ext/fts5/fts5_storage.c f8343db90d8c95a4d4b52f6676e354b4649ffd6e
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
F ext/fts5/fts5_test_mi.c b8d04816428202b2898d4ca38deb1739ac0110ae
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8
F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf
F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738
F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8
F ext/fts5/fts5parse.y 86fe6ba094a47e02fe8be2571539e6833d197764
F ext/fts5/fts5parse.y fcc5e92e570d38cab38488b2109cbf67468923b2
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
F ext/fts5/test/fts5_common.tcl b9b1fed811c0390511cef8b254826ea15d380f4d
F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841
F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084
F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b
F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f
@@ -136,7 +136,7 @@ F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e
F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb
F ext/fts5/test/fts5bigtok.test 017a9397b14e7598883a6328ead4a6539b42d59a
F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07
F ext/fts5/test/fts5config.test 8b2bc6dcc0eb06fa2b7dd65b2ce2db09e829e873
F ext/fts5/test/fts5config.test 7788b9c058074d640dfcdd81d97b6a9480000368
F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5
F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1
F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62
@@ -146,7 +146,7 @@ F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69
F ext/fts5/test/fts5dlidx.test 13871a14641017ae42f6f1055a8067bafd44cb3d
F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b
F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0
F ext/fts5/test/fts5eb.test 021aa80b7ac09b964249aa32ced9ee908703e4aa
F ext/fts5/test/fts5eb.test c516ae0c934be6fd29ec95ea8b5f11f461311535
F ext/fts5/test/fts5fault1.test e09040d3e17b8c0837101e8c79c8a874c4376fb7
F ext/fts5/test/fts5fault2.test d8c6c7f916ccbdfc10b2c69530e9dd3bc8313232
F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3
@@ -154,19 +154,20 @@ F ext/fts5/test/fts5fault4.test 532b6dacb963016cbf7003196bd87fb366540277
F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618
F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda
F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080
F ext/fts5/test/fts5fault8.test 430837fe6dd0511fd3aea52bd602ac02441bcb58
F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85
F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08
F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea
F ext/fts5/test/fts5faultB.test 92ae906284062bf081b6c854afa54dcb1aa9ef88
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9
F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d
F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b
F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367
F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3
F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75
F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc
F ext/fts5/test/fts5onepass.test 7ed9608e258132cb8d55e7c479b08676ad68810c
F ext/fts5/test/fts5optimize.test 42741e7c085ee0a1276140a752d4407d97c2c9f5
F ext/fts5/test/fts5optimize.test 9d3ac53bb9cae58cb070d795db86bcb2f9fec105
F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f
F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436
F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
@@ -214,7 +215,7 @@ F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c 194b5fc3a9a63cb6c5680d8f713800012bddca7c
F ext/misc/spellfix.c 598bbc45516227701558becdd38f4e6fe8e97cc2
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@@ -234,6 +235,7 @@ F ext/rbu/rbu8.test 3bbf2c35d71a843c463efe93946f14ad10c3ede0
F ext/rbu/rbu9.test 0806d1772c9f4981774ff028de6656e4183082af
F ext/rbu/rbuA.test c1a7b3e2d926b8f8448bb3b4ae787e314ee4b2b3
F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
F ext/rbu/rbu_common.tcl 0398545fed614f807d5f0ba55a85a51f08ba8f1a
F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d
@@ -241,7 +243,7 @@ F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
F ext/rbu/sqlite3rbu.c 371e8bf06cfb3f691adac47eb15ab1073ed92dcf
F ext/rbu/sqlite3rbu.c 5956f8bee63b5ab2b04e65c1801ea0f5920dac92
F ext/rbu/sqlite3rbu.h 0bdeb3be211aaba7d85445fa36f4701a25a3dbde
F ext/rbu/test_rbu.c 4a4cdcef4ef9379fc2a21f008805c80b27bcf573
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
@@ -292,17 +294,17 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
F src/btree.c 2712f087351f5c4ff0e71631b1e67b461611b99d
F src/btree.c 6eee126fe9d1f57118de9be2be840a4c6e691828
F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
F src/build.c 43b93fe757bfffe00f97462596418b052eefdccd
F src/build.c 213cbf84e99dd834e6ea46615633656d7ef79321
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
F src/delete.c 48802aa3ee6339f576d074336d3ae1b5f40e240f
F src/expr.c c4dad2cd6cec00387b75fef4551aff655430dcd2
F src/expr.c c329d581e5d631153456369684d7d4bcd94c907d
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 5cb42d9a59e2a590776fd3fc8ff6f61d40df3c6e
F src/func.c 552d300265aed09eea21f68ac742a440550c0062
@@ -320,7 +322,7 @@ F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memjournal.c 011da5236a7250385cc74c253f14bbee04c0d61e
F src/memjournal.c 6423a0817ffd8c7a04ef9e5fb974b6b9dd71f8b6
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
@@ -335,7 +337,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c f5bac8e74aaefc4ea520e43b4540793c3b8a9e8f
F src/os_win.c f0d7aa603eb6262143d7169a222aea07c4fca91d
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 17aa37b3b53a62a1bd98fe6f3c758bb41429ef08
F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d
F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821
F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
@@ -353,7 +355,7 @@ F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e
F src/sqlite.h.in 0235586b3fb639e85998d495c90f007657fd82af
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
F src/sqliteInt.h b017fbf491606a0fd1a5d43af40dbe965a928ead
F src/sqliteInt.h 84c673f27b77dfbd367cb3ed1de8b6f3b73102dc
F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
@@ -412,7 +414,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c 12800a93f0664f41575f96799eb881a786d565e6
F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
F src/vdbe.c 87ae3a5657fefed7875f3eb30e7ababd48013d71
F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512
@@ -428,7 +430,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
F src/where.c dff52f7f0842430f80a7017c7859124685b08453
F src/where.c 5533002ddf4fbc256f450cb629668a200b06a3ce
F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34
F src/wherecode.c 863aedf086131743763c1960637fde904eadc442
F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a
@@ -458,7 +460,7 @@ F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
F test/analyzeD.test 42af58de25a6436502e43006e9e59e2d71bcb0cf
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
F test/analyzeF.test 5d1fe1024ba2dfea3c18bede8c1ccef8aba1ab34
F test/analyzer1.test 498e2ff4b62740c2751c3a2f8b744fe26689fae9
F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
@@ -479,21 +481,21 @@ F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
F test/autovacuum.test 92c24eedbdb68e49f3fb71f26f9ce6d8988cac15
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
F test/backcompat.test 19a1f337c68419b020a7481dd272a472c4ad8ef4
F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d
F test/backup.test b79299a536a4c6d919094786595b95be56d02014
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
F test/backup4.test 2a2e4a64388090b152de753fd9e123f28f6a3bd4
F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32
F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4
F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
F test/bc_common.tcl 3eda41ef9cda7d5f6c205462c96228b301da4191
F test/bestindex1.test e228fe1e3794dbe20271481164e000d695abcd24
F test/bestindex2.test 10f2c6791f1cd0de414012528cd10a114648fd8f
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
F test/bestindex1.test d5ba89a7941a941476d8d69be39b146aaed3614c
F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
@@ -526,7 +528,7 @@ F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/cffault.test aadc1f61f8811cb600e3e069acbf8796f472a096
F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846
@@ -547,23 +549,23 @@ F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97
F test/corrupt2.test cb787825d761b0f869764d6990531382840de872
F test/corrupt3.test 4b548d0bbe2933bc81d3f54099a05fc4d28aff18
F test/corrupt4.test b99652079d542b21f4965f6248703b983e40fe80
F test/corrupt3.test e676f478fe602915d721472811f6f410b75ddc7e
F test/corrupt4.test 8d1d86b850fcc43e417450454f2044e52d55778a
F test/corrupt5.test 8ead52af76006f3286e9396cb41898018ccea107
F test/corrupt6.test 269548d19427ac554c830763b1c5ea54a0252f80
F test/corrupt7.test e4fa6d6584276679cc1d20c4e58beb9559a4eb85
F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568
F test/corrupt7.test b036f94bda4b0b23a2919bf717046ce9ecca4543
F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
F test/corruptC.test 0c46574f8d4f27ecc799b1b5c4cbf9b1817bce9a
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test be8e5088c369fc7979c662cd644efdaafc0f7f6d
F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
F test/corruptH.test 99ad81a4bda7cc078c589ef7542ecbc64e453c80
F test/corruptI.test 347babbf970e7947e3f91dccf7a1bec28a1bab04
F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91
F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51
F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
@@ -574,7 +576,7 @@ F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc
F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219
F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba
F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df
F test/crash8.test 61442a9964ab6b124fc5254e4258b45747842e6f
F test/crash8.test a63907617d8e74fb54b4bff23eca8a4435625245
F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
@@ -614,17 +616,17 @@ F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
F test/e_uri.test eed3eb41b22d051a1164110dacdc778899126e14
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
F test/e_vacuum.test 4d5b391384bb7d56bb9337d956f08035332421fc
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
F test/e_walauto.test 280714ddf14e1a47dcbc59d515cd0b026dfd5567
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
F test/e_walhook.test 4c0613a0c76e7a9d5c4c211e1b4cbcc1143914df
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test 85873fa5816c48915c82c4e74cb5c35a5b48160f
F test/eqp.test 3fe051af50921284189d1970eb653f9fcf5117d2
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
F test/exclusive.test f48243eaf40e0957215501a12f510a8644d13a02
@@ -744,17 +746,17 @@ F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb
F test/fts4check.test c3056eab9524232e4c9bdcd119912947e07bcc1c
F test/fts4content.test 05716af19a899cd70d5cd916c580043c03f30db4
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
F test/fts4growth.test 60d6bb3f78e25b34f533797dd9f2f9402310a13a
F test/fts4growth.test e5390da74619cacc389711bac9349640b32c4f9a
F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269
F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d
F test/fts4langid.test 9794addcc8faaee85ac60eceecdb52feb0c70f68
F test/fts4merge.test 146563df4a90ccb7f111a6e11ab29bbfe9e6ce2c
F test/fts4langid.test 65a7332c9bc257919e259a304aa8a38c41655b9d
F test/fts4merge.test d2b39f6b1bd4a9738a13540e2d044cba11c43d47
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
F test/fts4onepass.test 7319d61a2ed1325fc54afd0c060a0513b462303a
F test/fts4opt.test f15c84305c4b78c665fc476d8569e27ab9a0d418
F test/fts4opt.test fd6a11684b965e1999564ae763797b7fb9e34c96
F test/fts4unicode.test 27378af76394542cf490cf001d8d1505fe55f6a9
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
@@ -787,12 +789,12 @@ F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
F test/in5.test 1de657472fa9ac2924be25c2c959ac5ca1aae554
F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328
F test/in5.test acc710c12af118df5f8645eaba9479f5619eed81
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab
F test/incrblob_err.test af1f12ba60d220c9752073ff2bda2ad59e88960d
F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
@@ -819,7 +821,7 @@ F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
F test/intpkey.test 7506090fc08e028712a8bf47e5f54111947e3844
F test/io.test 3a7abcef18727cc0f2399e04b0e8903eccae50f8
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
@@ -887,7 +889,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test d2b2d6ca37890b26703a2258df8fd66f9869da02
F test/memsubsys1.test 0311bfb4edd2615e3aa56c7a9cf44574e4229077
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
@@ -902,9 +904,9 @@ F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2
F test/misc8.test 21ac9d35a5e110279ae9e1588b8914f54de1c60b
F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912
F test/mmap1.test 44a5ff1c1bcc7dcf2de50227d1f997e75a8ef1ae
F test/mmap1.test d2cfc1635171c434dcff0ece2f1c8e0a658807ce
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e
F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93
F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
F test/multiplex.test efd015ca0b5b4a57dc9535b8feb1273eebeadb60
@@ -913,8 +915,8 @@ F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4
F test/mutex1.test e0a44072d98189003deae4b091106f085d94bea8
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a
F test/nolock.test 0540dd96f39b8876e3ffdd8814fad0ea425efeee
F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3
F test/nolock.test 96e922d2d3db71c2dd6557c98e8027a28277b415
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
@@ -935,23 +937,23 @@ F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
F test/pager1.test f49df1a8b0e38b9ee3a7dd2ab4d427507b7314ce
F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
F test/pageropt.test f8d840f0fed84854dbd12b4c17fb3506eeb8224c
F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 64abe58d53cde4adcfb881e37aa5ea1b2a980e58
F test/pragma.test 507ac7ef2ea5682241ea0ef041799ca70bb5e0bf
F test/pragma.test afbf028be1c35b68f57db8eb015c4a3c59d8f28e
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
F test/pragma3.test 3f1984a04657331f838df5c519b443c2088df922
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
@@ -1058,11 +1060,11 @@ F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 1478cb3fb64ad30f291ddca87ca9dbd72ff552aa
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
F test/stat.test acc91e80517fff447ae8adcfd953cfdaa5efc0af
F test/stat.test b65bad7120c52583b8f0054d99eff80718119a77
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
@@ -1070,7 +1072,7 @@ F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
F test/sync.test 2f607e1821aa3af3c5c53b58835c05e511c95899
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
@@ -1079,11 +1081,11 @@ F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
F test/tclsqlite.test c6d9f546f79d15d0134c1e06583fb3ee0c3afad3
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl 750365ff97047ded5f2d6e28df82a998f7c66ae0
F test/tester.tcl d6dee24773e20320ab64d39bb5ce6e1a91b6029e
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1235,7 +1237,7 @@ F test/tkt3929.test cdf67acf5aa936ec4ffead81db87f8a71fe40e59
F test/tkt3935.test e15261fedb9e30a4305a311da614a5d8e693c767
F test/tkt3992.test f3e7d548ac26f763b47bc0f750da3d03c81071da
F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd
F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1
F test/tkt4018.test 18dbc6617f7a4b90e938d1bd6d26ad18daafaf08
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836
@@ -1301,18 +1303,18 @@ F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
F test/wal.test 0148c8b3421a25fdb4d9c160e84a681d0646371b
F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477
F test/wal2.test 25ae059e900dbb584e0775627e45415ba5940df1
F test/wal3.test 5dd734147f1f8f958c5261a1f2775d346d7013ce
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 88b5d9a6a3d1532497ee9f4296f010d66f07e33c
F test/wal5.test 22cb252502c5ff851925add2ca8a7e2af012e1d6
F test/wal6.test a9d6aa635b9d63607dabdc11406f5f96ca986635
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877
F test/walbak.test 018d4e5a3d45c6298d11b99f09a8ef6876527946
F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
F test/walblock.test be48f3a75eff0b4456209f26b3ce186c2015497d
F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278
@@ -1326,12 +1328,12 @@ F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
F test/walprotocol.test 059cb75484a1ecf6357a2c1b3324b8156749221e
F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
F test/walro.test 4ab7ac01b77c2f894235c699d59e3e3c7f15a160
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test f0c325563acde44f2c4ea6ba348e9e29f7121757
F test/where2.test af78c55589cbc82d793449493adba0dc3d659f23
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
@@ -1373,7 +1375,7 @@ F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/addopcodes.tcl 2b089684eb8b7d0db64cf9d8e6d2fe1b6d279e8d
F tool/build-all-msvc.bat 55be1cf8545dabd69df2ba6b3de6868da0c26f52 x
F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
@@ -1454,7 +1456,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 5791407b523abd24e832fc2361b3e9f01ee2f36a
R bba2e4d185d472ce58e719fcfcf03f67
P ea1d2cddd59192251ee5fd912b190cded4959879
R 24275616ba2669073b7ddeb77ba67682
U drh
Z 6f7df0629a8472a1465e8e2960a9953c
Z 86d93a0053c6301f416af4041023113a
+1 -1
View File
@@ -1 +1 @@
592d2104361500e5002783ba329a2609389c57b9
92be06c1a828d56652fa5269a3029f8cb029b2cd
+3 -3
View File
@@ -7572,9 +7572,9 @@ static int balance_nonroot(
** any cell). But it is important to pass the correct size to
** insertCell(), so reparse the cell now.
**
** Note that this can never happen in an SQLite data file, as all
** cells are at least 4 bytes. It only happens in b-trees used
** to evaluate "IN (SELECT ...)" and similar clauses.
** This can only happen for b-trees used to evaluate "IN (SELECT ...)"
** and WITHOUT ROWID tables with exactly one column which is the
** primary key.
*/
if( b.szCell[j]==4 ){
assert(leafCorrection==4);
+1 -1
View File
@@ -1135,7 +1135,7 @@ char sqlite3AffinityType(const char *zIn, u8 *pszEst){
char aff = SQLITE_AFF_NUMERIC;
const char *zChar = 0;
if( zIn==0 ) return aff;
assert( zIn!=0 );
while( zIn[0] ){
h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
zIn++;
+17 -18
View File
@@ -1568,23 +1568,22 @@ int sqlite3IsRowid(const char *z){
}
/*
** Return true if we are able to the IN operator optimization on a
** query of the form
**
** x IN (SELECT ...)
**
** Where the SELECT... clause is as specified by the parameter to this
** routine.
**
** The Select object passed in has already been preprocessed and no
** errors have been found.
** pX is the RHS of an IN operator. If pX is a SELECT statement
** that can be simplified to a direct table access, then return
** a pointer to the SELECT statement. If pX is not a SELECT statement,
** or if the SELECT statement needs to be manifested into a transient
** table, then return NULL.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static int isCandidateForInOpt(Select *p){
static Select *isCandidateForInOpt(Expr *pX){
Select *p;
SrcList *pSrc;
ExprList *pEList;
Expr *pRes;
Table *pTab;
if( p==0 ) return 0; /* right-hand side of IN is SELECT */
if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */
if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
p = pX->x.pSelect;
if( p->pPrior ) return 0; /* Not a compound SELECT */
if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
@@ -1600,13 +1599,15 @@ static int isCandidateForInOpt(Select *p){
if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
pTab = pSrc->a[0].pTab;
if( NEVER(pTab==0) ) return 0;
assert( pTab!=0 );
assert( pTab->pSelect==0 ); /* FROM clause is not a view */
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
pEList = p->pEList;
if( pEList->nExpr!=1 ) return 0; /* One column in the result set */
if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
return 1;
pRes = pEList->a[0].pExpr;
if( pRes->op!=TK_COLUMN ) return 0; /* Result is a column */
assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */
return p;
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -1738,15 +1739,13 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
** satisfy the query. This is preferable to generating a new
** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( pParse->nErr==0 && isCandidateForInOpt(p) ){
if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
Expr *pExpr; /* Expression <column> */
i16 iCol; /* Index of column <column> */
i16 iDb; /* Database idx for pTab */
assert( p ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
+76 -84
View File
@@ -69,7 +69,6 @@ struct MemJournal {
int flags; /* xOpen flags */
sqlite3_vfs *pVfs; /* The "real" underlying VFS */
const char *zJournal; /* Name of the journal file */
sqlite3_file *pReal; /* The "real" underlying file descriptor */
};
/*
@@ -83,40 +82,41 @@ static int memjrnlRead(
sqlite_int64 iOfst /* Begin reading at this offset */
){
MemJournal *p = (MemJournal *)pJfd;
if( p->pReal ){
return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
}else if( (iAmt+iOfst)>p->endpoint.iOffset ){
u8 *zOut = zBuf;
int nRead = iAmt;
int iChunkOffset;
FileChunk *pChunk;
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
if( (iAmt+iOfst)>p->endpoint.iOffset ){
return SQLITE_IOERR_SHORT_READ;
}else{
u8 *zOut = zBuf;
int nRead = iAmt;
int iChunkOffset;
FileChunk *pChunk;
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
sqlite3_int64 iOff = 0;
for(pChunk=p->pFirst;
ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
pChunk=pChunk->pNext
){
iOff += p->nChunkSize;
}
}else{
pChunk = p->readpoint.pChunk;
}
iChunkOffset = (int)(iOfst%p->nChunkSize);
do {
int iSpace = p->nChunkSize - iChunkOffset;
int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset));
memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy);
zOut += nCopy;
nRead -= iSpace;
iChunkOffset = 0;
} while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
p->readpoint.iOffset = iOfst+iAmt;
p->readpoint.pChunk = pChunk;
}
#endif
assert( (iAmt+iOfst)<=p->endpoint.iOffset );
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
sqlite3_int64 iOff = 0;
for(pChunk=p->pFirst;
ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
pChunk=pChunk->pNext
){
iOff += p->nChunkSize;
}
}else{
pChunk = p->readpoint.pChunk;
}
iChunkOffset = (int)(iOfst%p->nChunkSize);
do {
int iSpace = p->nChunkSize - iChunkOffset;
int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset));
memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy);
zOut += nCopy;
nRead -= iSpace;
iChunkOffset = 0;
} while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
p->readpoint.iOffset = iOfst+iAmt;
p->readpoint.pChunk = pChunk;
return SQLITE_OK;
}
@@ -138,36 +138,36 @@ static void memjrnlFreeChunks(MemJournal *p){
** Flush the contents of memory to a real file on disk.
*/
static int memjrnlCreateFile(MemJournal *p){
int rc = SQLITE_OK;
if( !p->pReal ){
sqlite3_file *pReal = (sqlite3_file *)&p[1];
rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
if( rc==SQLITE_OK ){
int nChunk = p->nChunkSize;
i64 iOff = 0;
FileChunk *pIter;
p->pReal = pReal;
for(pIter=p->pFirst; pIter && rc==SQLITE_OK; pIter=pIter->pNext){
int nWrite = nChunk;
if( pIter==p->endpoint.pChunk ){
nWrite = p->endpoint.iOffset % p->nChunkSize;
if( nWrite==0 ) nWrite = p->nChunkSize;
}
rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nWrite, iOff);
iOff += nWrite;
}
if( rc!=SQLITE_OK ){
/* If an error occurred while writing to the file, close it before
** returning. This way, SQLite uses the in-memory journal data to
** roll back changes made to the internal page-cache before this
** function was called. */
sqlite3OsClose(pReal);
p->pReal = 0;
}else{
/* No error has occurred. Free the in-memory buffers. */
memjrnlFreeChunks(p);
int rc;
sqlite3_file *pReal = (sqlite3_file*)p;
MemJournal copy = *p;
memset(p, 0, sizeof(MemJournal));
rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0);
if( rc==SQLITE_OK ){
int nChunk = copy.nChunkSize;
i64 iOff = 0;
FileChunk *pIter;
for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){
if( iOff + nChunk > copy.endpoint.iOffset ){
nChunk = copy.endpoint.iOffset - iOff;
}
rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff);
if( rc ) break;
iOff += nChunk;
}
if( rc==SQLITE_OK ){
/* No error has occurred. Free the in-memory buffers. */
memjrnlFreeChunks(&copy);
}
}
if( rc!=SQLITE_OK ){
/* If an error occurred while creating or writing to the file, restore
** the original before returning. This way, SQLite uses the in-memory
** journal data to roll back changes made to the internal page-cache
** before this function was called. */
sqlite3OsClose(pReal);
*p = copy;
}
return rc;
}
@@ -186,16 +186,12 @@ static int memjrnlWrite(
int nWrite = iAmt;
u8 *zWrite = (u8 *)zBuf;
/* If the file has already been created on disk. */
if( p->pReal ){
return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
}
/* If the file should be created now. */
else if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
/* If the file should be created now, create it and write the new data
** into the file on disk. */
if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
int rc = memjrnlCreateFile(p);
if( rc==SQLITE_OK ){
rc = memjrnlWrite(pJfd, zBuf, iAmt, iOfst);
rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst);
}
return rc;
}
@@ -208,10 +204,15 @@ static int memjrnlWrite(
** atomic-write optimization. In this case the first 28 bytes of the
** journal file may be written as part of committing the transaction. */
assert( iOfst==p->endpoint.iOffset || iOfst==0 );
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
if( iOfst==0 && p->pFirst ){
assert( p->nChunkSize>iAmt );
memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
}else{
}else
#else
assert( iOfst>0 || p->pFirst==0 );
#endif
{
while( nWrite>0 ){
FileChunk *pChunk = p->endpoint.pChunk;
int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
@@ -255,9 +256,7 @@ static int memjrnlWrite(
*/
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
MemJournal *p = (MemJournal *)pJfd;
if( p->pReal ){
return sqlite3OsTruncate(p->pReal, size);
}else if( size==0 ){
if( ALWAYS(size==0) ){
memjrnlFreeChunks(p);
p->nSize = 0;
p->endpoint.pChunk = 0;
@@ -274,7 +273,6 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
static int memjrnlClose(sqlite3_file *pJfd){
MemJournal *p = (MemJournal *)pJfd;
memjrnlFreeChunks(p);
if( p->pReal ) sqlite3OsClose(p->pReal);
return SQLITE_OK;
}
@@ -285,10 +283,7 @@ static int memjrnlClose(sqlite3_file *pJfd){
** syncing an in-memory journal is a no-op.
*/
static int memjrnlSync(sqlite3_file *pJfd, int flags){
MemJournal *p = (MemJournal *)pJfd;
if( p->pReal ){
return sqlite3OsSync(p->pReal, flags);
}
UNUSED_PARAMETER2(pJfd, flags);
return SQLITE_OK;
}
@@ -297,9 +292,6 @@ static int memjrnlSync(sqlite3_file *pJfd, int flags){
*/
static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
MemJournal *p = (MemJournal *)pJfd;
if( p->pReal ){
return sqlite3OsFileSize(p->pReal, pSize);
}
*pSize = (sqlite_int64) p->endpoint.iOffset;
return SQLITE_OK;
}
@@ -354,7 +346,7 @@ int sqlite3JournalOpen(
** it using the sqlite3OsOpen() function of the underlying VFS. In this
** case none of the code in this module is executed as a result of calls
** made on the journal file-handle. */
memset(p, 0, sizeof(MemJournal) + (pVfs ? pVfs->szOsFile : 0));
memset(p, 0, sizeof(MemJournal));
if( nSpill==0 ){
return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
}
@@ -403,7 +395,7 @@ int sqlite3JournalCreate(sqlite3_file *p){
** or false otherwise.
*/
int sqlite3JournalIsInMemory(sqlite3_file *p){
return p->pMethods==&MemJournalMethods && ((MemJournal*)p)->pReal==0;
return p->pMethods==&MemJournalMethods;
}
/*
@@ -411,5 +403,5 @@ int sqlite3JournalIsInMemory(sqlite3_file *p){
** pVfs to create the underlying on-disk files.
*/
int sqlite3JournalSize(sqlite3_vfs *pVfs){
return pVfs->szOsFile + sizeof(MemJournal);
return MAX(pVfs->szOsFile, sizeof(MemJournal));
}
+1 -17
View File
@@ -428,19 +428,6 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
*/
#define MAX_SECTOR_SIZE 0x10000
/*
** If the option SQLITE_EXTRA_DURABLE option is set at compile-time, then
** SQLite will do extra fsync() operations when synchronous==FULL to help
** ensure that transactions are durable across a power failure. Most
** applications are happy as long as transactions are consistent across
** a power failure, and are perfectly willing to lose the last transaction
** in exchange for the extra performance of avoiding directory syncs.
** And so the default SQLITE_EXTRA_DURABLE setting is off.
*/
#ifndef SQLITE_EXTRA_DURABLE
# define SQLITE_EXTRA_DURABLE 0
#endif
/*
** An instance of the following structure is allocated for each active
@@ -4823,11 +4810,7 @@ act_like_temp_file:
assert( pPager->ckptSyncFlags==0 );
}else{
pPager->fullSync = 1;
#if SQLITE_EXTRA_DURABLE
pPager->extraSync = 1;
#else
pPager->extraSync = 0;
#endif
pPager->syncFlags = SQLITE_SYNC_NORMAL;
pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
@@ -7184,6 +7167,7 @@ int sqlite3PagerWalCallback(Pager *pPager){
*/
int sqlite3PagerWalSupported(Pager *pPager){
const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
if( pPager->noLock ) return 0;
return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
}
+15
View File
@@ -451,6 +451,13 @@
# undef SQLITE_NEED_ERR_NAME
#endif
/*
** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN
*/
#ifdef SQLITE_OMIT_EXPLAIN
# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
#endif
/*
** Return true (non-zero) if the input is an integer that is too large
** to fit in 32-bits. This macro is used inside of various testcase()
@@ -1005,6 +1012,14 @@ typedef struct With With;
#include "os.h"
#include "mutex.h"
/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default
** synchronous setting to EXTRA. It is no longer supported.
*/
#ifdef SQLITE_EXTRA_DURABLE
# warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE
# define SQLITE_DEFAULT_SYNCHRONOUS 3
#endif
/*
** Default synchronous levels.
**
+9 -4
View File
@@ -1424,9 +1424,14 @@ u64 sqlite3LogEstToInt(LogEst x){
x /= 10;
if( n>=5 ) n -= 2;
else if( n>=1 ) n -= 1;
if( x>=3 ){
return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3);
}
return (n+8)>>(3-x);
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
if( x>60 ) return (u64)LARGEST_INT64;
#else
/* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input
** possible to this routine is 310, resulting in a maximum x of 31 */
assert( x<=60 );
#endif
return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
}
#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
+21 -13
View File
@@ -1979,6 +1979,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
WhereLoop **ppPrev, *p;
WhereInfo *pWInfo = pBuilder->pWInfo;
sqlite3 *db = pWInfo->pParse->db;
int rc;
/* If pBuilder->pOrSet is defined, then only keep track of the costs
** and prereqs.
@@ -2061,14 +2062,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
whereLoopDelete(db, pToDel);
}
}
whereLoopXfer(db, p, pTemplate);
rc = whereLoopXfer(db, p, pTemplate);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
Index *pIndex = p->u.btree.pIndex;
if( pIndex && pIndex->tnum==0 ){
p->u.btree.pIndex = 0;
}
}
return SQLITE_OK;
return rc;
}
/*
@@ -2810,10 +2811,9 @@ static int whereLoopAddVirtualOne(
/* Initialize the output fields of the sqlite3_index_info structure */
memset(pUsage, 0, sizeof(pUsage[0])*nConstraint);
if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
assert( pIdxInfo->needToFreeIdxStr==0 );
pIdxInfo->idxStr = 0;
pIdxInfo->idxNum = 0;
pIdxInfo->needToFreeIdxStr = 0;
pIdxInfo->orderByConsumed = 0;
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
pIdxInfo->estimatedRows = 25;
@@ -2887,13 +2887,16 @@ static int whereLoopAddVirtualOne(
}else{
pNew->wsFlags &= ~WHERE_ONEROW;
}
whereLoopInsert(pBuilder, pNew);
rc = whereLoopInsert(pBuilder, pNew);
if( pNew->u.vtab.needFree ){
sqlite3_free(pNew->u.vtab.idxStr);
pNew->u.vtab.needFree = 0;
}
WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n",
*pbIn, (sqlite3_uint64)mPrereq,
(sqlite3_uint64)(pNew->prereq & ~mPrereq)));
return SQLITE_OK;
return rc;
}
@@ -2958,15 +2961,15 @@ static int whereLoopAddVirtual(
}
/* First call xBestIndex() with all constraints usable. */
WHERETRACE(0x40, (" VirtualOne: all usable\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, &bIn);
mBest = pNew->prereq & ~mPrereq;
/* If the call to xBestIndex() with all terms enabled produced a plan
** that does not require any source tables, there is no point in making
** any further calls - if the xBestIndex() method is sane they will all
** return the same plan anyway.
*/
if( mBest ){
** that does not require any source tables (IOW: a plan with mBest==0),
** then there is no point in making any further calls to xBestIndex()
** since they will all return the same result (if the xBestIndex()
** implementation is sane). */
if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
int seenZero = 0; /* True if a plan with no prereqs seen */
int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */
Bitmask mPrev = 0;
@@ -2974,7 +2977,8 @@ static int whereLoopAddVirtual(
/* If the plan produced by the earlier call uses an IN(...) term, call
** xBestIndex again, this time with IN(...) terms disabled. */
if( rc==SQLITE_OK && bIn ){
if( bIn ){
WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, WO_IN, p, &bIn);
assert( bIn==0 );
mBestNoIn = pNew->prereq & ~mPrereq;
@@ -2999,6 +3003,8 @@ static int whereLoopAddVirtual(
mPrev = mNext;
if( mNext==ALLBITS ) break;
if( mNext==mBest || mNext==mBestNoIn ) continue;
WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
(sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mNext|mPrereq, 0, p, &bIn);
if( pNew->prereq==mPrereq ){
seenZero = 1;
@@ -3010,6 +3016,7 @@ static int whereLoopAddVirtual(
** that requires no source tables at all (i.e. one guaranteed to be
** usable), make a call here with all source tables disabled */
if( rc==SQLITE_OK && seenZero==0 ){
WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, 0, p, &bIn);
if( bIn==0 ) seenZeroNoIN = 1;
}
@@ -3018,6 +3025,7 @@ static int whereLoopAddVirtual(
** that requires no source tables at all and does not use an IN(...)
** operator, make a final call to obtain one here. */
if( rc==SQLITE_OK && seenZeroNoIN==0 ){
WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, WO_IN, p, &bIn);
}
}
+6 -3
View File
@@ -25,9 +25,12 @@ if {$tcl_platform(platform)=="windows"} {
set PROG "./sqlite3_analyzer"
}
if {![file exe $PROG]} {
puts "analyzer1 cannot run because $PROG is not available"
finish_test
return
set PROG [file normalize [file join $::cmdlinearg(TESTFIXTURE_HOME) $PROG]]
if {![file exe $PROG]} {
puts "analyzer1 cannot run because $PROG is not available"
finish_test
return
}
}
db close
forcedelete test.db test.db-journal test.db-wal
+14 -3
View File
@@ -269,7 +269,7 @@ do_test autovacuum-2.4.3 {
} {3 4 5 6 7 8 9 10}
# Right now there are 5 free pages in the database. Consume and then free
# a 520 pages. Then create 520 tables. This ensures that at least some of the
# all 520 pages. Then create 520 tables. This ensures that at least some of the
# desired root-pages reside on the second free-list trunk page, and that the
# trunk itself is required at some point.
do_test autovacuum-2.4.4 {
@@ -280,9 +280,20 @@ do_test autovacuum-2.4.4 {
} {}
set root_page_list [list]
set pending_byte_page [expr ($::sqlite_pending_byte / 1024) + 1]
# unusable_pages
# These are either the pending_byte page or the pointer map pages
#
unset -nocomplain unusable_page
if {[sqlite3 -has-codec]} {
array set unusable_page {205 1 408 1}
} else {
array set unusable_page {207 1 412 1}
}
set unusable_page($pending_byte_page) 1
for {set i 3} {$i<=532} {incr i} {
# 207 and 412 are pointer-map pages.
if { $i!=207 && $i!=412 && $i != $pending_byte_page} {
if {![info exists unusable_page($i)]} {
lappend root_page_list $i
}
}
+10 -3
View File
@@ -63,7 +63,7 @@ proc do_backcompat_test {rv bin1 bin2 script} {
set v [split [db version] .]
if {[llength $v]==3} {lappend v 0}
set ::sqlite_libversion [format \
"%d%.2d%.2d%2d" [lindex $v 0] [lindex $v 1] [lindex $v 2] [lindex $v 3]
"%d%.2d%.2d%.2d" [lindex $v 0] [lindex $v 1] [lindex $v 2] [lindex $v 3]
]
}
}
@@ -85,7 +85,8 @@ proc do_allbackcompat_test {script} {
set nErr [set_test_counter errors]
foreach dir {0 1} {
set bintag [string map {testfixture {}} $bin]
set bintag $bin
regsub {.*testfixture\.} $bintag {} bintag
set bintag [string map {\.exe {}} $bintag]
if {$bintag == ""} {set bintag self}
set ::bcname ".$bintag.$dir."
@@ -420,6 +421,12 @@ ifcapable fts3 {
if {[code1 { set ::sqlite_libversion }] >=3071200
&& [code2 { set ::sqlite_libversion }] >=3071200
} {
if {[code1 { set ::sqlite_libversion }]<3120000} {
set res {0 {0 1} 1 0}
} else {
set res {1 0}
}
do_test backcompat-3.9 {
sql1 { INSERT INTO t2(t2) VALUES('merge=100,4'); }
sql2 { INSERT INTO t2(t2) VALUES('merge=100,4'); }
@@ -428,7 +435,7 @@ ifcapable fts3 {
sql2 {
SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level;
}
} {0 {0 1} 1 0}
} $res
do_test backcompat-3.10 {
sql1 { INSERT INTO t2(t2) VALUES('integrity-check') }
+5
View File
@@ -23,6 +23,11 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix backup4
# The codec logic does not work for zero-length database files. A database
# file must contain at least one page in order to be recognized as an
# encrypted database.
do_not_use_codec
#-------------------------------------------------------------------------
# At one point this test was failing because [db] was using an out of
# date schema in test case 1.2.
+3 -2
View File
@@ -7,7 +7,7 @@ proc bc_find_binaries {zCaption} {
# against.
#
set binaries [list]
set self [file tail [info nameofexec]]
set self [info nameofexec]
set pattern "$self?*"
if {$::tcl_platform(platform)=="windows"} {
set pattern [string map {\.exe {}} $pattern]
@@ -52,7 +52,8 @@ proc do_bc_test {bin script} {
code1 { sqlite3 db test.db }
code2 { sqlite3 db test.db }
set bintag [string map {testfixture {}} $bin]
set bintag $bin
regsub {.*testfixture\.} $bintag {} bintag
set bintag [string map {\.exe {}} $bintag]
if {$bintag == ""} {set bintag self}
set saved_prefix $::testprefix
+5 -2
View File
@@ -15,6 +15,11 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix bestindex1
ifcapable !vtab {
finish_test
return
}
register_tcl_module db
proc vtab_command {method args} {
@@ -161,5 +166,3 @@ foreach {tn mode} {
}
finish_test
+4 -1
View File
@@ -13,6 +13,10 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix bestindex2
ifcapable !vtab {
finish_test
return
}
#-------------------------------------------------------------------------
# Virtual table callback for table named $tbl, with the columns specified
@@ -135,4 +139,3 @@ do_eqp_test 1.7.2 {
}
finish_test
+4
View File
@@ -17,6 +17,10 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix close
# This module bypasses the "-key" logic in tester.tcl, so it cannot run
# with the codec enabled.
do_not_use_codec
do_execsql_test 1.0 {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('one');
+3 -4
View File
@@ -18,10 +18,9 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
# These tests deal with corrupt database files
#
+3 -4
View File
@@ -18,10 +18,9 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
# These tests deal with corrupt database files
#
+3 -4
View File
@@ -19,10 +19,9 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
# These tests deal with corrupt database files
#
+3 -4
View File
@@ -19,10 +19,9 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
# These tests deal with corrupt database files
#
+3 -4
View File
@@ -18,10 +18,9 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
# These tests deal with corrupt database files
#
+3 -4
View File
@@ -14,10 +14,9 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptG
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
# These tests deal with corrupt database files
#
+4 -4
View File
@@ -14,10 +14,10 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptH
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
database_may_be_corrupt
# The corruption migrations tested by the code in this file are not detected
+4 -4
View File
@@ -19,10 +19,10 @@ if {[permutation]=="mmap"} {
return
}
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
database_may_be_corrupt
# Initialize the database.
+4 -4
View File
@@ -22,10 +22,10 @@ if {[permutation]=="mmap"} {
return
}
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
database_may_be_corrupt
# Initialize the database.
+1
View File
@@ -25,6 +25,7 @@ ifcapable !crashtest {
finish_test
return
}
do_not_use_codec
do_test crash8-1.1 {
execsql {
+1 -1
View File
@@ -13,7 +13,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix e_uri
do_not_use_codec
db close
proc parse_uri {uri} {
+30 -28
View File
@@ -159,35 +159,37 @@ do_test e_vacuum-1.3.1.2 {
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
} {1024 1}
# EVIDENCE-OF: R-08570-19916 However, when not in write-ahead log mode,
# the page_size and/or auto_vacuum properties of an existing database
# may be changed by using the page_size and/or pragma auto_vacuum
# pragmas and then immediately VACUUMing the database.
#
do_test e_vacuum-1.3.2.1 {
execsql { PRAGMA journal_mode = delete }
execsql { PRAGMA page_size = 2048 }
execsql { PRAGMA auto_vacuum = NONE }
execsql VACUUM
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
} {2048 0}
# EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
# auto_vacuum support property can be changed using VACUUM.
#
ifcapable wal {
do_test e_vacuum-1.3.3.1 {
execsql { PRAGMA journal_mode = wal }
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
} {2048 0}
do_test e_vacuum-1.3.3.2 {
execsql { PRAGMA page_size = 1024 }
execsql { PRAGMA auto_vacuum = FULL }
execsql VACUUM
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
} {2048 1}
if {![nonzero_reserved_bytes]} {
# EVIDENCE-OF: R-08570-19916 However, when not in write-ahead log mode,
# the page_size and/or auto_vacuum properties of an existing database
# may be changed by using the page_size and/or pragma auto_vacuum
# pragmas and then immediately VACUUMing the database.
#
do_test e_vacuum-1.3.2.1 {
execsql { PRAGMA journal_mode = delete }
execsql { PRAGMA page_size = 2048 }
execsql { PRAGMA auto_vacuum = NONE }
execsql VACUUM
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
} {2048 0}
# EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
# auto_vacuum support property can be changed using VACUUM.
#
ifcapable wal {
do_test e_vacuum-1.3.3.1 {
execsql { PRAGMA journal_mode = wal }
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
} {2048 0}
do_test e_vacuum-1.3.3.2 {
execsql { PRAGMA page_size = 1024 }
execsql { PRAGMA auto_vacuum = FULL }
execsql VACUUM
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
} {2048 1}
}
}
# EVIDENCE-OF: R-38001-03952 VACUUM only works on the main database. It
# is not possible to VACUUM an attached database file.
forcedelete test.db2
+5
View File
@@ -24,6 +24,11 @@ if {$tcl_platform(os) == "OpenBSD"} {
return
}
# This module uses hard-coded offsets which do not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
proc read_nbackfill {} {
seek $::shmfd 96
binary scan [read $::shmfd 4] n nBackfill
+34 -32
View File
@@ -516,45 +516,47 @@ det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" {
}
#-------------------------------------------------------------------------
# The following tests - eqp-6.* - test that the example C code on
# documentation page eqp.html works. The C code is duplicated in test1.c
# and wrapped in Tcl command [print_explain_query_plan]
#
set boilerplate {
proc explain_query_plan {db sql} {
set stmt [sqlite3_prepare_v2 db $sql -1 DUMMY]
print_explain_query_plan $stmt
sqlite3_finalize $stmt
if {![nonzero_reserved_bytes]} {
#-------------------------------------------------------------------------
# The following tests - eqp-6.* - test that the example C code on
# documentation page eqp.html works. The C code is duplicated in test1.c
# and wrapped in Tcl command [print_explain_query_plan]
#
set boilerplate {
proc explain_query_plan {db sql} {
set stmt [sqlite3_prepare_v2 db $sql -1 DUMMY]
print_explain_query_plan $stmt
sqlite3_finalize $stmt
}
sqlite3 db test.db
explain_query_plan db {%SQL%}
db close
exit
}
sqlite3 db test.db
explain_query_plan db {%SQL%}
db close
exit
}
# Do a "Print Explain Query Plan" test.
proc do_peqp_test {tn sql res} {
set fd [open script.tcl w]
puts $fd [string map [list %SQL% $sql] $::boilerplate]
close $fd
uplevel do_test $tn [list {
set fd [open "|[info nameofexec] script.tcl"]
set data [read $fd]
# Do a "Print Explain Query Plan" test.
proc do_peqp_test {tn sql res} {
set fd [open script.tcl w]
puts $fd [string map [list %SQL% $sql] $::boilerplate]
close $fd
set data
}] [list $res]
}
do_peqp_test 6.1 {
SELECT a, b FROM t1 EXCEPT SELECT d, 99 FROM t2 ORDER BY 1
} [string trimleft {
uplevel do_test $tn [list {
set fd [open "|[info nameofexec] script.tcl"]
set data [read $fd]
close $fd
set data
}] [list $res]
}
do_peqp_test 6.1 {
SELECT a, b FROM t1 EXCEPT SELECT d, 99 FROM t2 ORDER BY 1
} [string trimleft {
1 0 0 SCAN TABLE t1 USING COVERING INDEX i2
2 0 0 SCAN TABLE t2
2 0 0 USE TEMP B-TREE FOR ORDER BY
0 0 0 COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
}]
}
#-------------------------------------------------------------------------
# The following tests - eqp-7.* - test that queries that use the OP_Count
+22 -18
View File
@@ -59,11 +59,11 @@ do_test 1.4 {
INSERT INTO x1(x1) VALUES('merge=4,4');
SELECT level, end_block, length(root) FROM x1_segdir;
}
} {0 {0 110} 110 0 {0 132} 132 0 {0 129} 129 1 {128 658} 2}
} {1 {224 921} 2}
do_execsql_test 1.5 {
SELECT length(block) FROM x1_segments;
} {658 {}}
} {921 {}}
do_test 1.6 {
foreach L {
@@ -71,27 +71,33 @@ do_test 1.6 {
{That perched above Dead Man's Creek, beside the mountain road.}
{He turned the cycle down the hill and mounted for the fray,}
{But 'ere he'd gone a dozen yards it bolted clean away.}
{It left the track, and through the trees, just like a silver steak,}
{It whistled down the awful slope towards the Dead Man's Creek.}
{It shaved a stump by half an inch, it dodged a big white-box:}
{The very wallaroos in fright went scrambling up the rocks,}
{The wombats hiding in their caves dug deeper underground,}
{As Mulga Bill, as white as chalk, sat tight to every bound.}
{It struck a stone and gave a spring that cleared a fallen tree,}
{It raced beside a precipice as close as close could be;}
{And then as Mulga Bill let out one last despairing shriek}
{It made a leap of twenty feet into the Dead Man's Creek.}
{It shaved a stump by half an inch, it dodged a big white-box:}
{The very wallaroos in fright went scrambling up the rocks,}
{The wombats hiding in their caves dug deeper underground,}
} {
execsql { INSERT INTO x1 VALUES($L) }
}
execsql {
SELECT level, end_block, length(root) FROM x1_segdir;
}
} {1 {128 658} 2 1 {130 1377} 6 0 {0 117} 117}
} {1 {224 921} 2 1 {226 1230} 7 0 {0 98} 98}
do_execsql_test 1.7 {
SELECT sum(length(block)) FROM x1_segments WHERE blockid IN (129, 130);
} {1377}
SELECT sum(length(block)) FROM x1_segments WHERE blockid IN (224,225,226)
} {1230}
#-------------------------------------------------------------------------
#
@@ -131,24 +137,24 @@ do_execsql_test 2.5 {
SELECT end_block FROM x2_segdir WHERE level=3;
INSERT INTO x2(x2) VALUES('merge=4,4');
SELECT end_block FROM x2_segdir WHERE level=3;
} {{3828 -3430} {3828 -10191} {3828 -14109}}
} {{5588 -3950} {5588 -11766} {5588 -15541}}
do_execsql_test 2.6 {
SELECT sum(length(block)) FROM x2_segdir, x2_segments WHERE
blockid BETWEEN start_block AND leaves_end_block
AND level=3
} {14109}
} {15541}
do_execsql_test 2.7 {
INSERT INTO x2(x2) VALUES('merge=1000,4');
SELECT end_block FROM x2_segdir WHERE level=3;
} {{3828 86120}}
} {{5588 127563}}
do_execsql_test 2.8 {
SELECT sum(length(block)) FROM x2_segdir, x2_segments WHERE
blockid BETWEEN start_block AND leaves_end_block
AND level=3
} {86120}
} {127563}
#--------------------------------------------------------------------------
# Test that delete markers are removed from FTS segments when possible.
@@ -391,7 +397,7 @@ do_execsql_test 7.2 {
} {
0 0 {118 117483} 0 1 {238 118006} 0 2 {358 118006}
0 3 {478 118006} 0 4 {598 118006} 0 5 {718 118006}
1 0 {16014 -51226}
1 0 {23694 -69477}
}
do_execsql_test 7.3 {
@@ -400,7 +406,7 @@ do_execsql_test 7.3 {
} {
0 0 {118 117483} 0 1 {238 118006} 0 2 {358 118006}
0 3 {478 118006} 0 4 {598 118006} 0 5 {718 118006}
1 0 16014
1 0 23694
}
do_execsql_test 7.4 {
@@ -409,28 +415,26 @@ do_execsql_test 7.4 {
} {
0 0 {118 117483} 0 1 {238 118006} 0 2 {358 118006}
0 3 {478 118006} 0 4 {598 118006} 0 5 {718 118006}
1 0 16014
1 0 23694
}
do_execsql_test 7.5 {
INSERT INTO x6(x6) VALUES('merge=2500,4');
SELECT level, idx, end_block FROM x6_segdir;
SELECT level, idx, start_block, leaves_end_block, end_block FROM x6_segdir;
} {
0 0 {598 118006} 0 1 {718 118006} 1 0 16014
1 0 719 1171 23694
}
do_execsql_test 7.6 {
INSERT INTO x6(x6) VALUES('merge=2500,2');
SELECT level, idx, start_block, leaves_end_block, end_block FROM x6_segdir;
} {
2 0 23695 24147 {41262 633507}
1 0 719 1171 23694
}
do_execsql_test 7.7 {
SELECT sum(length(block)) FROM x6_segments
WHERE blockid BETWEEN 23695 AND 24147
} {633507}
} {635247}
finish_test
+1 -1
View File
@@ -481,6 +481,6 @@ foreach lid [list 4 [expr 1<<30]] {
do_execsql_test 5.4.$lid.5 {
SELECT count(*) FROM t6_segdir;
SELECT count(*) FROM t6_segments;
} {4 4}
} {1 2}
}
finish_test
+8 -17
View File
@@ -55,8 +55,6 @@ foreach mod {fts3 fts4} {
do_execsql_test 1.3 {
SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level
} {
0 {0 1 2 3}
1 {0 1 2 3 4 5 6}
2 {0 1 2 3}
}
@@ -71,7 +69,6 @@ foreach mod {fts3 fts4} {
do_execsql_test 1.5 {
SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level
} {
2 {0 1}
3 0
}
@@ -118,11 +115,7 @@ foreach mod {fts3 fts4} {
INSERT INTO t2(t2) VALUES('merge=1000000,2');
SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level
} {
0 0
2 0
3 0
4 0
6 0
}
#-------------------------------------------------------------------------
@@ -202,28 +195,27 @@ foreach mod {fts3 fts4} {
INSERT INTO t1(t1) VALUES('merge=1,5');
SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
} {
0 {0 1 2}
1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14}
2 {0 1 2 3}
}
do_execsql_test 5.4 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'0105'}
do_execsql_test 5.4 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'010F'}
do_test 5.5 {
foreach docid [execsql {SELECT docid FROM t1}] {
execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid}
}
} {}
do_execsql_test 5.6 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'0105'}
do_execsql_test 5.6 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'010F'}
do_execsql_test 5.7 {
SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
SELECT quote(value) from t1_stat WHERE rowid=1;
} {
0 {0 1 2 3 4 5 6 7 8 9 10}
0 {0 1 2 3 4 5 6 7}
1 {0 1 2 3 4 5 6 7 8 9 10 11 12}
2 {0 1 2 3 4 5 6 7}
X'0105'
2 {0 1 2 3 4 5 6 7}
X'010F'
}
do_execsql_test 5.8 {
@@ -232,9 +224,8 @@ foreach mod {fts3 fts4} {
SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
SELECT quote(value) from t1_stat WHERE rowid=1;
} {
0 {0 1 2 3 4}
1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13}
2 {0 1 2 3 4 5 6 7 8} X'0106'
2 {0 1 2 3 4 5 6 7 8} X'010E'
}
do_test 5.8.1 { fts3_integrity_check t1 } ok
@@ -252,7 +243,7 @@ foreach mod {fts3 fts4} {
SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
SELECT quote(value) from t1_stat WHERE rowid=1;
} {
0 0 1 {0 1} 2 0 3 0 X'0106'
0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 0 2 0 3 0 X'010E'
}
do_execsql_test 5.11 {
@@ -260,7 +251,7 @@ foreach mod {fts3 fts4} {
SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
SELECT quote(value) from t1_stat WHERE rowid=1;
} {
0 0 1 {0 1} 2 0 3 0 X''
1 {0 1} 2 0 3 0 X'010E'
}
#-------------------------------------------------------------------------
+3 -3
View File
@@ -62,7 +62,7 @@ do_all_bc_test {
do_test 1.7 { sql2 {
SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1
} } [list 0 1 2 18 3 5]
} } {2 15 3 5}
# Using the old connection, insert many rows.
do_test 1.8 {
@@ -73,7 +73,7 @@ do_all_bc_test {
do_test 1.9 { sql2 {
SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1
} } [list 0 13 1 13 2 5 3 6]
} } [list 0 12 1 13 2 4 3 6]
# Run a big incr-merge operation on the db.
do_test 1.10 { sql1 { INSERT INTO t2(t2) VALUES('merge=2000,2') } } {}
@@ -97,7 +97,7 @@ do_all_bc_test {
do_test 1.15 { sql2 {
SELECT level, count(*) FROM t2_segdir GROUP BY level ORDER BY 1
} } {6 1}
} } {4 1}
}
}
+46 -2
View File
@@ -92,7 +92,7 @@ do_execsql_test 1.5 {
do_test 1.6 {
while 1 {
set tc1 [db total_changes]
execsql { INSERT INTO t2(t2) VALUES('merge=5,0') }
execsql { INSERT INTO t2(t2) VALUES('merge=5,2') }
set tc2 [db total_changes]
if {($tc2 - $tc1) < 2} break
}
@@ -153,7 +153,7 @@ do_execsql_test 2.5 {
do_test 2.6 {
while 1 {
set tc1 [db total_changes]
execsql { INSERT INTO t2(t2) VALUES('merge=5,0') }
execsql { INSERT INTO t2(t2) VALUES('merge=5,2') }
set tc2 [db total_changes]
if {($tc2 - $tc1) < 2} break
}
@@ -166,4 +166,48 @@ do_execsql_test 2.8 {
SELECT level, count(*) FROM t2_segdir GROUP BY level;
} {0 2 1024 2 2048 2 3072 2}
#-------------------------------------------------------------------------
# Check that 'optimize' works when there is data in the in-memory hash
# table, but no segments at all on disk.
#
do_execsql_test 3.1 {
CREATE VIRTUAL TABLE fts USING fts4 (t);
INSERT INTO fts (fts) VALUES ('optimize');
}
do_execsql_test 3.2 {
INSERT INTO fts(fts) VALUES('integrity-check');
SELECT count(*) FROM fts_segdir;
} {0}
do_execsql_test 3.3 {
BEGIN;
INSERT INTO fts (rowid, t) VALUES (2, 'test');
INSERT INTO fts (fts) VALUES ('optimize');
COMMIT;
SELECT level, idx FROM fts_segdir;
} {0 0}
do_execsql_test 3.4 {
INSERT INTO fts(fts) VALUES('integrity-check');
SELECT rowid FROM fts WHERE fts MATCH 'test';
} {2}
do_execsql_test 3.5 {
INSERT INTO fts (fts) VALUES ('optimize');
INSERT INTO fts(fts) VALUES('integrity-check');
}
do_test 3.6 {
set c1 [db total_changes]
execsql { INSERT INTO fts (fts) VALUES ('optimize') }
expr {[db total_changes] - $c1}
} {1}
do_test 3.7 {
execsql { INSERT INTO fts (rowid, t) VALUES (3, 'xyz') }
set c1 [db total_changes]
execsql { INSERT INTO fts (fts) VALUES ('optimize') }
expr {([db total_changes] - $c1) > 1}
} {1}
do_test 3.8 {
set c1 [db total_changes]
execsql { INSERT INTO fts (fts) VALUES ('optimize') }
expr {[db total_changes] - $c1}
} {1}
finish_test
+35
View File
@@ -183,4 +183,39 @@ do_execsql_test 6.3.1 {
SELECT count(*) FROM x2 WHERE b IN (SELECT DISTINCT a FROM x1 LIMIT 2);
} {2}
#-------------------------------------------------------------------------
# Test to confirm that bug [5e3c886796e5] is fixed.
#
do_execsql_test 7.1 {
CREATE TABLE y1(a, b);
CREATE TABLE y2(c);
INSERT INTO y1 VALUES(1, 'one');
INSERT INTO y1 VALUES('two', 'two');
INSERT INTO y1 VALUES(3, 'three');
INSERT INTO y2 VALUES('one');
INSERT INTO y2 VALUES('two');
INSERT INTO y2 VALUES('three');
} {}
do_execsql_test 7.2.1 {
SELECT a FROM y1 WHERE b NOT IN (SELECT a FROM y2);
} {1 3}
do_execsql_test 7.2.2 {
SELECT a FROM y1 WHERE b IN (SELECT a FROM y2);
} {two}
do_execsql_test 7.3.1 {
CREATE INDEX y2c ON y2(c);
SELECT a FROM y1 WHERE b NOT IN (SELECT a FROM y2);
} {1 3}
do_execsql_test 7.3.2 {
SELECT a FROM y1 WHERE b IN (SELECT a FROM y2);
} {two}
finish_test
finish_test
+14 -9
View File
@@ -126,6 +126,11 @@ foreach AutoVacuumMode [list 0 1] {
execsql "PRAGMA mmap_size = 0"
execsql "PRAGMA auto_vacuum = $AutoVacuumMode"
# Extra value added to size answers
set ib2_extra 0
if {$AutoVacuumMode} {incr ib2_extra}
if {[nonzero_reserved_bytes]} {incr ib2_extra}
do_test incrblob-2.$AutoVacuumMode.1 {
set ::str [string repeat abcdefghij 2900]
execsql {
@@ -136,7 +141,7 @@ foreach AutoVacuumMode [list 0 1] {
COMMIT;
}
expr [file size test.db]/1024
} [expr 31 + $AutoVacuumMode]
} [expr 31 + $ib2_extra]
ifcapable autovacuum {
do_test incrblob-2.$AutoVacuumMode.2 {
@@ -163,7 +168,7 @@ foreach AutoVacuumMode [list 0 1] {
# sqlite uses the ptrmap pages to avoid reading the other pages.
#
nRead db
} [expr $AutoVacuumMode ? 4 : 30]
} [expr $AutoVacuumMode ? 4 : 30+$ib2_extra]
do_test incrblob-2.$AutoVacuumMode.4 {
string range [db one {SELECT v FROM blobs}] end-19 end
@@ -187,7 +192,7 @@ foreach AutoVacuumMode [list 0 1] {
# sqlite uses the ptrmap pages to avoid reading the other pages.
#
nRead db
} [expr $AutoVacuumMode ? 4 : 30]
} [expr $AutoVacuumMode ? 4 : 30 + $ib2_extra]
# Pages 1 (the write-counter) and 32 (the blob data) were written.
do_test incrblob-2.$AutoVacuumMode.6 {
@@ -210,7 +215,7 @@ foreach AutoVacuumMode [list 0 1] {
do_test incrblob-2.$AutoVacuumMode.9 {
nRead db
} [expr $AutoVacuumMode ? 4 : 30]
} [expr $AutoVacuumMode ? 4 : 30 + $ib2_extra]
}
sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
@@ -384,7 +389,7 @@ ifcapable vtab {
ifcapable attach {
do_test incrblob-5.1 {
forcedelete test2.db test2.db-journal
set ::size [expr [file size [info script]]]
set ::size [expr [file size $::cmdlinearg(INFO_SCRIPT)]]
execsql {
ATTACH 'test2.db' AS aux;
CREATE TABLE aux.files(name, text);
@@ -392,16 +397,16 @@ ifcapable attach {
}
set fd [db incrblob aux files text 1]
fconfigure $fd -translation binary
set fd2 [open [info script]]
set fd2 [open $::cmdlinearg(INFO_SCRIPT)]
fconfigure $fd2 -translation binary
puts -nonewline $fd [read $fd2]
close $fd
close $fd2
set ::text [db one {select text from aux.files}]
string length $::text
} [file size [info script]]
} [file size $::cmdlinearg(INFO_SCRIPT)]
do_test incrblob-5.2 {
set fd2 [open [info script]]
set fd2 [open $::cmdlinearg(INFO_SCRIPT)]
fconfigure $fd2 -translation binary
set ::data [read $fd2]
close $fd2
@@ -576,7 +581,7 @@ foreach {tn arg} {1 "" 2 -readonly} {
}
set fd [open [info script]]
set fd [open $::cmdlinearg(INFO_SCRIPT)]
fconfigure $fd -translation binary
set ::data [read $fd 14000]
close $fd
+2 -2
View File
@@ -24,12 +24,12 @@ ifcapable {!incrblob || !memdebug || !tclvar} {
source $testdir/malloc_common.tcl
unset -nocomplain ::fd ::data
set ::fd [open [info script]]
set ::fd [open $::cmdlinearg(INFO_SCRIPT)]
set ::data [read $::fd]
close $::fd
do_malloc_test 1 -tclprep {
set bytes [file size [info script]]
set bytes [file size $::cmdlinearg(INFO_SCRIPT)]
execsql {
CREATE TABLE blobs(k, v BLOB);
INSERT INTO blobs VALUES(1, zeroblob($::bytes));
+1 -1
View File
@@ -424,7 +424,7 @@ ifcapable pager_pragmas {
# The COMMIT requires a single fsync() - to the database file.
execsql { COMMIT }
list [file size test.db] [nSync]
} {39936 1}
} "[expr {[nonzero_reserved_bytes]?40960:39936}] 1"
}
#----------------------------------------------------------------------
+1 -1
View File
@@ -255,7 +255,7 @@ do_test memsubsys1-7.4 {
} 0
do_test memsubsys1-7.5 {
set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
expr {$maxreq<4100}
expr {$maxreq<4100 + 4200*[nonzero_reserved_bytes]}
} 1
do_test memsubsys1-7.6 {
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
+4 -2
View File
@@ -88,7 +88,7 @@ foreach {t mmap_size nRead c2init} {
sql2 { DELETE FROM t1 WHERE rowid%2; }
do_test $t.$tn.2 {
sql1 "SELECT count(*) FROM t1; PRAGMA integrity_check ; PRAGMA page_count"
} {16 ok 42}
} "16 ok [expr {42+[nonzero_reserved_bytes]}]"
# Have connection 2 grow the file. Check connection 1 can still read it.
sql2 { INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1 }
@@ -104,7 +104,9 @@ foreach {t mmap_size nRead c2init} {
# Check that the number of pages read by connection 1 indicates that the
# "PRAGMA mmap_size" command worked.
do_test $t.$tn.5 { nRead db } $nRead
if {[nonzero_reserved_bytes]==0} {
do_test $t.$tn.5 { nRead db } $nRead
}
}
}
+3
View File
@@ -19,6 +19,9 @@ ifcapable !mmap||!vtab {
source $testdir/lock_common.tcl
set testprefix mmap3
# A codec shuts down memory-mapped I/O
if {[nonzero_reserved_bytes]} {finish_test; return;}
do_test mmap3-1.0 {
load_static_extension db wholenumber
db eval {
+41 -39
View File
@@ -151,45 +151,47 @@ sqlite3_finalize $::STMT
# Then it reads the value of the database to verify it is converted into
# NULL.
#
do_test nan-3.1 {
db eval {
DELETE FROM t1;
INSERT INTO t1 VALUES(0.5);
PRAGMA auto_vacuum=OFF;
PRAGMA page_size=1024;
VACUUM;
}
hexio_read test.db 2040 8
} {3FE0000000000000}
do_test nan-3.2 {
db eval {
SELECT x, typeof(x) FROM t1
}
} {0.5 real}
do_test nan-3.3 {
db close
hexio_write test.db 2040 FFF8000000000000
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
do_test nan-3.4 {
db close
hexio_write test.db 2040 7FF8000000000000
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
do_test nan-3.5 {
db close
hexio_write test.db 2040 FFFFFFFFFFFFFFFF
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
do_test nan-3.6 {
db close
hexio_write test.db 2040 7FFFFFFFFFFFFFFF
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
if {![nonzero_reserved_bytes]} {
do_test nan-3.1 {
db eval {
DELETE FROM t1;
INSERT INTO t1 VALUES(0.5);
PRAGMA auto_vacuum=OFF;
PRAGMA page_size=1024;
VACUUM;
}
hexio_read test.db 2040 8
} {3FE0000000000000}
do_test nan-3.2 {
db eval {
SELECT x, typeof(x) FROM t1
}
} {0.5 real}
do_test nan-3.3 {
db close
hexio_write test.db 2040 FFF8000000000000
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
do_test nan-3.4 {
db close
hexio_write test.db 2040 7FF8000000000000
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
do_test nan-3.5 {
db close
hexio_write test.db 2040 FFFFFFFFFFFFFFFF
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
do_test nan-3.6 {
db close
hexio_write test.db 2040 7FFFFFFFFFFFFFFF
sqlite3 db test.db
db eval {SELECT x, typeof(x) FROM t1}
} {{} null}
}
# Verify that the sqlite3AtoF routine is able to handle extreme
# numbers.
+32
View File
@@ -182,4 +182,36 @@ do_test nolock-3.12 {
db2 close
db close
tvfs delete
# 2016-03-11: Make sure all works when transitioning to WAL mode under nolock.
#
do_test nolock-4.1 {
forcedelete test.db
sqlite3 db file:test.db?nolock=1 -uri 1
db eval {
PRAGMA journal_mode=WAL;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('youngling');
SELECT * FROM t1;
}
} {delete youngling}
db close
do_test nolock-4.2 {
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA journal_mode=WAL;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES('catbird');
SELECT * FROM t1;
}
} {wal catbird}
do_test nolock-4.3 {
db close
sqlite3 db file:test.db?nolock=1 -uri 1
set rc [catch {db eval {SELECT * FROM t1}} msg]
lappend rc $msg
} {1 {unable to open database file}}
finish_test
+58 -27
View File
@@ -1396,26 +1396,47 @@ do_test pager1-9.3.1 {
execsql { PRAGMA page_size = 1024 }
for {set ii 0} {$ii < 4} {incr ii} { execsql "CREATE TABLE t${ii}(a, b)" }
} {}
do_test pager1-9.3.2 {
sqlite3 db2 test.db2
execsql {
PRAGMA page_size = 4096;
PRAGMA synchronous = OFF;
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
} db2
sqlite3_backup B db2 main db main
B step 30
list [B step 10000] [B finish]
} {SQLITE_DONE SQLITE_OK}
do_test pager1-9.3.3 {
db2 close
db close
tv delete
file size test.db2
} [file size test.db]
if {[nonzero_reserved_bytes]} {
# backup with a page size changes is not possible with the codec
#
do_test pager1-9.3.2codec {
sqlite3 db2 test.db2
execsql {
PRAGMA page_size = 4096;
PRAGMA synchronous = OFF;
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
} db2
sqlite3_backup B db2 main db main
B step 30
list [B step 10000] [B finish]
} {SQLITE_READONLY SQLITE_READONLY}
do_test pager1-9.3.3codec {
db2 close
db close
tv delete
file size test.db2
} [file size test.db2]
} else {
do_test pager1-9.3.2 {
sqlite3 db2 test.db2
execsql {
PRAGMA page_size = 4096;
PRAGMA synchronous = OFF;
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
} db2
sqlite3_backup B db2 main db main
B step 30
list [B step 10000] [B finish]
} {SQLITE_DONE SQLITE_OK}
do_test pager1-9.3.3 {
db2 close
db close
tv delete
file size test.db2
} [file size test.db]
}
do_test pager1-9.4.1 {
faultsim_delete_and_reopen
@@ -2447,13 +2468,23 @@ do_test pager1-29.1 {
}
file size test.db
} [expr 1024*3]
do_test pager1-29.2 {
execsql {
PRAGMA page_size = 4096;
VACUUM;
}
file size test.db
} [expr 4096*3]
if {[nonzero_reserved_bytes]} {
# VACUUM with size changes is not possible with the codec.
do_test pager1-29.2 {
catchsql {
PRAGMA page_size = 4096;
VACUUM;
}
} {1 {attempt to write a readonly database}}
} else {
do_test pager1-29.2 {
execsql {
PRAGMA page_size = 4096;
VACUUM;
}
file size test.db
} [expr 4096*3]
}
#-------------------------------------------------------------------------
# Test that if an empty database file (size 0 bytes) is opened in
+1
View File
@@ -16,6 +16,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_not_use_codec
ifcapable {!pager_pragmas||secure_delete||direct_read} {
finish_test
+64 -62
View File
@@ -1741,73 +1741,75 @@ forcedelete data_dir
} ;# endif windows
database_may_be_corrupt
if {![nonzero_reserved_bytes]} {
do_test 21.1 {
# Create a corrupt database in testerr.db. And a non-corrupt at test.db.
#
db close
forcedelete test.db
sqlite3 db test.db
execsql {
PRAGMA page_size = 1024;
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 1);
}
for {set i 0} {$i < 10} {incr i} {
execsql { INSERT INTO t1 SELECT a + (1 << $i), b + (1 << $i) FROM t1 }
}
db close
forcecopy test.db testerr.db
hexio_write testerr.db 15000 [string repeat 55 100]
} {100}
set mainerr {*** in database main ***
do_test 21.1 {
# Create a corrupt database in testerr.db. And a non-corrupt at test.db.
#
db close
forcedelete test.db
sqlite3 db test.db
execsql {
PRAGMA page_size = 1024;
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 1);
}
for {set i 0} {$i < 10} {incr i} {
execsql { INSERT INTO t1 SELECT a + (1 << $i), b + (1 << $i) FROM t1 }
}
db close
forcecopy test.db testerr.db
hexio_write testerr.db 15000 [string repeat 55 100]
} {100}
set mainerr {*** in database main ***
Multiple uses for byte 672 of page 15}
set auxerr {*** in database aux ***
set auxerr {*** in database aux ***
Multiple uses for byte 672 of page 15}
set mainerr {/{\*\*\* in database main \*\*\*
set mainerr {/{\*\*\* in database main \*\*\*
Multiple uses for byte 672 of page 15}.*/}
set auxerr {/{\*\*\* in database aux \*\*\*
set auxerr {/{\*\*\* in database aux \*\*\*
Multiple uses for byte 672 of page 15}.*/}
do_test 22.2 {
catch { db close }
sqlite3 db testerr.db
execsql { PRAGMA integrity_check }
} $mainerr
do_test 22.3.1 {
catch { db close }
sqlite3 db test.db
execsql {
ATTACH 'testerr.db' AS 'aux';
PRAGMA integrity_check;
}
} $auxerr
do_test 22.3.2 {
execsql { PRAGMA main.integrity_check; }
} {ok}
do_test 22.3.3 {
execsql { PRAGMA aux.integrity_check; }
} $auxerr
do_test 22.4.1 {
catch { db close }
sqlite3 db testerr.db
execsql {
ATTACH 'test.db' AS 'aux';
PRAGMA integrity_check;
}
} $mainerr
do_test 22.4.2 {
execsql { PRAGMA main.integrity_check; }
} $mainerr
do_test 22.4.3 {
execsql { PRAGMA aux.integrity_check; }
} {ok}
do_test 22.2 {
catch { db close }
sqlite3 db testerr.db
execsql { PRAGMA integrity_check }
} $mainerr
do_test 22.3.1 {
catch { db close }
sqlite3 db test.db
execsql {
ATTACH 'testerr.db' AS 'aux';
PRAGMA integrity_check;
}
} $auxerr
do_test 22.3.2 {
execsql { PRAGMA main.integrity_check; }
} {ok}
do_test 22.3.3 {
execsql { PRAGMA aux.integrity_check; }
} $auxerr
do_test 22.4.1 {
catch { db close }
sqlite3 db testerr.db
execsql {
ATTACH 'test.db' AS 'aux';
PRAGMA integrity_check;
}
} $mainerr
do_test 22.4.2 {
execsql { PRAGMA main.integrity_check; }
} $mainerr
do_test 22.4.3 {
execsql { PRAGMA aux.integrity_check; }
} {ok}
}
db close
forcedelete test.db test.db-wal test.db-journal
sqlite3 db test.db
+1
View File
@@ -15,6 +15,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_not_use_codec
do_execsql_test pragma3-100 {
PRAGMA data_version;
+10 -1
View File
@@ -35,9 +35,18 @@ do_execsql_test 140 {
} {160}
do_execsql_test 200 {
SELECT spellfix1_scriptcode('+3.14159');
} {999}
} {215}
do_execsql_test 210 {
SELECT spellfix1_scriptcode('And God said: "Да будет свет"');
} {998}
do_execsql_test 220 {
SELECT spellfix1_scriptcode('+3.14159 light');
} {215}
do_execsql_test 230 {
SELECT spellfix1_scriptcode('+3.14159 свет');
} {220}
do_execsql_test 240 {
SELECT spellfix1_scriptcode('וַיֹּ֥אמֶר +3.14159');
} {125}
finish_test
+4
View File
@@ -21,6 +21,10 @@ ifcapable !vtab||!compound {
return
}
# This module uses hard-coded results that depend on exact measurements of
# pages sizes at the byte level, and hence will not work if the reserved_bytes
# value is nonzero.
if {[nonzero_reserved_bytes]} {finish_test; return;}
set ::asc 1
proc a_string {n} { string range [string repeat [incr ::asc]. $n] 1 $n }
+18 -7
View File
@@ -15,6 +15,7 @@ source $testdir/tester.tcl
source $testdir/lock_common.tcl
set testprefix superlock
do_not_use_codec
# Test organization:
#
@@ -238,13 +239,23 @@ db_swap test.db2 test.db
do_catchsql_test 6.9 { SELECT * FROM t1 } {0 {1 2 3 4}}
do_catchsql_test 6.10 { SELECT * FROM t2 } {1 {no such table: t2}}
do_execsql_test 6.11 {
PRAGMA journal_mode = delete;
PRAGMA page_size = 512;
VACUUM;
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(5, 6);
} {delete wal}
if {[nonzero_reserved_bytes]} {
# Vacuum with a size change is not allowed with the codec
do_execsql_test 6.11codec {
PRAGMA journal_mode = delete;
VACUUM;
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(5, 6);
} {delete wal}
} else {
do_execsql_test 6.11 {
PRAGMA journal_mode = delete;
PRAGMA page_size = 512;
VACUUM;
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(5, 6);
} {delete wal}
}
db_swap test.db2 test.db
do_catchsql_test 6.12 { SELECT * FROM t1 } {1 {no such table: t1}}
+2 -3
View File
@@ -22,10 +22,9 @@ source $testdir/tester.tcl
# Check the error messages generated by tclsqlite
#
set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
if {[sqlite3 -has-codec]} {
set r "sqlite_orig HANDLE FILENAME ?-key CODEC-KEY?"
} else {
set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
append r " ?-key CODECKEY?"
}
do_test tcl-1.1 {
set v [catch {sqlite3 bogus} msg]
+23 -1
View File
@@ -374,6 +374,12 @@ proc do_not_use_codec {} {
reset_db
}
# Return true if the "reserved_bytes" integer on database files is non-zero.
#
proc nonzero_reserved_bytes {} {
return [sqlite3 -has-codec]
}
# Print a HELP message and exit
#
proc print_help_and_quit {} {
@@ -411,6 +417,8 @@ if {[info exists cmdlinearg]==0} {
# --match=$pattern
# --verbose=$val
# --output=$filename
# -q Reduce output
# --testdir=$dir Run tests in subdirectory $dir
# --help
#
set cmdlinearg(soft-heap-limit) 0
@@ -425,6 +433,7 @@ if {[info exists cmdlinearg]==0} {
set cmdlinearg(match) ""
set cmdlinearg(verbose) ""
set cmdlinearg(output) ""
set cmdlinearg(testdir) "testdir"
set leftover [list]
foreach a $argv {
@@ -454,6 +463,7 @@ if {[info exists cmdlinearg]==0} {
}
{^-+binarylog=.+$} {
foreach {dummy cmdlinearg(binarylog)} [split $a =] break
set cmdlinearg(binarylog) [file normalize $cmdlinearg(binarylog)]
}
{^-+soak=.+$} {
foreach {dummy cmdlinearg(soak)} [split $a =] break
@@ -486,6 +496,7 @@ if {[info exists cmdlinearg]==0} {
{^-+output=.+$} {
foreach {dummy cmdlinearg(output)} [split $a =] break
set cmdlinearg(output) [file normalize $cmdlinearg(output)]
if {$cmdlinearg(verbose)==""} {
set cmdlinearg(verbose) 2
}
@@ -498,6 +509,9 @@ if {[info exists cmdlinearg]==0} {
error "option --verbose= must be set to a boolean or to \"file\""
}
}
{^-+testdir=.*$} {
foreach {dummy cmdlinearg(testdir)} [split $a =] break
}
{.*help.*} {
print_help_and_quit
}
@@ -507,10 +521,18 @@ if {[info exists cmdlinearg]==0} {
}
default {
lappend leftover $a
lappend leftover [file normalize $a]
}
}
}
set testdir [file normalize $testdir]
set cmdlinearg(TESTFIXTURE_HOME) [pwd]
set cmdlinearg(INFO_SCRIPT) [file normalize [info script]]
set argv0 [file normalize $argv0]
if {$cmdlinearg(testdir)!=""} {
file mkdir $cmdlinearg(testdir)
cd $cmdlinearg(testdir)
}
set argv $leftover
# Install the malloc layer used to inject OOM errors. And the 'automatic'
+1
View File
@@ -16,6 +16,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_not_use_codec
proc testsql {sql} {
set fd [open tf_main.tcl w]
+2
View File
@@ -1378,6 +1378,7 @@ do_test wal-21.3 {
#-------------------------------------------------------------------------
# Test reading and writing of databases with different page-sizes.
#
incr ::do_not_use_codec
foreach pgsz {512 1024 2048 4096 8192 16384 32768 65536} {
do_multiclient_test tn [string map [list %PGSZ% $pgsz] {
do_test wal-22.%PGSZ%.$tn.1 {
@@ -1398,6 +1399,7 @@ foreach pgsz {512 1024 2048 4096 8192 16384 32768 65536} {
} {0}
}]
}
incr ::do_not_use_codec -1
#-------------------------------------------------------------------------
# Test that when 1 or more pages are recovered from a WAL file,
+1
View File
@@ -18,6 +18,7 @@ source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
do_not_use_codec
set testprefix wal5
+1
View File
@@ -27,6 +27,7 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix wal8
ifcapable !wal {finish_test ; return }
do_not_use_codec
db close
forcedelete test.db test.db-wal
+2
View File
@@ -127,6 +127,7 @@ do_test walbak-2.1 {
}
} {}
do_test walbak-2.2 {
forcedelete abc.db
db backup abc.db
sqlite3 db2 abc.db
string compare [sig db] [sig db2]
@@ -239,6 +240,7 @@ foreach {tn setup} {
}
} {
if {$tn==4 && [sqlite3 -has-codec]} continue
foreach f [glob -nocomplain test.db*] { forcedelete $f }
eval $setup
+1 -1
View File
@@ -212,7 +212,7 @@ do_multiclient_test tn {
INSERT INTO t2 SELECT x||y, y||x FROM t2;
}
file size test.db-wal
} {147800}
} [expr {[nonzero_reserved_bytes]?148848:147800}]
do_test 1.4.4.2 {
csql1 { SELECT * FROM t1 }
} {0 {a b c d e f g h i j k l 1 2 3 4 5 6}}
+11
View File
@@ -765,4 +765,15 @@ do_execsql_test where2-13.1 {
SELECT * FROM t13 WHERE (1=2 AND a=3) OR a=4;
} {4 5}
# https://www.sqlite.org/src/info/5e3c886796e5512e (2016-03-09)
# Correlated subquery on the RHS of an IN operator
#
do_execsql_test where2-14.1 {
CREATE TABLE t14a(x INTEGER PRIMARY KEY);
INSERT INTO t14a(x) VALUES(1),(2),(3),(4);
CREATE TABLE t14b(y INTEGER PRIMARY KEY);
INSERT INTO t14b(y) VALUES(1);
SELECT x FROM t14a WHERE x NOT IN (SELECT x FROM t14b);
} {}
finish_test
+12 -8
View File
@@ -665,11 +665,13 @@ FOR %%P IN (%PLATFORMS%) DO (
REM are prevented from doing so.
REM
IF NOT DEFINED NOSYMBOLS (
%__ECHO% XCOPY "%DLL_PDB_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF EXIST "%DLL_PDB_FILE_NAME%" (
%__ECHO% XCOPY "%DLL_PDB_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "%DLL_PDB_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
IF ERRORLEVEL 1 (
ECHO Failed to copy "%DLL_PDB_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
)
)
)
@@ -722,11 +724,13 @@ FOR %%P IN (%PLATFORMS%) DO (
REM unless we are prevented from doing so.
REM
IF NOT DEFINED NOSYMBOLS (
%__ECHO% XCOPY "%EXE_PDB_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF EXIST "%EXE_PDB_FILE_NAME%" (
%__ECHO% XCOPY "%EXE_PDB_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
ECHO Failed to copy "%EXE_PDB_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
IF ERRORLEVEL 1 (
ECHO Failed to copy "%EXE_PDB_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
)
)
)
)