Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85ebe788c7 | |||
| 87d9f8b595 | |||
| d72c1d639f | |||
| 5e884edc9f | |||
| f002023104 | |||
| d8668c8752 | |||
| dd853fb6e5 | |||
| 0e8e04efd1 | |||
| 8c441848d2 | |||
| 142f927687 | |||
| 0a58f18b07 | |||
| f3b4d49a96 |
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.8.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.8.3.
|
||||
#
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.8.8'
|
||||
PACKAGE_STRING='sqlite 3.8.8'
|
||||
PACKAGE_VERSION='3.8.8.3'
|
||||
PACKAGE_STRING='sqlite 3.8.8.3'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# Factoring default headers for most tests.
|
||||
@@ -1480,7 +1480,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.8.8 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.8.8.3 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1545,7 +1545,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.8:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.8.3:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1659,7 +1659,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.8.8
|
||||
sqlite configure 3.8.8.3
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
@@ -1673,7 +1673,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.8.8, which was
|
||||
It was created by sqlite $as_me 3.8.8.3, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -13951,7 +13951,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.8.8, which was
|
||||
This file was extended by sqlite $as_me 3.8.8.3, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -14004,7 +14004,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.8.8
|
||||
sqlite config.status 3.8.8.3
|
||||
configured by $0, generated by GNU Autoconf 2.62,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
||||
+54
-62
@@ -5020,6 +5020,22 @@ static void fts3EvalNextRow(
|
||||
}
|
||||
pExpr->iDocid = pLeft->iDocid;
|
||||
pExpr->bEof = (pLeft->bEof || pRight->bEof);
|
||||
if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
|
||||
if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
|
||||
Fts3Doclist *pDl = &pRight->pPhrase->doclist;
|
||||
while( *pRc==SQLITE_OK && pRight->bEof==0 ){
|
||||
memset(pDl->pList, 0, pDl->nList);
|
||||
fts3EvalNextRow(pCsr, pRight, pRc);
|
||||
}
|
||||
}
|
||||
if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){
|
||||
Fts3Doclist *pDl = &pLeft->pPhrase->doclist;
|
||||
while( *pRc==SQLITE_OK && pLeft->bEof==0 ){
|
||||
memset(pDl->pList, 0, pDl->nList);
|
||||
fts3EvalNextRow(pCsr, pLeft, pRc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -5392,6 +5408,7 @@ static void fts3EvalRestart(
|
||||
}
|
||||
pPhrase->doclist.pNextDocid = 0;
|
||||
pPhrase->doclist.iDocid = 0;
|
||||
pPhrase->pOrPoslist = 0;
|
||||
}
|
||||
|
||||
pExpr->iDocid = 0;
|
||||
@@ -5637,6 +5654,7 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
iDocid = pExpr->iDocid;
|
||||
pIter = pPhrase->doclist.pList;
|
||||
if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
|
||||
int rc = SQLITE_OK;
|
||||
int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
|
||||
int iMul; /* +1 if csr dir matches index dir, else -1 */
|
||||
int bOr = 0;
|
||||
@@ -5662,72 +5680,43 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
** an incremental phrase. Load the entire doclist for the phrase
|
||||
** into memory in this case. */
|
||||
if( pPhrase->bIncr ){
|
||||
int rc = SQLITE_OK;
|
||||
int bEofSave = pExpr->bEof;
|
||||
fts3EvalRestart(pCsr, pExpr, &rc);
|
||||
while( rc==SQLITE_OK && !pExpr->bEof ){
|
||||
fts3EvalNextRow(pCsr, pExpr, &rc);
|
||||
if( bEofSave==0 && pExpr->iDocid==iDocid ) break;
|
||||
int bEofSave = pNear->bEof;
|
||||
fts3EvalRestart(pCsr, pNear, &rc);
|
||||
while( rc==SQLITE_OK && !pNear->bEof ){
|
||||
fts3EvalNextRow(pCsr, pNear, &rc);
|
||||
if( bEofSave==0 && pNear->iDocid==iDocid ) break;
|
||||
}
|
||||
pIter = pPhrase->doclist.pList;
|
||||
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
|
||||
iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1);
|
||||
while( bTreeEof==1
|
||||
&& pNear->bEof==0
|
||||
&& (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
fts3EvalNextRow(pCsr, pExpr, &rc);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
iDocid = pExpr->iDocid;
|
||||
pIter = pPhrase->doclist.pList;
|
||||
}
|
||||
|
||||
bEof = (pPhrase->doclist.nAll==0);
|
||||
assert( bDescDoclist==0 || bDescDoclist==1 );
|
||||
assert( pCsr->bDesc==0 || pCsr->bDesc==1 );
|
||||
|
||||
if( bEof==0 ){
|
||||
if( pCsr->bDesc==bDescDoclist ){
|
||||
int dummy;
|
||||
if( pNear->bEof ){
|
||||
/* This expression is already at EOF. So position it to point to the
|
||||
** last entry in the doclist at pPhrase->doclist.aAll[]. Variable
|
||||
** iDocid is already set for this entry, so all that is required is
|
||||
** to set pIter to point to the first byte of the last position-list
|
||||
** in the doclist.
|
||||
**
|
||||
** It would also be correct to set pIter and iDocid to zero. In
|
||||
** this case, the first call to sqltie3Fts4DoclistPrev() below
|
||||
** would also move the iterator to point to the last entry in the
|
||||
** doclist. However, this is expensive, as to do so it has to
|
||||
** iterate through the entire doclist from start to finish (since
|
||||
** it does not know the docid for the last entry). */
|
||||
pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1];
|
||||
fts3ReversePoslist(pPhrase->doclist.aAll, &pIter);
|
||||
}
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistPrev(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &dummy, &bEof
|
||||
);
|
||||
}
|
||||
}else{
|
||||
if( pNear->bEof ){
|
||||
pIter = 0;
|
||||
iDocid = 0;
|
||||
}
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistNext(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &bEof
|
||||
);
|
||||
}
|
||||
if( bTreeEof ){
|
||||
while( rc==SQLITE_OK && !pNear->bEof ){
|
||||
fts3EvalNextRow(pCsr, pNear, &rc);
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
pIter = pPhrase->pOrPoslist;
|
||||
iDocid = pPhrase->iOrDocid;
|
||||
if( pCsr->bDesc==bDescDoclist ){
|
||||
bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistNext(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &bEof
|
||||
);
|
||||
}
|
||||
}else{
|
||||
bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll);
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
|
||||
int dummy;
|
||||
sqlite3Fts3DoclistPrev(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
&pIter, &iDocid, &dummy, &bEof
|
||||
);
|
||||
}
|
||||
}
|
||||
pPhrase->pOrPoslist = pIter;
|
||||
pPhrase->iOrDocid = iDocid;
|
||||
|
||||
if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
|
||||
}
|
||||
@@ -5741,10 +5730,13 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
}
|
||||
while( iThis<iCol ){
|
||||
fts3ColumnlistCopy(0, &pIter);
|
||||
if( *pIter==0x00 ) return 0;
|
||||
if( *pIter==0x00 ) return SQLITE_OK;
|
||||
pIter++;
|
||||
pIter += fts3GetVarint32(pIter, &iThis);
|
||||
}
|
||||
if( *pIter==0x00 ){
|
||||
pIter = 0;
|
||||
}
|
||||
|
||||
*ppOut = ((iCol==iThis)?pIter:0);
|
||||
return SQLITE_OK;
|
||||
|
||||
@@ -375,6 +375,11 @@ struct Fts3Phrase {
|
||||
int bIncr; /* True if doclist is loaded incrementally */
|
||||
int iDoclistToken;
|
||||
|
||||
/* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an
|
||||
** OR condition. */
|
||||
char *pOrPoslist;
|
||||
i64 iOrDocid;
|
||||
|
||||
/* Variables below this point are populated by fts3_expr.c when parsing
|
||||
** a MATCH expression. Everything above is part of the evaluation phase.
|
||||
*/
|
||||
|
||||
+27
-25
@@ -442,37 +442,39 @@ static int fts3BestSnippet(
|
||||
sIter.nSnippet = nSnippet;
|
||||
sIter.nPhrase = nList;
|
||||
sIter.iCurrent = -1;
|
||||
(void)fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
|
||||
rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
|
||||
if( rc==SQLITE_OK ){
|
||||
|
||||
/* Set the *pmSeen output variable. */
|
||||
for(i=0; i<nList; i++){
|
||||
if( sIter.aPhrase[i].pHead ){
|
||||
*pmSeen |= (u64)1 << i;
|
||||
/* Set the *pmSeen output variable. */
|
||||
for(i=0; i<nList; i++){
|
||||
if( sIter.aPhrase[i].pHead ){
|
||||
*pmSeen |= (u64)1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop through all candidate snippets. Store the best snippet in
|
||||
** *pFragment. Store its associated 'score' in iBestScore.
|
||||
*/
|
||||
pFragment->iCol = iCol;
|
||||
while( !fts3SnippetNextCandidate(&sIter) ){
|
||||
int iPos;
|
||||
int iScore;
|
||||
u64 mCover;
|
||||
u64 mHighlight;
|
||||
fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover, &mHighlight);
|
||||
assert( iScore>=0 );
|
||||
if( iScore>iBestScore ){
|
||||
pFragment->iPos = iPos;
|
||||
pFragment->hlmask = mHighlight;
|
||||
pFragment->covered = mCover;
|
||||
iBestScore = iScore;
|
||||
/* Loop through all candidate snippets. Store the best snippet in
|
||||
** *pFragment. Store its associated 'score' in iBestScore.
|
||||
*/
|
||||
pFragment->iCol = iCol;
|
||||
while( !fts3SnippetNextCandidate(&sIter) ){
|
||||
int iPos;
|
||||
int iScore;
|
||||
u64 mCover;
|
||||
u64 mHighlite;
|
||||
fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite);
|
||||
assert( iScore>=0 );
|
||||
if( iScore>iBestScore ){
|
||||
pFragment->iPos = iPos;
|
||||
pFragment->hlmask = mHighlite;
|
||||
pFragment->covered = mCover;
|
||||
iBestScore = iScore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*piScore = iBestScore;
|
||||
}
|
||||
sqlite3_free(sIter.aPhrase);
|
||||
*piScore = iBestScore;
|
||||
return SQLITE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
C Version\s3.8.8
|
||||
D 2015-01-16T12:08:06.393
|
||||
C Version\s3.8.8.3
|
||||
D 2015-02-25T13:29:11.692
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5407a688f4d77a05c18a8142be8ae5a2829dd610
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 4c057774e6138b9023fc16ec05639ddd3329b152
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
||||
F VERSION d846487aff892625eb8e75960234e7285f0462fe
|
||||
F VERSION 0de46a30a2d0a7a6a686fd35186fbad0ac06ff71
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure b2882796ddebd33ac4e9d4ccf5c5ca11888fc30e x
|
||||
F configure 444b4cd66ec94631b2b624cf24d01142c9aac0ae x
|
||||
F configure.ac 6a8d145aea6d81f0b90013340780e43ed74fd5f4
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||
@@ -78,16 +78,16 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 5c464816508e40feb3c61f1f5566551764698fc8
|
||||
F ext/fts3/fts3.c 845f20440dacac6e09f5c7735205609b9a86536b
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 53d4eca1fb23eab00681fb028fb82eb5705c1e21
|
||||
F ext/fts3/fts3Int.h 394858c12a17740f7a1f6bd372c4606d4425a8d1
|
||||
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
|
||||
F ext/fts3/fts3_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905
|
||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c 51beb5c1498176fd9caccaf1c75b55cb803a985a
|
||||
F ext/fts3/fts3_snippet.c 55c126e07158b2a705f52dee2cdc57208d3e999a
|
||||
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
|
||||
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
|
||||
F ext/fts3/fts3_tokenize_vtab.c becc661223db7898b213f9e8a23d75bac02408c9
|
||||
@@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660
|
||||
F src/main.c 05bf368c934cc73d02906030846eb4d1818c10f7
|
||||
F src/main.c 341fcc5601a8ca84389fa32bcf5a857f65af8dd0
|
||||
F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
||||
@@ -229,8 +229,8 @@ F src/printf.c ea82bcb1b83273b4c67177c233c1f78c81fc42f9
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c e4c38c75e36f28aed80a69a725d888751bfd53df
|
||||
F src/shell.c 5b8e786a7c8eec87fa3f2ea615b337d2d99e284c
|
||||
F src/select.c a4e8fda24c8eab2682a058bdda0d5d68cfe3919c
|
||||
F src/shell.c ee1a80bf2b0e9e0c2b93db8f0f82b841289b2641
|
||||
F src/sqlite.h.in 9dfc99d6533d36d6a549c4f3f01cacc8be956ada
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
@@ -296,16 +296,16 @@ F src/vdbe.c ddfc977981cd6324668aa6b114045eb1c677421a
|
||||
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
|
||||
F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
|
||||
F src/vdbeapi.c 4bc511a46b9839392ae0e90844a71dc96d9dbd71
|
||||
F src/vdbeaux.c 07ef87c6d4b5abdf13ff33babb10205702fdab0a
|
||||
F src/vdbeaux.c f06d38c71d7f533348c09869d69fd1b647042a5b
|
||||
F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778
|
||||
F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
|
||||
F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9
|
||||
F src/wal.c 85353539f2d9d0c91ebd057c32525b1e1aa3335e
|
||||
F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c d46de821bc604a4fd36fa3928c086950e91aafb1
|
||||
F src/where.c 88509f19a64a36e1c22a1dbdac74ee1a62d99dc3
|
||||
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@@ -349,7 +349,7 @@ F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
|
||||
F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7
|
||||
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d
|
||||
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
|
||||
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
@@ -650,7 +650,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
F test/index3.test 55a90cff99834305e8141df7afaef39674b57062
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
|
||||
F test/index6.test fb370966ac3cd0989053dd5385757b5c3e24ab6a
|
||||
F test/index6.test c56852451b574ad5b2a1789e566e62e6ab244f42
|
||||
F test/index7.test 917cf1e1c7439bb155abbeabec511b28945e157b
|
||||
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
@@ -769,6 +769,7 @@ F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
|
||||
F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb
|
||||
F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
|
||||
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||
F test/oserror.test 14fec2796c2b6fe431c7823750e8a18a761176d7
|
||||
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
|
||||
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
|
||||
@@ -1125,7 +1126,7 @@ F test/wal.test 885f32b2b390b30b4aa3dbb0e568f8f78d40f5cc
|
||||
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
|
||||
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 11b8658dd4d5448f4604124bebd9b68be5bc3e66
|
||||
F test/wal5.test dba8f5f5de95178bc40521d6edf153b2e2829917
|
||||
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
||||
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
@@ -1236,10 +1237,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 8f45217cbafef2297cdcec3fd69f4371dfb83922
|
||||
R 933466cd8ec4e35d692da3aefe1a6703
|
||||
P ec27ab0eb3a1ee08a73dda23d2a0f9fb70962745
|
||||
R 7a9d6545656b7d4fe08d198e32a78d62
|
||||
T +bgcolor * #d0c0ff
|
||||
T +sym-release *
|
||||
T +sym-version-3.8.8 *
|
||||
T +sym-version-3.8.8.3 *
|
||||
U drh
|
||||
Z bb546801ed90d1803572e32e58b772a4
|
||||
Z 9dbdbd01efd2c5089344e2a1709c163b
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
7d68a42face3ab14ed88407d4331872f5b243fdf
|
||||
9d6c1880fb75660bbabd693175579529785f8a6b
|
||||
@@ -1966,6 +1966,7 @@ int sqlite3_wal_checkpoint_v2(
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb);
|
||||
}else{
|
||||
db->busyHandler.nBusy = 0;
|
||||
rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
|
||||
sqlite3Error(db, rc);
|
||||
}
|
||||
|
||||
+6
-4
@@ -543,7 +543,9 @@ static void pushOntoSorter(
|
||||
pKI = pOp->p4.pKeyInfo;
|
||||
memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
|
||||
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
|
||||
pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, 1);
|
||||
testcase( pKI->nXField>2 );
|
||||
pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
|
||||
pKI->nXField-1);
|
||||
addrJmp = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
|
||||
pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
|
||||
@@ -1054,7 +1056,7 @@ static KeyInfo *keyInfoFromExprList(
|
||||
int i;
|
||||
|
||||
nExpr = pList->nExpr;
|
||||
pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra-iStart, 1);
|
||||
pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1);
|
||||
if( pInfo ){
|
||||
assert( sqlite3KeyInfoIsWriteable(pInfo) );
|
||||
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
|
||||
@@ -4924,7 +4926,7 @@ int sqlite3Select(
|
||||
*/
|
||||
if( sSort.pOrderBy ){
|
||||
KeyInfo *pKeyInfo;
|
||||
pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0);
|
||||
pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
|
||||
sSort.iECursor = pParse->nTab++;
|
||||
sSort.addrSortIndex =
|
||||
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
|
||||
@@ -5098,7 +5100,7 @@ int sqlite3Select(
|
||||
** will be converted into a Noop.
|
||||
*/
|
||||
sAggInfo.sortingIdx = pParse->nTab++;
|
||||
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, 0);
|
||||
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
|
||||
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
|
||||
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
|
||||
0, (char*)pKeyInfo, P4_KEYINFO);
|
||||
|
||||
+35
-17
@@ -59,18 +59,38 @@
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_EDITLINE
|
||||
# undef HAVE_READLINE
|
||||
# define HAVE_READLINE 1
|
||||
# include <editline/readline.h>
|
||||
#endif
|
||||
#if !HAVE_READLINE
|
||||
# define add_history(X)
|
||||
# define read_history(X)
|
||||
# define write_history(X)
|
||||
# define stifle_history(X)
|
||||
|
||||
#if HAVE_EDITLINE || HAVE_READLINE
|
||||
|
||||
# define shell_add_history(X) add_history(X)
|
||||
# define shell_read_history(X) read_history(X)
|
||||
# define shell_write_history(X) write_history(X)
|
||||
# define shell_stifle_history(X) stifle_history(X)
|
||||
# define shell_readline(X) readline(X)
|
||||
|
||||
#elif HAVE_LINENOISE
|
||||
|
||||
# include "linenoise.h"
|
||||
# define shell_add_history(X) linenoiseHistoryAdd(X)
|
||||
# define shell_read_history(X) linenoiseHistoryLoad(X)
|
||||
# define shell_write_history(X) linenoiseHistorySave(X)
|
||||
# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
|
||||
# define shell_readline(X) linenoise(X)
|
||||
|
||||
#else
|
||||
|
||||
# define shell_read_history(X)
|
||||
# define shell_write_history(X)
|
||||
# define shell_stifle_history(X)
|
||||
|
||||
# define SHELL_USE_LOCAL_GETLINE 1
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
@@ -431,14 +451,14 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
|
||||
zResult = local_getline(zPrior, in);
|
||||
}else{
|
||||
zPrompt = isContinuation ? continuePrompt : mainPrompt;
|
||||
#if HAVE_READLINE
|
||||
free(zPrior);
|
||||
zResult = readline(zPrompt);
|
||||
if( zResult && *zResult ) add_history(zResult);
|
||||
#else
|
||||
#if SHELL_USE_LOCAL_GETLINE
|
||||
printf("%s", zPrompt);
|
||||
fflush(stdout);
|
||||
zResult = local_getline(zPrior, stdin);
|
||||
#else
|
||||
free(zPrior);
|
||||
zResult = shell_readline(zPrompt);
|
||||
if( zResult && *zResult ) shell_add_history(zResult);
|
||||
#endif
|
||||
}
|
||||
return zResult;
|
||||
@@ -4488,13 +4508,11 @@ int main(int argc, char **argv){
|
||||
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
|
||||
}
|
||||
}
|
||||
#if HAVE_READLINE
|
||||
if( zHistory ) read_history(zHistory);
|
||||
#endif
|
||||
if( zHistory ) shell_read_history(zHistory);
|
||||
rc = process_input(&data, 0);
|
||||
if( zHistory ){
|
||||
stifle_history(100);
|
||||
write_history(zHistory);
|
||||
shell_stifle_history(100);
|
||||
shell_write_history(zHistory);
|
||||
free(zHistory);
|
||||
}
|
||||
}else{
|
||||
|
||||
@@ -3349,6 +3349,41 @@ debugCompareEnd:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_DEBUG
|
||||
/*
|
||||
** Count the number of fields (a.k.a. columns) in the record given by
|
||||
** pKey,nKey. The verify that this count is less than or equal to the
|
||||
** limit given by pKeyInfo->nField + pKeyInfo->nXField.
|
||||
**
|
||||
** If this constraint is not satisfied, it means that the high-speed
|
||||
** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
|
||||
** not work correctly. If this assert() ever fires, it probably means
|
||||
** that the KeyInfo.nField or KeyInfo.nXField values were computed
|
||||
** incorrectly.
|
||||
*/
|
||||
static void vdbeAssertFieldCountWithinLimits(
|
||||
int nKey, const void *pKey, /* The record to verify */
|
||||
const KeyInfo *pKeyInfo /* Compare size with this KeyInfo */
|
||||
){
|
||||
int nField = 0;
|
||||
u32 szHdr;
|
||||
u32 idx;
|
||||
u32 notUsed;
|
||||
const unsigned char *aKey = (const unsigned char*)pKey;
|
||||
|
||||
if( CORRUPT_DB ) return;
|
||||
idx = getVarint32(aKey, szHdr);
|
||||
assert( szHdr<=nKey );
|
||||
while( idx<szHdr ){
|
||||
idx += getVarint32(aKey+idx, notUsed);
|
||||
nField++;
|
||||
}
|
||||
assert( nField <= pKeyInfo->nField+pKeyInfo->nXField );
|
||||
}
|
||||
#else
|
||||
# define vdbeAssertFieldCountWithinLimits(A,B,C)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Both *pMem1 and *pMem2 contain string values. Compare the two values
|
||||
** using the collation sequence pColl. As usual, return a negative , zero
|
||||
@@ -3760,6 +3795,7 @@ static int vdbeRecordCompareInt(
|
||||
i64 v = pPKey2->aMem[0].u.i;
|
||||
i64 lhs;
|
||||
|
||||
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
|
||||
assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB );
|
||||
switch( serial_type ){
|
||||
case 1: { /* 1-byte signed integer */
|
||||
@@ -3847,6 +3883,7 @@ static int vdbeRecordCompareString(
|
||||
int serial_type;
|
||||
int res;
|
||||
|
||||
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
|
||||
getVarint32(&aKey1[1], serial_type);
|
||||
if( serial_type<12 ){
|
||||
res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
|
||||
|
||||
@@ -1694,7 +1694,7 @@ static int walCheckpoint(
|
||||
int sync_flags, /* Flags for OsSync() (or 0) */
|
||||
u8 *zBuf /* Temporary buffer to use */
|
||||
){
|
||||
int rc; /* Return code */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int szPage; /* Database page-size */
|
||||
WalIterator *pIter = 0; /* Wal iterator context */
|
||||
u32 iDbpage = 0; /* Next database page to write */
|
||||
@@ -1708,104 +1708,107 @@ static int walCheckpoint(
|
||||
testcase( szPage<=32768 );
|
||||
testcase( szPage>=65536 );
|
||||
pInfo = walCkptInfo(pWal);
|
||||
if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK;
|
||||
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
|
||||
|
||||
/* Allocate the iterator */
|
||||
rc = walIteratorInit(pWal, &pIter);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
assert( pIter );
|
||||
|
||||
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
|
||||
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
|
||||
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
|
||||
|
||||
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
|
||||
** safe to write into the database. Frames beyond mxSafeFrame might
|
||||
** overwrite database pages that are in use by active readers and thus
|
||||
** cannot be backfilled from the WAL.
|
||||
*/
|
||||
mxSafeFrame = pWal->hdr.mxFrame;
|
||||
mxPage = pWal->hdr.nPage;
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
u32 y = pInfo->aReadMark[i];
|
||||
if( mxSafeFrame>y ){
|
||||
assert( y<=pWal->hdr.mxFrame );
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
}else if( rc==SQLITE_BUSY ){
|
||||
mxSafeFrame = y;
|
||||
xBusy = 0;
|
||||
}else{
|
||||
goto walcheckpoint_out;
|
||||
}
|
||||
/* Allocate the iterator */
|
||||
rc = walIteratorInit(pWal, &pIter);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
assert( pIter );
|
||||
|
||||
if( pInfo->nBackfill<mxSafeFrame
|
||||
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
|
||||
){
|
||||
i64 nSize; /* Current size of database file */
|
||||
u32 nBackfill = pInfo->nBackfill;
|
||||
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
|
||||
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
|
||||
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
|
||||
|
||||
/* Sync the WAL to disk */
|
||||
if( sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
}
|
||||
|
||||
/* If the database may grow as a result of this checkpoint, hint
|
||||
** about the eventual size of the db file to the VFS layer.
|
||||
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
|
||||
** safe to write into the database. Frames beyond mxSafeFrame might
|
||||
** overwrite database pages that are in use by active readers and thus
|
||||
** cannot be backfilled from the WAL.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
i64 nReq = ((i64)mxPage * szPage);
|
||||
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
|
||||
if( rc==SQLITE_OK && nSize<nReq ){
|
||||
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Iterate through the contents of the WAL, copying data to the db file. */
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
assert( walFramePgno(pWal, iFrame)==iDbpage );
|
||||
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
|
||||
iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
|
||||
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
|
||||
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
iOffset = (iDbpage-1)*(i64)szPage;
|
||||
testcase( IS_BIG_INT(iOffset) );
|
||||
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
|
||||
/* If work was actually accomplished... */
|
||||
if( rc==SQLITE_OK ){
|
||||
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
|
||||
i64 szDb = pWal->hdr.nPage*(i64)szPage;
|
||||
testcase( IS_BIG_INT(szDb) );
|
||||
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
|
||||
if( rc==SQLITE_OK && sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
|
||||
mxSafeFrame = pWal->hdr.mxFrame;
|
||||
mxPage = pWal->hdr.nPage;
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
u32 y = pInfo->aReadMark[i];
|
||||
if( mxSafeFrame>y ){
|
||||
assert( y<=pWal->hdr.mxFrame );
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
}else if( rc==SQLITE_BUSY ){
|
||||
mxSafeFrame = y;
|
||||
xBusy = 0;
|
||||
}else{
|
||||
goto walcheckpoint_out;
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->nBackfill = mxSafeFrame;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the reader lock held while backfilling */
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
|
||||
}
|
||||
if( pInfo->nBackfill<mxSafeFrame
|
||||
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
|
||||
){
|
||||
i64 nSize; /* Current size of database file */
|
||||
u32 nBackfill = pInfo->nBackfill;
|
||||
|
||||
if( rc==SQLITE_BUSY ){
|
||||
/* Reset the return code so as not to report a checkpoint failure
|
||||
** just because there are active readers. */
|
||||
rc = SQLITE_OK;
|
||||
/* Sync the WAL to disk */
|
||||
if( sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
}
|
||||
|
||||
/* If the database may grow as a result of this checkpoint, hint
|
||||
** about the eventual size of the db file to the VFS layer.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
i64 nReq = ((i64)mxPage * szPage);
|
||||
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
|
||||
if( rc==SQLITE_OK && nSize<nReq ){
|
||||
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Iterate through the contents of the WAL, copying data to the db file */
|
||||
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
i64 iOffset;
|
||||
assert( walFramePgno(pWal, iFrame)==iDbpage );
|
||||
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
|
||||
continue;
|
||||
}
|
||||
iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
|
||||
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
|
||||
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
iOffset = (iDbpage-1)*(i64)szPage;
|
||||
testcase( IS_BIG_INT(iOffset) );
|
||||
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
|
||||
/* If work was actually accomplished... */
|
||||
if( rc==SQLITE_OK ){
|
||||
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
|
||||
i64 szDb = pWal->hdr.nPage*(i64)szPage;
|
||||
testcase( IS_BIG_INT(szDb) );
|
||||
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
|
||||
if( rc==SQLITE_OK && sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pInfo->nBackfill = mxSafeFrame;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the reader lock held while backfilling */
|
||||
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_BUSY ){
|
||||
/* Reset the return code so as not to report a checkpoint failure
|
||||
** just because there are active readers. */
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
|
||||
@@ -1820,7 +1823,7 @@ static int walCheckpoint(
|
||||
}else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
|
||||
u32 salt1;
|
||||
sqlite3_randomness(4, &salt1);
|
||||
assert( mxSafeFrame==pWal->hdr.mxFrame );
|
||||
assert( pInfo->nBackfill==pWal->hdr.mxFrame );
|
||||
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
|
||||
|
||||
+6
-1
@@ -1614,6 +1614,7 @@ static void constructAutomaticIndex(
|
||||
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
|
||||
if( pLoop->prereq==0
|
||||
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
|
||||
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
|
||||
&& sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){
|
||||
pPartial = sqlite3ExprAnd(pParse->db, pPartial,
|
||||
sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
|
||||
@@ -4694,7 +4695,11 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
|
||||
int i;
|
||||
WhereTerm *pTerm;
|
||||
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
|
||||
if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab)
|
||||
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -49,4 +49,35 @@ do_execsql_test autoindex4-2.0 {
|
||||
ORDER BY rowid;
|
||||
} {1 123 654 | 0 555 444 | 4 234 987 |}
|
||||
|
||||
# Ticket [2326c258d02ead33d]
|
||||
# Two joins, one with and the other without an ORDER BY clause.
|
||||
# The one without ORDER BY correctly returns two rows of result.
|
||||
# The one with ORDER BY returns no rows.
|
||||
#
|
||||
do_execsql_test autoindex4-3.0 {
|
||||
CREATE TABLE A(Name text);
|
||||
CREATE TABLE Items(ItemName text , Name text);
|
||||
INSERT INTO Items VALUES('Item1','Parent');
|
||||
INSERT INTO Items VALUES('Item2','Parent');
|
||||
CREATE TABLE B(Name text);
|
||||
|
||||
SELECT Items.ItemName
|
||||
FROM Items
|
||||
LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy')
|
||||
LEFT JOIN B ON (B.Name = Items.ItemName)
|
||||
WHERE Items.Name = 'Parent'
|
||||
ORDER BY Items.ItemName;
|
||||
} {Item1 Item2}
|
||||
do_execsql_test autoindex4-3.1 {
|
||||
CREATE INDEX Items_x1 ON Items(ItemName,Name) WHERE ItemName = 'dummy';
|
||||
|
||||
SELECT Items.ItemName
|
||||
FROM Items
|
||||
LEFT JOIN A ON (A.Name = Items.ItemName and Items.ItemName = 'dummy')
|
||||
LEFT JOIN B ON (B.Name = Items.ItemName)
|
||||
WHERE Items.Name = 'Parent'
|
||||
ORDER BY Items.ItemName;
|
||||
} {Item1 Item2}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -267,5 +267,33 @@ do_execsql_test index6-6.2 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
# Test case for ticket [2326c258d02ead33d69faa63de8f4686b9b1b9d9] on
|
||||
# 2015-02-24. Any use of a partial index qualifying constraint inside
|
||||
# the ON clause of a LEFT JOIN was causing incorrect results for all
|
||||
# versions of SQLite 3.8.0 through 3.8.8.
|
||||
#
|
||||
do_execsql_test index6-7.0 {
|
||||
CREATE TABLE t7a(x);
|
||||
CREATE TABLE t7b(y);
|
||||
INSERT INTO t7a(x) VALUES(1);
|
||||
CREATE INDEX t7ax ON t7a(x) WHERE x=99;
|
||||
PRAGMA automatic_index=OFF;
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {}}
|
||||
do_execsql_test index6-7.1 {
|
||||
INSERT INTO t7b(y) VALUES(2);
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {}
|
||||
do_execsql_test index6-7.2 {
|
||||
INSERT INTO t7a(x) VALUES(99);
|
||||
SELECT * FROM t7a LEFT JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {1 {} 99 2}
|
||||
do_execsql_test index6-7.3 {
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {99 2}
|
||||
do_execsql_test index6-7.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t7a JOIN t7b ON (x=99) ORDER BY x;
|
||||
} {/USING COVERING INDEX t7ax/}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# 2015-01-19
|
||||
#
|
||||
# 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 file is testing ORDER BY and LIMIT on tables with
|
||||
# many columns.
|
||||
#
|
||||
# These tests verify that ticket [f97c4637102a3ae72b7911167e1d4da12ce60722]
|
||||
# from 2015-01-19 has been fixed.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix orderby8
|
||||
|
||||
do_test 1.0 {
|
||||
db eval {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES(1),(5),(9),(7),(3),(2),(4),(6),(8);
|
||||
}
|
||||
set ::result_set "x"
|
||||
} {x}
|
||||
for {set i 1} {$i<200} {incr i} {
|
||||
append ::result_set ", x+$i"
|
||||
do_test 1.$i {
|
||||
set res {}
|
||||
db eval "SELECT $::result_set FROM t1 ORDER BY x LIMIT -1" {
|
||||
lappend res $x
|
||||
}
|
||||
set res
|
||||
} {1 2 3 4 5 6 7 8 9}
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -390,6 +390,87 @@ foreach {testprefix do_wal_checkpoint} {
|
||||
} [wal_file_size 2 1024]
|
||||
|
||||
}
|
||||
|
||||
# Test that FULL, RESTART and TRUNCATE callbacks block on other clients
|
||||
# and truncate the wal file as required even if the entire wal file has
|
||||
# already been checkpointed when they are invoked.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
|
||||
code1 $do_wal_checkpoint
|
||||
code2 $do_wal_checkpoint
|
||||
code3 $do_wal_checkpoint
|
||||
|
||||
do_test 5.$tn.1 {
|
||||
sql1 {
|
||||
PRAGMA page_size = 1024;
|
||||
PRAGMA auto_vacuum = 0;
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA synchronous = normal;
|
||||
CREATE TABLE t1(x, y);
|
||||
CREATE INDEX i1 ON t1(x, y);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
}
|
||||
file size test.db-wal
|
||||
} [wal_file_size 10 1024]
|
||||
|
||||
do_test 5.$tn.2 {
|
||||
sql2 { BEGIN; SELECT * FROM t1 }
|
||||
} {1 2 3 4 5 6}
|
||||
|
||||
do_test 5.$tn.3 { do_wal_checkpoint db -mode passive } {0 10 10}
|
||||
|
||||
do_test 5.$tn.4 {
|
||||
sql3 { BEGIN; INSERT INTO t1 VALUES(7, 8); }
|
||||
} {}
|
||||
|
||||
do_test 5.$tn.5 { do_wal_checkpoint db -mode passive } {0 10 10}
|
||||
do_test 5.$tn.6 { do_wal_checkpoint db -mode full } {1 10 10}
|
||||
|
||||
do_test 5.$tn.7 { sql3 { ROLLBACK } } {}
|
||||
|
||||
do_test 5.$tn.8 { do_wal_checkpoint db -mode full } {0 10 10}
|
||||
do_test 5.$tn.9 { do_wal_checkpoint db -mode truncate } {1 10 10}
|
||||
|
||||
do_test 5.$tn.10 {
|
||||
file size test.db-wal
|
||||
} [wal_file_size 10 1024]
|
||||
|
||||
proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 }
|
||||
db busy xBusyHandler
|
||||
|
||||
do_test 5.$tn.11 { do_wal_checkpoint db -mode truncate } {0 0 0}
|
||||
do_test 5.$tn.12 { file size test.db-wal } 0
|
||||
|
||||
do_test 5.$tn.13 {
|
||||
sql1 {
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
|
||||
do_test 5.$tn.14 {
|
||||
sql2 { BEGIN; SELECT * FROM t1 }
|
||||
} {1 2 3 4 5 6 7 8 9 10}
|
||||
|
||||
proc xBusyHandler {n} { return 1 }
|
||||
do_test 5.$tn.14 { do_wal_checkpoint db -mode truncate } {1 4 4}
|
||||
do_test 5.$tn.15 { file size test.db-wal } [wal_file_size 4 1024]
|
||||
|
||||
do_test 5.$tn.16 { do_wal_checkpoint db -mode restart } {1 4 4}
|
||||
|
||||
proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 }
|
||||
db busy xBusyHandler
|
||||
do_test 5.$tn.17 { do_wal_checkpoint db -mode restart } {0 4 4}
|
||||
do_test 5.$tn.18 { file size test.db-wal } [wal_file_size 4 1024]
|
||||
|
||||
do_test 5.$tn.19 { do_wal_checkpoint db -mode truncate } {0 0 0}
|
||||
do_test 5.$tn.20 { file size test.db-wal } 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user