Merge the latest trunk changes into the wal-readonly branch.

FossilOrigin-Name: 2c6b5a28e3f6b7cb96b944d0a254f3707885f1ce
This commit is contained in:
drh 2011-05-31 17:08:32 +00:00
commit bdd0f3bc0e
41 changed files with 1241 additions and 271 deletions

View File

@ -378,7 +378,8 @@ TESTSRC = \
$(TOP)/src/test_thread.c \
$(TOP)/src/test_vfs.c \
$(TOP)/src/test_wholenumber.c \
$(TOP)/src/test_wsd.c
$(TOP)/src/test_wsd.c \
$(TOP)/ext/fts3/fts3_term.c
# Source code to the library files needed by the test fixture
#
@ -420,6 +421,7 @@ TESTSRC2 = \
$(TOP)/ext/fts3/fts3.c \
$(TOP)/ext/fts3/fts3_aux.c \
$(TOP)/ext/fts3/fts3_expr.c \
$(TOP)/ext/fts3/fts3_term.c \
$(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/fts3/fts3_write.c \
$(TOP)/ext/async/sqlite3async.c
@ -828,12 +830,12 @@ fts3_hash.lo: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
fts3_icu.lo: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
fts3_snippet.lo: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c
fts3_porter.lo: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
fts3_snippet.lo: $(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c
fts3_tokenizer.lo: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c

View File

@ -977,6 +977,8 @@ static int fts3InitVtab(
p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
p->bHasDocsize = (isFts4 && bNoDocsize==0);
p->bHasStat = isFts4;
TESTONLY( p->inTransaction = -1 );
TESTONLY( p->mxSavepoint = -1 );
fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1);
/* Fill in the zName and zDb fields of the vtab structure. */
@ -1195,7 +1197,7 @@ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
** table is missing a row that is present in the full-text index.
** The data structures are corrupt.
*/
rc = SQLITE_CORRUPT;
rc = SQLITE_CORRUPT_VTAB;
}
pCsr->isEof = 1;
if( pContext ){
@ -1255,7 +1257,7 @@ static int fts3ScanInteriorNode(
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
if( zCsr>zEnd ){
return SQLITE_CORRUPT;
return SQLITE_CORRUPT_VTAB;
}
while( zCsr<zEnd && (piFirst || piLast) ){
@ -1273,7 +1275,7 @@ static int fts3ScanInteriorNode(
zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
rc = SQLITE_CORRUPT;
rc = SQLITE_CORRUPT_VTAB;
goto finish_scan;
}
if( nPrefix+nSuffix>nAlloc ){
@ -3274,7 +3276,11 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
*/
static int fts3BeginMethod(sqlite3_vtab *pVtab){
UNUSED_PARAMETER(pVtab);
assert( ((Fts3Table *)pVtab)->nPendingData==0 );
TESTONLY( Fts3Table *p = (Fts3Table*)pVtab );
assert( p->nPendingData==0 );
assert( p->inTransaction!=1 );
TESTONLY( p->inTransaction = 1 );
TESTONLY( p->mxSavepoint = -1; );
return SQLITE_OK;
}
@ -3285,7 +3291,11 @@ static int fts3BeginMethod(sqlite3_vtab *pVtab){
*/
static int fts3CommitMethod(sqlite3_vtab *pVtab){
UNUSED_PARAMETER(pVtab);
assert( ((Fts3Table *)pVtab)->nPendingData==0 );
TESTONLY( Fts3Table *p = (Fts3Table*)pVtab );
assert( p->nPendingData==0 );
assert( p->inTransaction!=0 );
TESTONLY( p->inTransaction = 0 );
TESTONLY( p->mxSavepoint = -1; );
return SQLITE_OK;
}
@ -3294,7 +3304,11 @@ static int fts3CommitMethod(sqlite3_vtab *pVtab){
** hash-table. Any changes made to the database are reverted by SQLite.
*/
static int fts3RollbackMethod(sqlite3_vtab *pVtab){
sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab);
Fts3Table *p = (Fts3Table*)pVtab;
sqlite3Fts3PendingTermsClear(p);
assert( p->inTransaction!=0 );
TESTONLY( p->inTransaction = 0 );
TESTONLY( p->mxSavepoint = -1; );
return SQLITE_OK;
}
@ -3650,13 +3664,29 @@ static int fts3RenameMethod(
}
static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
return sqlite3Fts3PendingTermsFlush((Fts3Table *)pVtab);
Fts3Table *p = (Fts3Table*)pVtab;
UNUSED_PARAMETER(iSavepoint);
assert( p->inTransaction );
assert( p->mxSavepoint < iSavepoint );
TESTONLY( p->mxSavepoint = iSavepoint );
return sqlite3Fts3PendingTermsFlush(p);
}
static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
TESTONLY( Fts3Table *p = (Fts3Table*)pVtab );
UNUSED_PARAMETER(iSavepoint);
UNUSED_PARAMETER(pVtab);
assert( p->inTransaction );
assert( p->mxSavepoint >= iSavepoint );
TESTONLY( p->mxSavepoint = iSavepoint-1 );
return SQLITE_OK;
}
static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab);
Fts3Table *p = (Fts3Table*)pVtab;
UNUSED_PARAMETER(iSavepoint);
assert( p->inTransaction );
assert( p->mxSavepoint >= iSavepoint );
TESTONLY( p->mxSavepoint = iSavepoint );
sqlite3Fts3PendingTermsClear(p);
return SQLITE_OK;
}

View File

@ -92,12 +92,32 @@ typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */
typedef short int i16; /* 2-byte (or larger) signed integer */
typedef unsigned int u32; /* 4-byte unsigned integer */
typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */
/*
** Macro used to suppress compiler warnings for unused parameters.
*/
#define UNUSED_PARAMETER(x) (void)(x)
/*
** Activate assert() only if SQLITE_TEST is enabled.
*/
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
/*
** The TESTONLY macro is used to enclose variable declarations or
** other bits of code that are needed to support the arguments
** within testcase() and assert() macros.
*/
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
# define TESTONLY(X) X
#else
# define TESTONLY(X)
#endif
#endif /* SQLITE_AMALGAMATION */
typedef struct Fts3Table Fts3Table;
typedef struct Fts3Cursor Fts3Cursor;
typedef struct Fts3Expr Fts3Expr;
@ -151,6 +171,16 @@ struct Fts3Table {
int nPendingData;
sqlite_int64 iPrevDocid;
Fts3Hash pendingTerms;
#if defined(SQLITE_DEBUG)
/* State variables used for validating that the transaction control
** methods of the virtual table are called at appropriate times. These
** values do not contribution to the FTS computation; they are used for
** verifying the SQLite core.
*/
int inTransaction; /* True after xBegin but before xCommit/xRollback */
int mxSavepoint; /* Largest valid xSavepoint integer */
#endif
};
/*
@ -381,6 +411,7 @@ int sqlite3Fts3ExprParse(sqlite3_tokenizer *,
void sqlite3Fts3ExprFree(Fts3Expr *);
#ifdef SQLITE_TEST
int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
int sqlite3Fts3InitTerm(sqlite3 *db);
#endif
/* fts3_aux.c */

View File

@ -342,6 +342,7 @@ static int fts3auxFilterMethod(
int isScan;
UNUSED_PARAMETER(nVal);
UNUSED_PARAMETER(idxStr);
assert( idxStr==0 );
assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0
@ -459,7 +460,10 @@ int sqlite3Fts3InitAux(sqlite3 *db){
0, /* xCommit */
0, /* xRollback */
0, /* xFindFunction */
0 /* xRename */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
};
int rc; /* Return code */

View File

@ -960,7 +960,7 @@ static int fts3MatchinfoSelectDoctotal(
a = sqlite3_column_blob(pStmt, 0);
a += sqlite3Fts3GetVarint(a, &nDoc);
if( nDoc==0 ) return SQLITE_CORRUPT;
if( nDoc==0 ) return SQLITE_CORRUPT_VTAB;
*pnDoc = (u32)nDoc;
if( paLen ) *paLen = a;
@ -1555,7 +1555,7 @@ void sqlite3Fts3Offsets(
);
rc = fts3StringAppend(&res, aBuffer, -1);
}else if( rc==SQLITE_DONE ){
rc = SQLITE_CORRUPT;
rc = SQLITE_CORRUPT_VTAB;
}
}
}

View File

@ -291,7 +291,7 @@ static int fts3SelectDocsize(
rc = sqlite3_step(pStmt);
if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
rc = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT;
if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT_VTAB;
pStmt = 0;
}else{
rc = SQLITE_OK;
@ -972,7 +972,7 @@ static int fts3SegReaderNext(Fts3Table *p, Fts3SegReader *pReader){
if( nPrefix<0 || nSuffix<=0
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
){
return SQLITE_CORRUPT;
return SQLITE_CORRUPT_VTAB;
}
if( nPrefix+nSuffix>pReader->nTermAlloc ){
@ -998,7 +998,7 @@ static int fts3SegReaderNext(Fts3Table *p, Fts3SegReader *pReader){
if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
|| pReader->aDoclist[pReader->nDoclist-1]
){
return SQLITE_CORRUPT;
return SQLITE_CORRUPT_VTAB;
}
return SQLITE_OK;
}
@ -1123,7 +1123,7 @@ int sqlite3Fts3SegReaderCost(
}
if( nDoc==0 || nByte==0 ){
sqlite3_reset(pStmt);
return SQLITE_CORRUPT;
return SQLITE_CORRUPT_VTAB;
}
pCsr->nRowAvg = (int)(((nByte / nDoc) + pgsz) / pgsz);
@ -2762,7 +2762,7 @@ int sqlite3Fts3UpdateMethod(
if( nArg>1 && rc==SQLITE_OK ){
if( bInsertDone==0 ){
rc = fts3InsertData(p, apVal, pRowid);
if( rc==SQLITE_CONSTRAINT ) rc = SQLITE_CORRUPT;
if( rc==SQLITE_CONSTRAINT ) rc = SQLITE_CORRUPT_VTAB;
}
if( rc==SQLITE_OK && (!isRemove || *pRowid!=iRemove) ){
rc = fts3PendingTermsDocid(p, *pRowid);

View File

@ -517,17 +517,17 @@ nodeAcquire(
if( pNode && iNode==1 ){
pRtree->iDepth = readInt16(pNode->zData);
if( pRtree->iDepth>RTREE_MAX_DEPTH ){
rc = SQLITE_CORRUPT;
rc = SQLITE_CORRUPT_VTAB;
}
}
/* If no error has occurred so far, check if the "number of entries"
** field on the node is too large. If so, set the return code to
** SQLITE_CORRUPT.
** SQLITE_CORRUPT_VTAB.
*/
if( pNode && rc==SQLITE_OK ){
if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
rc = SQLITE_CORRUPT;
rc = SQLITE_CORRUPT_VTAB;
}
}
@ -535,7 +535,7 @@ nodeAcquire(
if( pNode!=0 ){
nodeHashInsert(pRtree, pNode);
}else{
rc = SQLITE_CORRUPT;
rc = SQLITE_CORRUPT_VTAB;
}
*ppNode = pNode;
}else{
@ -1062,7 +1062,7 @@ static int nodeRowidIndex(
return SQLITE_OK;
}
}
return SQLITE_CORRUPT;
return SQLITE_CORRUPT_VTAB;
}
/*
@ -1657,7 +1657,7 @@ static int AdjustTree(
int iCell;
if( nodeParentIndex(pRtree, p, &iCell) ){
return SQLITE_CORRUPT;
return SQLITE_CORRUPT_VTAB;
}
nodeGetCell(pRtree, pParent, iCell, &cell);
@ -2329,7 +2329,7 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
}
rc = sqlite3_reset(pRtree->pReadParent);
if( rc==SQLITE_OK ) rc = rc2;
if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT;
if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB;
pChild = pChild->pParent;
}
return rc;
@ -2849,7 +2849,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
}
static sqlite3_module rtreeModule = {
0, /* iVersion */
0, /* iVersion */
rtreeCreate, /* xCreate - create a table */
rtreeConnect, /* xConnect - connect to an existing table */
rtreeBestIndex, /* xBestIndex - Determine search strategy */
@ -2868,7 +2868,10 @@ static sqlite3_module rtreeModule = {
0, /* xCommit - commit transaction */
0, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
rtreeRename /* xRename - rename the table */
rtreeRename, /* xRename - rename the table */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
};
static int rtreeSqlInit(

View File

@ -54,8 +54,8 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \
backup.o bitvec.o btmutex.o btree.o build.o \
callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o fts3_write.o \
func.o global.o hash.o \
fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
fts3_write.o func.o global.o hash.o \
icu.o insert.o journal.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memjournal.o \

View File

@ -1,7 +1,7 @@
C Add\smissing\scomments\sassociated\swith\sreadonly\sshm\schanges.
D 2011-05-11T17:36:17.276
C Merge\sthe\slatest\strunk\schanges\sinto\sthe\swal-readonly\sbranch.
D 2011-05-31T17:08:32.975
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
@ -61,28 +61,28 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 0077bd07395d2aabafa1ed1b104552619ecad34a
F ext/fts3/fts3.c b3a10a1a320aaeb56a1dd6710bf09eb5c2370839
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 8c2ac39ee17362571c58ab2c4f0667324c31f738
F ext/fts3/fts3_aux.c 9e931f55eed8498dafe7bc1160f10cbb1a652fdf
F ext/fts3/fts3Int.h c8c0011c5e5b3a7703376ea6cd7deb91cfb96a06
F ext/fts3/fts3_aux.c 97c960b1b0d371c08eae6b8565dfac619eb9d979
F ext/fts3/fts3_expr.c 5f49e0deaf723724b08100bb3ff40aab02ad0c93
F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c
F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec
F ext/fts3/fts3_icu.c ac494aed69835008185299315403044664bda295
F ext/fts3/fts3_porter.c d61cfd81fb0fd8fbcb25adcaee0ba671aefaa5c2
F ext/fts3/fts3_snippet.c a4a3c7d2ab15ca9188e2d9b51a5e3927bf76580d
F ext/fts3/fts3_snippet.c 92b40397b28422c35c4127492d7ac6da34d1966a
F ext/fts3/fts3_term.c f115f5a5f4298303d3b22fc6c524b8d565c7b950
F ext/fts3/fts3_tokenizer.c 055f3dc7369585350b28db1ee0f3b214dca6724d
F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d
F ext/fts3/fts3_write.c 7d6d904b89333448eb968fc82470a74985d0b61e
F ext/fts3/fts3_write.c b50181e5ecf484c2f56e98d651424e4b69f96c89
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 829c6901a2b065ff93a68d431f9eaba8de7128e0
F ext/rtree/rtree.c 4b8438444927191b55de18e00df43b2e02aacbda
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test 28e1b8da4da98093ce3210187434dd760a8d89d8
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@ -102,7 +102,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk 496cec8b7890e39127532294e28e5e1d1b1beae1
F main.mk 6111163d4e9720e4212ef288e967b4aa2c2ce379
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
@ -122,7 +122,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 26f8a9d6169413c5682b89b5397d20437b653154
F src/btree.c 0d3b39dcb79565c053e35fc12713f12d8a74d6a9
F src/btree.h d796dc4030b3cce7f5a0cc4f2f986d2befa6b8ac
F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3
F src/build.c 0132bc6631fa617a1d28ef805921f6dbac18a514
@ -130,7 +130,7 @@ F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4
F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b
F src/delete.c 7a24fcc9a31664d145acb97ce56b6d9f249a25e4
F src/delete.c cecc926c70783452f3e8eb452c728291ce1a0b21
F src/expr.c e3cf0957c6b8faaaf7386a3bc69e53c0dc9705be
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c a43ba8a005fb5efd1deeee06853e3a6120d46a91
@ -144,7 +144,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
F src/main.c a145cea130adfe945ab1fa7e9543c492e3f2f419
F src/main.c 4e55ff4800181e3ad063492740f54ce406de5deb
F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
@ -163,30 +163,30 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
F src/os_unix.c 03630dd062c3d1fb9f25e2a227048b709c5babff
F src/os_win.c ff0e14615a5086fa5ba6926e4ec0dc9cfb5a1a84
F src/pager.c 4056376f83f85cea9922a11161087c529e39f7dc
F src/os_unix.c af3c3f6a0fc6dbde802e55848f1cad7fb2121ff3
F src/os_win.c 218b899469e570d46eb8147c2383075f7c026230
F src/pager.c 2cf3bad86e6fbac42d9dbd3b89799185a343b17b
F src/pager.h 34c6b029446f06f40847746d22faac0d354dd909
F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa
F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e
F src/pragma.c 49c90ab27a4339d4b5bc0b03c08cbcf20ed8d454
F src/pragma.c 9e778decc3ee9bcaf88904b4a3b0a4360aaf0eab
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff
F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79
F src/sqlite.h.in adeb2c8019a3851a10e3872f44b34c95c6e409f2
F src/shell.c decd04236a7ef26be5ef46d4ea963044bfad9a48
F src/sqlite.h.in 55fe75ae0d2ee71c33283bae647443c8ec8400be
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
F src/sqliteInt.h 798fb09648cefc159ac9b3ce5e00f5ada1377ed1
F src/sqliteInt.h 8936583efbbc5820e9b01befa6e76947a2be8f52
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 501c9a200fd998a268be475be5858febc90b725b
F src/test1.c 6ae026cd9d2b1b1e95a372a7460d091705db645d
F src/test1.c efca486a25fb894988e7a82e84579a4e57388a02
F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432
F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
@ -199,8 +199,8 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
F src/test_config.c d536042f27226b4639f0f87d4795fd37428a9ddf
F src/test_demovfs.c 938d0f595f8bd310076e1c06cf7885a01ce7ce01
F src/test_config.c 9a6aa8301a56906612b5e70f5b38e80cfb8af8e7
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254
@ -208,10 +208,10 @@ F src/test_hexio.c c4773049603151704a6ab25ac5e936b5109caf5a
F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
F src/test_journal.c 785edd54f963aefb3c1628124170a56697c68c70
F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c 7ca7be34e0e09ef0ed6619544552ed95732e41f6
F src/test_multiplex.c fdabd793ee7a9642c5a8a470def2347144c46d05
F src/test_multiplex.c a7457a1ac46964b7f897d75ecfd447410ec067e6
F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
@ -226,29 +226,30 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c 162c4ec0137a549c009bb9ecab550527743cfc5d
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c 361ae0a0f1cbf5a28ad0388a258b104017a370c0
F src/test_vfs.c 0ac5b2e3da61bc385c1017890687c359746be2fd
F src/test_vfstrace.c 2265c9895f350c8d3c39b079998fbe7481505cc1
F src/test_vfs.c e7855568dfa1e0ba73668d273b65605d9f8b77e8
F src/test_vfstrace.c 0b884e06094a746da729119a2cabdc7aa790063d
F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8
F src/update.c 5bcb56e5c7380a2eecb0e71891dbd4ad7437748f
F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60
F src/util.c 914e860d21496b19a912cd14f6f7a889a22f44e1
F src/util.c 0f33bbbdfcc4a2d8cf20c3b2a16ffc3b57c58a70
F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e
F src/vdbe.c b2070c926a896e59234e27412a45e261fe752235
F src/vdbe.c 103827f560cdc48b1d455ce4d4b3573dd88f9ab4
F src/vdbe.h 8a675fefdf7119441fe817c800a9a52440c2e797
F src/vdbeInt.h fe8f58d305e629fff02f61f655aca1d299f1f6ae
F src/vdbeapi.c e0e2672e0a96ae3f8575c8ecd02912a3e8a554a1
F src/vdbeaux.c 25aa5ba7d46b4fe7c8f33dc132d474242d5f9726
F src/vdbeaux.c 99900868d18618a07ffaf780ecc41fd807834bde
F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562
F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
F src/vtab.c 48dcef8bc757c2e7b488f68b5ddebb1650da2450
F src/wal.c 6d8ee757f62bca9b0b713724677878dff5bf7e79
F src/wal.h c1e05cdf3d42ed7c9263739ca8f5cdd8761e7de3
F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336
F src/wal.c 861ea98779dac3867e5f97d13e61cbbb39b310b0
F src/wal.h 0835021ae243c2f1119e997e8af5d8cc3b991de1
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5
F test/8_3_names.test b93687beebd17f6ebf812405a6833bae5d1f4199
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125
@ -379,7 +380,7 @@ F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test bf385ae3aa0f014c4933ae66fd3e1302138493eb
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
F test/e_update.test 963d6876064e65f318d1c93aaed36a02b9b389bf
F test/e_uri.test 9ce11319fb9b271bf7392027f913f7830e93e7a7
F test/e_uri.test b6da43a10f44d9aa0aff5ffa3c2f3de668361255
F test/e_vacuum.test 6c09c2af7f2f140518f371c5342100118f779dcf
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
@ -458,7 +459,7 @@ F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
F test/fts3conf.test 8e65ea56f88ced6cdd2252bdddb1a8327ae5af7e
F test/fts3corrupt.test 7890cc202406858386ddf390a879dcf80bc10abf
F test/fts3corrupt.test 7b0f91780ca36118d73324ec803187208ad33b32
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
F test/fts3d.test 95fb3c862cbc4297c93fceb9a635543744e9ef52
@ -589,7 +590,7 @@ F test/misc5.test 45b2e3ed5f79af2b4f38ae362eaf4c49674575bd
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test 29032efcd3d826fbd409e2a7af873e7939f4a4e3
F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
F test/multiplex.test a88f3e2c16e567e72be7296195c59fbdd6a8d3d4
F test/multiplex.test 7a8a50c8ed72dfcf4db9ebae977f7a63184639d8
F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
F test/nan.test dc212a22b36109fd1ae37154292444ef249c5ec2
@ -704,6 +705,7 @@ F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
F test/threadtest3.c 0ed13e09690f6204d7455fac3b0e8ece490f6eef
F test/tkt-02a8e81d44.test 58494de77be2cf249228ada3f313fa399821c6ab
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
F test/tkt-2d1a5c67d.test 73574c758502bf23260c17f97fcd9316dfb5a060
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
F test/tkt-31338dca7e.test 5741cd48de500347a437ba1be58c8335e83c5a5e
F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac
@ -841,7 +843,7 @@ F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e
F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced
F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
F test/uri.test 2d08a6f77bf93ca925743a65802c4aa23aaaf373
F test/uri.test 53de9a2549cbda9c343223236918ef502f6a9051
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test 29b60e8cc9e573b39676df6c4a75fe9e02d04a09
F test/vacuum2.test 91a84c9b08adfc4472097d2e8deb0150214e0e76
@ -873,6 +875,7 @@ F test/wal3.test 5c396cc22497244d627306f4c1d360167353f8dd
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
F test/wal5.test 1bbfaa316dc2a1d0d1fac3f4500c38a90055a41b
F test/wal6.test 07aa31ca8892d0527f2c5c5a9a2a87aa421dfaa8
F test/wal7.test 09bc8de3d11949571d6f7a4188b308059cec27e5
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4
F test/walbig.test e882bc1d014afffbfa2b6ba36e0f07d30a633ad0
@ -936,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P cde45a033ee6834900f5f5c272c383408883a74c
R 77f3671cb0a1ec2771484489a2a100be
U dan
Z 826df29e354d14eb64673fd89c39c62e
P 6a2ea52e6c09a570428161090c2f087c66f714ec a0ae314c7f41d0146a9ee1adc576cd977219a378
R 2d882c761e53216861edc4b651b9e13f
U drh
Z 136bd350bac5191ea5a92cebd8db2492

View File

@ -1 +1 @@
6a2ea52e6c09a570428161090c2f087c66f714ec
2c6b5a28e3f6b7cb96b944d0a254f3707885f1ce

View File

@ -788,6 +788,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
*pRC = SQLITE_CORRUPT_BKPT;
goto ptrmap_exit;
}
assert( offset <= (int)pBt->usableSize-5 );
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
@ -827,6 +828,11 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
offset = PTRMAP_PTROFFSET(iPtrmap, key);
if( offset<0 ){
sqlite3PagerUnref(pDbPage);
return SQLITE_CORRUPT_BKPT;
}
assert( offset <= (int)pBt->usableSize-5 );
assert( pEType!=0 );
*pEType = pPtrmap[offset];
if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
@ -5384,10 +5390,10 @@ static int fillInCell(
** "sz" must be the number of bytes in the cell.
*/
static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
int i; /* Loop counter */
u32 pc; /* Offset to cell content of cell being deleted */
u8 *data; /* pPage->aData */
u8 *ptr; /* Used to move bytes around within data[] */
u8 *endPtr; /* End of loop */
int rc; /* The return code */
int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
@ -5412,9 +5418,11 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
*pRC = rc;
return;
}
for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2];
while( ptr<endPtr ){
ptr[0] = ptr[2];
ptr[1] = ptr[3];
ptr += 2;
}
pPage->nCell--;
put2byte(&data[hdr+3], pPage->nCell);

View File

@ -401,6 +401,7 @@ void sqlite3DeleteFrom(
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
sqlite3VtabMakeWritable(pParse, pTab);
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, OE_Abort);
sqlite3MayAbort(pParse);
}else
#endif

View File

@ -2922,3 +2922,25 @@ int sqlite3_test_control(int op, ...){
#endif /* SQLITE_OMIT_BUILTIN_TEST */
return rc;
}
/*
** This is a utility routine, useful to VFS implementations, that checks
** to see if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of the query parameter.
**
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation. The zParam argument is the name of the
** query parameter we seek. This routine returns the value of the zParam
** parameter if it exists. If the parameter does not exist, this routine
** returns a NULL pointer.
*/
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] ){
int x = strcmp(zFilename, zParam);
zFilename += sqlite3Strlen30(zFilename) + 1;
if( x==0 ) return zFilename;
zFilename += sqlite3Strlen30(zFilename) + 1;
}
return 0;
}

View File

@ -3775,6 +3775,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
#endif
pShmNode->h = -1;
pDbFd->pInode->pShmNode = pShmNode;
@ -4827,6 +4828,11 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
** corresponding database file and sets *pMode to this value. Whenever
** possible, WAL and journal files are created using the same permissions
** as the associated database file.
**
** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
** original filename is unavailable. But 8_3_NAMES is only used for
** FAT filesystems and permissions do not matter there, so just use
** the default permissions.
*/
static int findCreateFileMode(
const char *zPath, /* Path of file (possibly) being created */
@ -4834,6 +4840,7 @@ static int findCreateFileMode(
mode_t *pMode /* OUT: Permissions to open file with */
){
int rc = SQLITE_OK; /* Return Code */
*pMode = SQLITE_DEFAULT_FILE_PERMISSIONS;
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
char zDb[MAX_PATHNAME+1]; /* Database file path */
int nDb; /* Number of valid bytes in zDb */
@ -4845,15 +4852,15 @@ static int findCreateFileMode(
**
** "<path to db>-journal"
** "<path to db>-wal"
** "<path to db>-journal-NNNN"
** "<path to db>-wal-NNNN"
** "<path to db>-journalNN"
** "<path to db>-walNN"
**
** where NNNN is a 4 digit decimal number. The NNNN naming schemes are
** where NN is a 4 digit decimal number. The NN naming schemes are
** used by the test_multiplex.c module.
*/
nDb = sqlite3Strlen30(zPath) - 1;
while( nDb>0 && zPath[nDb]!='l' ) nDb--;
nDb -= ((flags & SQLITE_OPEN_WAL) ? 3 : 7);
while( nDb>0 && zPath[nDb]!='-' ) nDb--;
if( nDb==0 ) return SQLITE_OK;
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
@ -4864,8 +4871,6 @@ static int findCreateFileMode(
}
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
*pMode = 0600;
}else{
*pMode = SQLITE_DEFAULT_FILE_PERMISSIONS;
}
return rc;
}

View File

@ -1570,6 +1570,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
memset(pNew, 0, sizeof(*pNew));
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
/* Look to see if there is an existing winShmNode that can be used.
** If no matching winShmNode currently exists, create a new one.

View File

@ -4407,10 +4407,12 @@ int sqlite3PagerOpen(
memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
memcpy(pPager->zJournal, zPathname, nPathname);
memcpy(&pPager->zJournal[nPathname], "-journal", 8);
sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
pPager->zWal = &pPager->zJournal[nPathname+8+1];
memcpy(pPager->zWal, zPathname, nPathname);
memcpy(&pPager->zWal[nPathname], "-wal", 4);
sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
#endif
sqlite3_free(zPathname);
}
@ -5748,11 +5750,21 @@ int sqlite3PagerCommitPhaseOne(
}else{
if( pagerUseWal(pPager) ){
PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
if( pList ){
PgHdr *pPageOne = 0;
if( pList==0 ){
/* Must have at least one page for the WAL commit flag.
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
rc = sqlite3PagerGet(pPager, 1, &pPageOne);
pList = pPageOne;
pList->pDirty = 0;
}
assert( rc==SQLITE_OK );
if( ALWAYS(pList) ){
rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1,
(pPager->fullSync ? pPager->syncFlags : 0)
);
}
sqlite3PagerUnref(pPageOne);
if( rc==SQLITE_OK ){
sqlite3PcacheCleanAll(pPager->pPCache);
}
@ -6610,6 +6622,7 @@ int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
if( iLimit>=-1 ){
pPager->journalSizeLimit = iLimit;
sqlite3WalLimit(pPager->pWal, iLimit);
}
return pPager->journalSizeLimit;
}
@ -6701,7 +6714,8 @@ static int pagerOpenWal(Pager *pPager){
*/
if( rc==SQLITE_OK ){
rc = sqlite3WalOpen(pPager->pVfs,
pPager->fd, pPager->zWal, pPager->exclusiveMode, &pPager->pWal
pPager->fd, pPager->zWal, pPager->exclusiveMode,
pPager->journalSizeLimit, &pPager->pWal
);
}

View File

@ -253,6 +253,13 @@ int sqlite3PcacheFetch(
}
if( pPg ){
int rc;
#ifdef SQLITE_LOG_CACHE_SPILL
sqlite3_log(SQLITE_FULL,
"spill page %d making room for %d - cache used: %d/%d",
pPg->pgno, pgno,
sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
pCache->nMax);
#endif
rc = pCache->xStress(pCache->pStress, pPg);
if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
return rc;

View File

@ -49,7 +49,7 @@ static u8 getSafetyLevel(const char *z){
/*
** Interpret the given string as a boolean value.
*/
static u8 getBoolean(const char *z){
u8 sqlite3GetBoolean(const char *z){
return getSafetyLevel(z)&1;
}
@ -219,7 +219,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
mask &= ~(SQLITE_ForeignKeys);
}
if( getBoolean(zRight) ){
if( sqlite3GetBoolean(zRight) ){
db->flags |= mask;
}else{
db->flags &= ~mask;
@ -433,7 +433,7 @@ void sqlite3Pragma(
int b = -1;
assert( pBt!=0 );
if( zRight ){
b = getBoolean(zRight);
b = sqlite3GetBoolean(zRight);
}
if( pId2->n==0 && b>=0 ){
int ii;
@ -1033,7 +1033,7 @@ void sqlite3Pragma(
#ifndef NDEBUG
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
if( zRight ){
if( getBoolean(zRight) ){
if( sqlite3GetBoolean(zRight) ){
sqlite3ParserTrace(stderr, "parser: ");
}else{
sqlite3ParserTrace(0, 0);
@ -1047,7 +1047,7 @@ void sqlite3Pragma(
*/
if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
if( zRight ){
sqlite3RegisterLikeFunctions(db, getBoolean(zRight));
sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight));
}
}else

View File

@ -2649,6 +2649,7 @@ static void main_init(struct callback_data *data) {
data->mode = MODE_List;
memcpy(data->separator,"|", 2);
data->showHeader = 0;
sqlite3_config(SQLITE_CONFIG_URI, 1);
sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
@ -2663,6 +2664,11 @@ int main(int argc, char **argv){
int i;
int rc = 0;
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1);
}
Argv0 = argv[0];
main_init(&data);
stdin_is_interactive = isatty(0);

View File

@ -453,6 +453,7 @@ int sqlite3_exec(
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@ -462,8 +463,7 @@ int sqlite3_exec(
**
** These bit values are intended for use in the
** 3rd parameter to the [sqlite3_open_v2()] interface and
** in the 4th parameter to the xOpen method of the
** [sqlite3_vfs] object.
** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
*/
#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
@ -471,6 +471,7 @@ int sqlite3_exec(
#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */
#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
@ -483,7 +484,6 @@ int sqlite3_exec(
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
#define SQLITE_OPEN_URI 0x00100000 /* Ok for sqlite3_open_v2() */
/* Reserved: 0x00F00000 */
@ -582,17 +582,18 @@ struct sqlite3_file {
/*
** CAPI3REF: OS Interface File Virtual Methods Object
**
** Every file opened by the [sqlite3_vfs] xOpen method populates an
** Every file opened by the [sqlite3_vfs.xOpen] method populates an
** [sqlite3_file] object (or, more commonly, a subclass of the
** [sqlite3_file] object) with a pointer to an instance of this object.
** This object defines the methods used to perform various operations
** against the open file represented by the [sqlite3_file] object.
**
** If the xOpen method sets the sqlite3_file.pMethods element
** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element
** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
** may be invoked even if the xOpen reported that it failed. The
** only way to prevent a call to xClose following a failed xOpen
** is for the xOpen to set the sqlite3_file.pMethods element to NULL.
** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The
** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen]
** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element
** to NULL.
**
** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
** [SQLITE_SYNC_FULL]. The first choice is the normal fsync().
@ -783,11 +784,11 @@ typedef struct sqlite3_mutex sqlite3_mutex;
/*
** CAPI3REF: OS Interface Object
** KEYWORDS: VFS VFSes
**
** An instance of the sqlite3_vfs object defines the interface between
** the SQLite core and the underlying operating system. The "vfs"
** in the name of the object stands for "virtual file system".
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
** The value of the iVersion field is initially 1 but may be larger in
** future versions of SQLite. Additional fields may be appended to this
@ -816,6 +817,7 @@ typedef struct sqlite3_mutex sqlite3_mutex;
** The zName field holds the name of the VFS module. The name must
** be unique across all VFS modules.
**
** [[sqlite3_vfs.xOpen]]
** ^SQLite guarantees that the zFilename parameter to xOpen
** is either a NULL pointer or string obtained
** from xFullPathname() with an optional suffix added.
@ -893,6 +895,7 @@ typedef struct sqlite3_mutex sqlite3_mutex;
** element will be valid after xOpen returns regardless of the success
** or failure of the xOpen call.
**
** [[sqlite3_vfs.xAccess]]
** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
@ -1139,9 +1142,9 @@ int sqlite3_os_end(void);
** implementation of an application-defined [sqlite3_os_init()].
**
** The first argument to sqlite3_config() is an integer
** [SQLITE_CONFIG_SINGLETHREAD | configuration option] that determines
** [configuration option] that determines
** what property of SQLite is to be configured. Subsequent arguments
** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | configuration option]
** vary depending on the [configuration option]
** in the first argument.
**
** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
@ -1251,6 +1254,7 @@ struct sqlite3_mem_methods {
/*
** CAPI3REF: Configuration Options
** KEYWORDS: {configuration option}
**
** These constants are the available integer configuration options that
** can be passed as the first argument to the [sqlite3_config()] interface.
@ -1263,7 +1267,7 @@ struct sqlite3_mem_methods {
** is invoked.
**
** <dl>
** <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
** [[SQLITE_CONFIG_SINGLETHREAD]] <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
** <dd>There are no arguments to this option. ^This option sets the
** [threading mode] to Single-thread. In other words, it disables
** all mutexing and puts SQLite into a mode where it can only be used
@ -1274,7 +1278,7 @@ struct sqlite3_mem_methods {
** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD
** configuration option.</dd>
**
** <dt>SQLITE_CONFIG_MULTITHREAD</dt>
** [[SQLITE_CONFIG_MULTITHREAD]] <dt>SQLITE_CONFIG_MULTITHREAD</dt>
** <dd>There are no arguments to this option. ^This option sets the
** [threading mode] to Multi-thread. In other words, it disables
** mutexing on [database connection] and [prepared statement] objects.
@ -1288,7 +1292,7 @@ struct sqlite3_mem_methods {
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_MULTITHREAD configuration option.</dd>
**
** <dt>SQLITE_CONFIG_SERIALIZED</dt>
** [[SQLITE_CONFIG_SERIALIZED]] <dt>SQLITE_CONFIG_SERIALIZED</dt>
** <dd>There are no arguments to this option. ^This option sets the
** [threading mode] to Serialized. In other words, this option enables
** all mutexes including the recursive
@ -1304,7 +1308,7 @@ struct sqlite3_mem_methods {
** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
**
** <dt>SQLITE_CONFIG_MALLOC</dt>
** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure. The argument specifies
** alternative low-level memory allocation routines to be used in place of
@ -1312,7 +1316,7 @@ struct sqlite3_mem_methods {
** its own private copy of the content of the [sqlite3_mem_methods] structure
** before the [sqlite3_config()] call returns.</dd>
**
** <dt>SQLITE_CONFIG_GETMALLOC</dt>
** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods]
** structure is filled with the currently defined memory allocation routines.)^
@ -1320,7 +1324,7 @@ struct sqlite3_mem_methods {
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^This option takes single argument of type int, interpreted as a
** boolean, which enables or disables the collection of memory allocation
** statistics. ^(When memory allocation statistics are disabled, the
@ -1336,7 +1340,7 @@ struct sqlite3_mem_methods {
** allocation statistics are disabled by default.
** </dd>
**
** <dt>SQLITE_CONFIG_SCRATCH</dt>
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** scratch memory. There are three arguments: A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
@ -1352,7 +1356,7 @@ struct sqlite3_mem_methods {
** scratch memory beyond what is provided by this configuration option, then
** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
**
** <dt>SQLITE_CONFIG_PAGECACHE</dt>
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^This option specifies a static memory buffer that SQLite can use for
** the database page cache with the default page cache implemenation.
** This configuration should not be used if an application-define page
@ -1373,7 +1377,7 @@ struct sqlite3_mem_methods {
** be aligned to an 8-byte boundary or subsequent behavior of SQLite
** will be undefined.</dd>
**
** <dt>SQLITE_CONFIG_HEAP</dt>
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^This option specifies a static memory buffer that SQLite will use
** for all of its dynamic memory allocation needs beyond those provided
** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
@ -1390,7 +1394,7 @@ struct sqlite3_mem_methods {
** The minimum allocation size is capped at 2^12. Reasonable values
** for the minimum allocation size are 2^5 through 2^8.</dd>
**
** <dt>SQLITE_CONFIG_MUTEX</dt>
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure. The argument specifies
** alternative low-level mutex routines to be used in place
@ -1402,7 +1406,7 @@ struct sqlite3_mem_methods {
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** <dt>SQLITE_CONFIG_GETMUTEX</dt>
** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** instance of the [sqlite3_mutex_methods] structure. The
** [sqlite3_mutex_methods]
@ -1415,7 +1419,7 @@ struct sqlite3_mem_methods {
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(This option takes two arguments that determine the default
** memory allocation for the lookaside memory allocator on each
** [database connection]. The first argument is the
@ -1425,18 +1429,18 @@ struct sqlite3_mem_methods {
** verb to [sqlite3_db_config()] can be used to change the lookaside
** configuration on individual connections.)^ </dd>
**
** <dt>SQLITE_CONFIG_PCACHE</dt>
** [[SQLITE_CONFIG_PCACHE]] <dt>SQLITE_CONFIG_PCACHE</dt>
** <dd> ^(This option takes a single argument which is a pointer to
** an [sqlite3_pcache_methods] object. This object specifies the interface
** to a custom page cache implementation.)^ ^SQLite makes a copy of the
** object and uses it for page cache memory allocations.</dd>
**
** <dt>SQLITE_CONFIG_GETPCACHE</dt>
** [[SQLITE_CONFIG_GETPCACHE]] <dt>SQLITE_CONFIG_GETPCACHE</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
** [sqlite3_pcache_methods] object. SQLite copies of the current
** page cache implementation into that object.)^ </dd>
**
** <dt>SQLITE_CONFIG_LOG</dt>
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
** <dd> ^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
** function with a call signature of void(*)(void*,int,const char*),
** and a pointer to void. ^If the function pointer is not NULL, it is
@ -1454,7 +1458,7 @@ struct sqlite3_mem_methods {
** In a multi-threaded application, the application-defined logger
** function must be threadsafe. </dd>
**
** <dt>SQLITE_CONFIG_URI
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
** <dd> This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
** is globally disabled. If URI handling is globally enabled, all filenames
@ -1570,13 +1574,17 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
**
** ^This routine returns the [rowid] of the most recent
** successful [INSERT] into the database from the [database connection]
** in the first argument. ^If no successful [INSERT]s
** in the first argument. ^As of SQLite version 3.7.7, this routines
** records the last insert rowid of both ordinary tables and [virtual tables].
** ^If no successful [INSERT]s
** have ever occurred on that database connection, zero is returned.
**
** ^(If an [INSERT] occurs within a trigger, then the [rowid] of the inserted
** row is returned by this routine as long as the trigger is running.
** But once the trigger terminates, the value returned by this routine
** reverts to the last value inserted before the trigger fired.)^
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
** row as long as the trigger or virtual table method is running.
** But once the trigger or virtual table method ends, the value returned
** by this routine reverts to what it was before the trigger or virtual
** table method began.)^
**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
@ -2391,7 +2399,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** sqlite3_open_v2() can take one of
** the following three values, optionally combined with the
** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
** and/or [SQLITE_OPEN_PRIVATECACHE] flags:)^
** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
**
** <dl>
** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
@ -2410,9 +2418,8 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** </dl>
**
** If the 3rd parameter to sqlite3_open_v2() is not one of the
** combinations shown above or one of the combinations shown above combined
** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX],
** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_PRIVATECACHE] flags,
** combinations shown above optionally combined with other
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
** then the behavior is undefined.
**
** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
@ -2444,27 +2451,36 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** on-disk database will be created. ^This private database will be
** automatically deleted as soon as the database connection is closed.
**
** ^If URI filename interpretation is enabled, and the filename argument
** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
**
** ^If [URI filename] interpretation is enabled, and the filename argument
** begins with "file:", then the filename is interpreted as a URI. ^URI
** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
** is set in the fourth argument to sqlite3_open_v2(), or if it has
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
** [sqlite3_config()] method.
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
** As of SQLite version 3.7.7, URI filename interpretation is turned off
** by default, but future releases of SQLite might enable URI filename
** intepretation by default. See "[URI filenames]" for additional
** information.
**
** URI filenames are parsed according to RFC 1738. If the URI contains an
** 'authority', then it must be either an empty string or the string
** URI filenames are parsed according to RFC 3986. ^If the URI contains an
** authority, then it must be either an empty string or the string
** "localhost". ^If the authority is not an empty string or "localhost", an
** error is returned to the caller. ^The 'fragment' component of a URI, if
** present, is always ignored.
** error is returned to the caller. ^The fragment component of a URI, if
** present, is ignored.
**
** ^SQLite uses the 'path' component of the URI as the path to the database file
** to open. ^If the path begins with a '/' character, then it is interpreted as
** an absolute path. ^If it does not begin with a '/', it is interpreted as a
** relative path. ^On windows, the first component of an absolute path
** ^SQLite uses the path component of the URI as the name of the disk file
** which contains the database. ^If the path begins with a '/' character,
** then it is interpreted as an absolute path. ^If the path does not begin
** with a '/' (meaning that the authority section is omitted from the URI)
** then the path is interpreted as a relative path.
** ^On windows, the first component of an absolute path
** is a drive specification (e.g. "C:").
**
** [[core URI query parameters]]
** The query component of a URI may contain parameters that are interpreted
** either by SQLite itself, or by a [sqlite3_vfs | custom VFS implementation].
** either by SQLite itself, or by a [VFS | custom VFS implementation].
** SQLite interprets the following four query parameters:
**
** <ul>
@ -2516,9 +2532,11 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** </ul>
**
** ^Specifying an unknown parameter in the query component of a URI is not an
** error.
** error. Future versions of SQLite might understand additional query
** parameters. See "[query parameters with special meaning to SQLite]" for
** additional information.
**
** URI filename examples:
** [[URI filename examples]] <h3>URI filename examples</h3>
**
** <table border="1" align=center cellpadding=5>
** <tr><th> URI filenames <th> Results
@ -2576,6 +2594,26 @@ int sqlite3_open_v2(
const char *zVfs /* Name of VFS module to use */
);
/*
** CAPI3REF: Obtain Values For URI Parameters
**
** This is a utility routine, useful to VFS implementations, that checks
** to see if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of the query parameter.
**
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation. The zParam argument is the name of the
** query parameter we seek. This routine returns the value of the zParam
** parameter if it exists. If the parameter does not exist, this routine
** returns a NULL pointer.
**
** If the zFilename argument to this function is not a pointer that SQLite
** passed into the xOpen VFS method, then the behavior of this routine
** is undefined and probably undesirable.
*/
const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
/*
** CAPI3REF: Error Codes And Messages
**
@ -2691,43 +2729,45 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
** Additional information is available at [limits | Limits in SQLite].
**
** <dl>
** ^(<dt>SQLITE_LIMIT_LENGTH</dt>
** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
**
** ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
**
** ^(<dt>SQLITE_LIMIT_COLUMN</dt>
** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt>
** <dd>The maximum number of columns in a table definition or in the
** result set of a [SELECT] or the maximum number of columns in an index
** or in an ORDER BY or GROUP BY clause.</dd>)^
**
** ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
**
** ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
**
** ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
** used to implement an SQL statement. This limit is not currently
** enforced, though that might be added in some future release of
** SQLite.</dd>)^
**
** ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
**
** ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
**
** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
** <dd>The maximum length of the pattern argument to the [LIKE] or
** [GLOB] operators.</dd>)^
**
** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
** </dl>
*/
@ -3069,6 +3109,8 @@ int sqlite3_bind_parameter_count(sqlite3_stmt*);
** is included as part of the name.)^
** ^Parameters of the form "?" without a following integer have no name
** and are referred to as "nameless" or "anonymous parameters".
** ^Any parameter that is optimized out of the prepared statement by the
** query planner becomes a nameless or anonymous parameter.
**
** ^The first host parameter has an index of 1, not 0.
**
@ -5581,7 +5623,7 @@ int sqlite3_test_control(int op, ...);
** about the performance of SQLite, and optionally to reset various
** highwater marks. ^The first argument is an integer code for
** the specific parameter to measure. ^(Recognized integer codes
** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].)^
** are of the form [status parameters | SQLITE_STATUS_...].)^
** ^The current value of the parameter is returned into *pCurrent.
** ^The highest recorded value is returned in *pHighwater. ^If the
** resetFlag is true, then the highest record value is reset after
@ -5608,12 +5650,13 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
/*
** CAPI3REF: Status Parameters
** KEYWORDS: {status parameters}
**
** These integer constants designate various run-time status parameters
** that can be returned by [sqlite3_status()].
**
** <dl>
** ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
** <dd>This parameter is the current amount of memory checked out
** using [sqlite3_malloc()], either directly or indirectly. The
** figure includes calls made to [sqlite3_malloc()] by the application
@ -5623,23 +5666,24 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
**
** ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt>
** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
** internal equivalents). Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
** <dd>This parameter records the number of separate memory allocations
** currently checked out.</dd>)^
**
** ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
** <dd>This parameter returns the number of pages used out of the
** [pagecache memory allocator] that was configured using
** [SQLITE_CONFIG_PAGECACHE]. The
** value returned is in pages, not in bytes.</dd>)^
**
** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]]
** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of page cache
** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
@ -5649,13 +5693,13 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
** no space was left in the page cache.</dd>)^
**
** ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [pagecache memory allocator]. Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
** <dd>This parameter returns the number of allocations used out of the
** [scratch memory allocator] configured using
** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
@ -5663,7 +5707,7 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
** outstanding at time, this parameter also reports the number of threads
** using scratch memory at the same time.</dd>)^
**
** ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of scratch memory
** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
** buffer and where forced to overflow to [sqlite3_malloc()]. The values
@ -5673,13 +5717,13 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
** slots were available.
** </dd>)^
**
** ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [scratch memory allocator]. Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>This parameter records the deepest parser stack. It is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
@ -5704,9 +5748,9 @@ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
** about a single [database connection]. ^The first argument is the
** database connection object to be interrogated. ^The second argument
** is an integer constant, taken from the set of
** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros, that
** [SQLITE_DBSTATUS options], that
** determines the parameter to interrogate. The set of
** [SQLITE_DBSTATUS_LOOKASIDE_USED | SQLITE_DBSTATUS_*] macros is likely
** [SQLITE_DBSTATUS options] is likely
** to grow in future releases of SQLite.
**
** ^The current value of the requested parameter is written into *pCur
@ -5723,6 +5767,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
@ -5734,15 +5779,16 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** if a discontinued or unsupported verb is invoked.
**
** <dl>
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
** <dd>This parameter returns the number of lookaside memory slots currently
** checked out.</dd>)^
**
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
** <dd>This parameter returns the number malloc attempts that were
** satisfied using lookaside memory. Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
** <dd>This parameter returns the number malloc attempts that might have
** been satisfied using lookaside memory but failed due to the amount of
@ -5750,6 +5796,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** Only the high-water value is meaningful;
** the current value is always zero.)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
** <dd>This parameter returns the number malloc attempts that might have
** been satisfied using lookaside memory but failed due to all lookaside
@ -5757,12 +5804,12 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** Only the high-water value is meaningful;
** the current value is always zero.)^
**
** ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** memory used by all pager caches associated with the database connection.)^
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
**
** ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** memory used to store the schema for all databases associated
** with the connection - main, temp, and any [ATTACH]-ed databases.)^
@ -5771,7 +5818,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** [shared cache mode] being enabled.
** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
**
** ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
** <dd>This parameter returns the approximate number of of bytes of heap
** and lookaside memory used by all prepared statements associated with
** the database connection.)^
@ -5793,7 +5840,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** CAPI3REF: Prepared Statement Status
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS_SORT | counters] that measure the number
** [SQLITE_STMTSTATUS counters] that measure the number
** of times it has performed specific operations.)^ These counters can
** be used to monitor the performance characteristics of the prepared
** statements. For example, if the number of table steps greatly exceeds
@ -5804,7 +5851,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** ^(This interface is used to retrieve and reset counter values from
** a [prepared statement]. The first argument is the prepared statement
** object to be interrogated. The second argument
** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter]
** is an integer code for a specific [SQLITE_STMTSTATUS counter]
** to be interrogated.)^
** ^The current value of the requested counter is returned.
** ^If the resetFlg is true, then the counter is reset to zero after this
@ -5816,24 +5863,25 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
**
** These preprocessor macros define integer codes that name counter
** values associated with the [sqlite3_stmt_status()] interface.
** The meanings of the various counters are as follows:
**
** <dl>
** <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
** <dd>^This is the number of times that SQLite has stepped forward in
** a table as part of a full table scan. Large numbers for this counter
** may indicate opportunities for performance improvement through
** careful use of indices.</dd>
**
** <dt>SQLITE_STMTSTATUS_SORT</dt>
** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt>
** <dd>^This is the number of sort operations that have occurred.
** A non-zero value in this counter may indicate an opportunity to
** improvement performance through careful use of indices.</dd>
**
** <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
** <dd>^This is the number of rows inserted into transient indices that
** were created automatically in order to help joins run faster.
** A non-zero value in this counter may indicate an opportunity to
@ -5884,6 +5932,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** the application may discard the parameter after the call to
** [sqlite3_config()] returns.)^
**
** [[the xInit() page cache method]]
** ^(The xInit() method is called once for each effective
** call to [sqlite3_initialize()])^
** (usually only once during the lifetime of the process). ^(The xInit()
@ -5894,6 +5943,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** built-in default page cache is used instead of the application defined
** page cache.)^
**
** [[the xShutdown() page cache method]]
** ^The xShutdown() method is called by [sqlite3_shutdown()].
** It can be used to clean up
** any outstanding resources before process shutdown, if required.
@ -5908,6 +5958,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** ^SQLite will never invoke xInit() more than once without an intervening
** call to xShutdown().
**
** [[the xCreate() page cache methods]]
** ^SQLite invokes the xCreate() method to construct a new cache instance.
** SQLite will typically create one cache instance for each open database file,
** though this is not guaranteed. ^The
@ -5932,6 +5983,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** ^Hence, a cache created with bPurgeable false will
** never contain any unpinned pages.
**
** [[the xCachesize() page cache method]]
** ^(The xCachesize() method may be called at any time by SQLite to set the
** suggested maximum cache-size (number of pages stored by) the cache
** instance passed as the first argument. This is the value configured using
@ -5939,9 +5991,11 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** parameter, the implementation is not required to do anything with this
** value; it is advisory only.
**
** [[the xPagecount() page cache methods]]
** The xPagecount() method must return the number of pages currently
** stored in the cache, both pinned and unpinned.
**
** [[the xFetch() page cache methods]]
** The xFetch() method locates a page in the cache and returns a pointer to
** the page, or a NULL pointer.
** A "page", in this context, means a buffer of szPage bytes aligned at an
@ -5970,6 +6024,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** attempt to unpin one or more cache pages by spilling the content of
** pinned pages to disk and synching the operating system disk cache.
**
** [[the xUnpin() page cache method]]
** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
** as its second argument. If the third parameter, discard, is non-zero,
** then the page must be evicted from the cache.
@ -5982,6 +6037,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** call to xUnpin() unpins the page regardless of the number of prior calls
** to xFetch().
**
** [[the xRekey() page cache methods]]
** The xRekey() method is used to change the key value associated with the
** page passed as the second argument. If the cache
** previously contains an entry associated with newKey, it must be
@ -5994,6 +6050,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
** of these pages are pinned, they are implicitly unpinned, meaning that
** they can be safely discarded.
**
** [[the xDestroy() page cache method]]
** ^The xDestroy() method is used to delete a cache allocated by xCreate().
** All resources associated with the specified cache should be freed. ^After
** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
@ -6056,7 +6113,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** There should be exactly one call to sqlite3_backup_finish() for each
** successful call to sqlite3_backup_init().
**
** <b>sqlite3_backup_init()</b>
** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
**
** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the
** [database connection] associated with the destination database
@ -6083,7 +6140,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** sqlite3_backup_finish() functions to perform the specified backup
** operation.
**
** <b>sqlite3_backup_step()</b>
** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
**
** ^Function sqlite3_backup_step(B,N) will copy up to N pages between
** the source and destination databases specified by [sqlite3_backup] object B.
@ -6140,7 +6197,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** by the backup operation, then the backup database is automatically
** updated at the same time.
**
** <b>sqlite3_backup_finish()</b>
** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
**
** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the
** application wishes to abandon the backup operation, the application
@ -6163,7 +6220,8 @@ typedef struct sqlite3_backup sqlite3_backup;
** is not a permanent error and does not affect the return value of
** sqlite3_backup_finish().
**
** <b>sqlite3_backup_remaining(), sqlite3_backup_pagecount()</b>
** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
**
** ^Each call to sqlite3_backup_step() sets two values inside
** the [sqlite3_backup] object: the number of pages still to be backed
@ -6544,9 +6602,6 @@ int sqlite3_wal_checkpoint_v2(
** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()]
** documentation for additional information about the meaning and use of
** each of these values.
**
** <dt>SQLITE_CONFIG_GETMUTEX</dt>
** <dd> ^(This option takes a single argument which is a pointer to an
*/
#define SQLITE_CHECKPOINT_PASSIVE 0
#define SQLITE_CHECKPOINT_FULL 1

View File

@ -1235,6 +1235,7 @@ struct VTable {
sqlite3_vtab *pVtab; /* Pointer to vtab instance */
int nRef; /* Number of pointers to this structure */
u8 bConstraint; /* True if constraints are supported */
int iSavepoint; /* Depth of the SAVEPOINT stack */
VTable *pNext; /* Next in linked list (see above) */
};
@ -2941,6 +2942,12 @@ int sqlite3AddInt64(i64*,i64);
int sqlite3SubInt64(i64*,i64);
int sqlite3MulInt64(i64*,i64);
int sqlite3AbsInt32(int);
#ifdef SQLITE_ENABLE_8_3_NAMES
void sqlite3FileSuffix3(const char*, char*);
#else
# define sqlite3FileSuffix3(X,Y)
#endif
u8 sqlite3GetBoolean(const char *z);
const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);

View File

@ -163,7 +163,7 @@ const char *sqlite3TestErrorName(int rc){
case SQLITE_IOERR_CHECKRESERVEDLOCK:
zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break;
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
default: zName = "SQLITE_Unknown"; break;

View File

@ -73,6 +73,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "memdebug", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_8_3_NAMES
Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_MEMSYS3
Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
#else

View File

@ -10,14 +10,12 @@
**
*************************************************************************
**
** An example of a simple VFS implementation that omits complex features
** often not required or not possible on embedded platforms. Also includes
** code to buffer writes to the journal file, which can be a significant
** performance improvement on some embedded platforms.
** This file implements an example of a simple VFS implementation that
** omits complex features often not required or not possible on embedded
** platforms. Code is included to buffer writes to the journal file,
** which can be a significant performance improvement on some embedded
** platforms.
**
*/
/*
** OVERVIEW
**
** The code in this file implements a minimal SQLite VFS that can be

View File

@ -14,13 +14,7 @@
** an existing VFS. The code in this file attempts to verify that SQLite
** correctly populates and syncs a journal file before writing to a
** corresponding database file.
*/
#if SQLITE_TEST /* This file is used for testing only */
#include "sqlite3.h"
#include "sqliteInt.h"
/*
**
** INTERFACE
**
** The public interface to this wrapper VFS is two functions:
@ -99,6 +93,10 @@
**
** c) The journal file is deleted using xDelete.
*/
#if SQLITE_TEST /* This file is used for testing only */
#include "sqlite3.h"
#include "sqliteInt.h"
/*
** Maximum pathname length supported by the jt backend.

View File

@ -11,13 +11,36 @@
*************************************************************************
**
** This file contains a VFS "shim" - a layer that sits in between the
** pager and the real VFS.
** pager and the real VFS - that breaks up a very large database file
** into two or more smaller files on disk. This is useful, for example,
** in order to support large, multi-gigabyte databases on older filesystems
** that limit the maximum file size to 2 GiB.
**
** This particular shim enforces a multiplex system on DB files.
** This shim shards/partitions a single DB file into smaller
** "chunks" such that the total DB file size may exceed the maximum
** file size of the underlying file system.
** USAGE:
**
** Compile this source file and link it with your application. Then
** at start-time, invoke the following procedure:
**
** int sqlite3_multiplex_initialize(
** const char *zOrigVfsName, // The underlying real VFS
** int makeDefault // True to make multiplex the default VFS
** );
**
** The procedure call above will create and register a new VFS shim named
** "multiplex". The multiplex VFS will use the VFS named by zOrigVfsName to
** do the actual disk I/O. (The zOrigVfsName parameter may be NULL, in
** which case the default VFS at the moment sqlite3_multiplex_initialize()
** is called will be used as the underlying real VFS.)
**
** If the makeDefault parameter is TRUE then multiplex becomes the new
** default VFS. Otherwise, you can use the multiplex VFS by specifying
** "multiplex" as the 4th parameter to sqlite3_open_v2() or by employing
** URI filenames and adding "vfs=multiplex" as a parameter to the filename
** URI.
**
** The multiplex VFS allows databases up to 32 GiB in size. But it splits
** the files up into 1 GiB pieces, so that they will work even on filesystems
** that do not support large files.
*/
#include "sqlite3.h"
#include <string.h>
@ -185,13 +208,77 @@ static void multiplexLeave(void){ sqlite3_mutex_leave(gMultiplex.pMutex); }
** than the actual length of the string. For very long strings (greater
** than 1GiB) the value returned might be less than the true string length.
*/
int multiplexStrlen30(const char *z){
static int multiplexStrlen30(const char *z){
const char *z2 = z;
if( z==0 ) return 0;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at pOrigVfs->mxPathname characters. This function departs
** from the traditional temporary name generation in the os_win
** and os_unix VFS in several ways, but is necessary so that
** the file name is known for temporary files (like those used
** during vacuum.)
**
** N.B. This routine assumes your underlying VFS is ok with using
** "/" as a directory seperator. This is the default for UNIXs
** and is allowed (even mixed) for most versions of Windows.
*/
static int multiplexGetTempname(sqlite3_vfs *pOrigVfs, int nBuf, char *zBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
int i,j;
int attempts = 0;
int exists = 0;
int rc = SQLITE_ERROR;
/* Check that the output buffer is large enough for
** pVfs->mxPathname characters.
*/
if( pOrigVfs->mxPathname <= nBuf ){
char *zTmp = sqlite3_malloc(pOrigVfs->mxPathname);
if( zTmp==0 ) return SQLITE_NOMEM;
/* sqlite3_temp_directory should always be less than
** pVfs->mxPathname characters.
*/
sqlite3_snprintf(pOrigVfs->mxPathname,
zTmp,
"%s/",
sqlite3_temp_directory ? sqlite3_temp_directory : ".");
rc = pOrigVfs->xFullPathname(pOrigVfs, zTmp, nBuf, zBuf);
sqlite3_free(zTmp);
if( rc ) return rc;
/* Check that the output buffer is large enough for the temporary file
** name.
*/
j = multiplexStrlen30(zBuf);
if( (j + 8 + 1 + 3 + 1) <= nBuf ){
/* Make 3 attempts to generate a unique name. */
do {
attempts++;
sqlite3_randomness(8, &zBuf[j]);
for(i=0; i<8; i++){
zBuf[j+i] = (char)zChars[ ((unsigned char)zBuf[j+i])%(sizeof(zChars)-1) ];
}
memcpy(&zBuf[j+i], ".tmp", 5);
rc = pOrigVfs->xAccess(pOrigVfs, zBuf, SQLITE_ACCESS_EXISTS, &exists);
} while ( (rc==SQLITE_OK) && exists && (attempts<3) );
if( rc==SQLITE_OK && exists ){
rc = SQLITE_ERROR;
}
}
}
return rc;
}
/* Translate an sqlite3_file* that is really a multiplexGroup* into
** the sqlite3_file* for the underlying original VFS.
*/
@ -295,12 +382,12 @@ static int multiplexOpen(
int flags, /* Flags to control the opening */
int *pOutFlags /* Flags showing results of opening */
){
int rc; /* Result code */
int rc = SQLITE_OK; /* Result code */
multiplexConn *pMultiplexOpen; /* The new multiplex file descriptor */
multiplexGroup *pGroup; /* Corresponding multiplexGroup object */
sqlite3_file *pSubOpen; /* Real file descriptor */
sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
int nName = multiplexStrlen30(zName);
int nName;
int i;
int sz;
@ -311,23 +398,39 @@ static int multiplexOpen(
*/
multiplexEnter();
pMultiplexOpen = (multiplexConn*)pConn;
/* allocate space for group */
sz = sizeof(multiplexGroup) /* multiplexGroup */
+ (sizeof(sqlite3_file *)*SQLITE_MULTIPLEX_MAX_CHUNKS) /* pReal[] */
+ (pOrigVfs->szOsFile*SQLITE_MULTIPLEX_MAX_CHUNKS) /* *pReal */
+ SQLITE_MULTIPLEX_MAX_CHUNKS /* bOpen[] */
+ nName + 1; /* zName */
/* If the second argument to this function is NULL, generate a
** temporary file name to use. This will be handled by the
** original xOpen method. We just need to allocate space for
** it.
*/
if( !zName ){
rc = multiplexGetTempname(pOrigVfs, pOrigVfs->mxPathname, gMultiplex.zName);
zName = gMultiplex.zName;
}
if( rc==SQLITE_OK ){
/* allocate space for group */
nName = multiplexStrlen30(zName);
sz = sizeof(multiplexGroup) /* multiplexGroup */
+ (sizeof(sqlite3_file *)*SQLITE_MULTIPLEX_MAX_CHUNKS) /* pReal[] */
+ (pOrigVfs->szOsFile*SQLITE_MULTIPLEX_MAX_CHUNKS) /* *pReal */
+ SQLITE_MULTIPLEX_MAX_CHUNKS /* bOpen[] */
+ nName + 1; /* zName */
#ifndef SQLITE_MULTIPLEX_EXT_OVWR
sz += SQLITE_MULTIPLEX_EXT_SZ;
assert(nName+SQLITE_MULTIPLEX_EXT_SZ < pOrigVfs->mxPathname);
sz += SQLITE_MULTIPLEX_EXT_SZ;
assert(nName+SQLITE_MULTIPLEX_EXT_SZ < pOrigVfs->mxPathname);
#else
assert(nName >= SQLITE_MULTIPLEX_EXT_SZ);
assert(nName < pOrigVfs->mxPathname);
assert(nName >= SQLITE_MULTIPLEX_EXT_SZ);
assert(nName < pOrigVfs->mxPathname);
#endif
pGroup = sqlite3_malloc( sz );
if( pGroup==0 ){
rc=SQLITE_NOMEM;
}else{
pGroup = sqlite3_malloc( sz );
if( pGroup==0 ){
rc=SQLITE_NOMEM;
}
}
if( rc==SQLITE_OK ){
/* assign pointers to extra space allocated */
char *p = (char *)&pGroup[1];
pMultiplexOpen->pGroup = pGroup;
@ -411,7 +514,7 @@ static int multiplexDelete(
}
rc2 = pOrigVfs->xAccess(pOrigVfs, gMultiplex.zName,
SQLITE_ACCESS_EXISTS, &exists);
if( rc2==SQLITE_OK && exists){
if( rc2==SQLITE_OK && exists ){
/* if it exists, delete it */
rc2 = pOrigVfs->xDelete(pOrigVfs, gMultiplex.zName, syncDir);
if( rc2!=SQLITE_OK ) rc = rc2;

View File

@ -10,10 +10,6 @@
**
******************************************************************************
**
*/
#if SQLITE_TEST /* This file is used for testing only */
/*
** This file contains the implementation of the Tcl [testvfs] command,
** used to create SQLite VFS implementations with various properties and
** instrumentation to support testing SQLite.
@ -28,6 +24,7 @@
** -mxpathname INTEGER (Value for sqlite3_vfs.mxPathname)
** -iversion INTEGER (Value for sqlite3_vfs.iVersion)
*/
#if SQLITE_TEST /* This file is used for testing only */
#include "sqlite3.h"
#include "sqliteInt.h"

View File

@ -12,6 +12,100 @@
**
** This file contains code implements a VFS shim that writes diagnostic
** output for each VFS call, similar to "strace".
**
** USAGE:
**
** This source file exports a single symbol which is the name of a
** function:
**
** int vfstrace_register(
** const char *zTraceName, // Name of the newly constructed VFS
** const char *zOldVfsName, // Name of the underlying VFS
** int (*xOut)(const char*,void*), // Output routine. ex: fputs
** void *pOutArg, // 2nd argument to xOut. ex: stderr
** int makeDefault // Make the new VFS the default
** );
**
** Applications that want to trace their VFS usage must provide a callback
** function with this prototype:
**
** int traceOutput(const char *zMessage, void *pAppData);
**
** This function will "output" the trace messages, where "output" can
** mean different things to different applications. The traceOutput function
** for the command-line shell (see shell.c) is "fputs" from the standard
** library, which means that all trace output is written on the stream
** specified by the second argument. In the case of the command-line shell
** the second argument is stderr. Other applications might choose to output
** trace information to a file, over a socket, or write it into a buffer.
**
** The vfstrace_register() function creates a new "shim" VFS named by
** the zTraceName parameter. A "shim" VFS is an SQLite backend that does
** not really perform the duties of a true backend, but simply filters or
** interprets VFS calls before passing them off to another VFS which does
** the actual work. In this case the other VFS - the one that does the
** real work - is identified by the second parameter, zOldVfsName. If
** the the 2nd parameter is NULL then the default VFS is used. The common
** case is for the 2nd parameter to be NULL.
**
** The third and fourth parameters are the pointer to the output function
** and the second argument to the output function. For the SQLite
** command-line shell, when the -vfstrace option is used, these parameters
** are fputs and stderr, respectively.
**
** The fifth argument is true (non-zero) to cause the newly created VFS
** to become the default VFS. The common case is for the fifth parameter
** to be true.
**
** The call to vfstrace_register() simply creates the shim VFS that does
** tracing. The application must also arrange to use the new VFS for
** all database connections that are created and for which tracing is
** desired. This can be done by specifying the trace VFS using URI filename
** notation, or by specifying the trace VFS as the 4th parameter to
** sqlite3_open_v2() or by making the trace VFS be the default (by setting
** the 5th parameter of vfstrace_register() to 1).
**
**
** ENABLING VFSTRACE IN A COMMAND-LINE SHELL
**
** The SQLite command line shell implemented by the shell.c source file
** can be used with this module. To compile in -vfstrace support, first
** gather this file (test_vfstrace.c), the shell source file (shell.c),
** and the SQLite amalgamation source files (sqlite3.c, sqlite3.h) into
** the working directory. Then compile using a command like the following:
**
** gcc -o sqlite3 -Os -I. -DSQLITE_ENABLE_VFSTRACE \
** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \
** -DHAVE_READLINE -DHAVE_USLEEP=1 \
** shell.c test_vfstrace.c sqlite3.c -ldl -lreadline -lncurses
**
** The gcc command above works on Linux and provides (in addition to the
** -vfstrace option) support for FTS3 and FTS4, RTREE, and command-line
** editing using the readline library. The command-line shell does not
** use threads so we added -DSQLITE_THREADSAFE=0 just to make the code
** run a little faster. For compiling on a Mac, you'll probably need
** to omit the -DHAVE_READLINE, the -lreadline, and the -lncurses options.
** The compilation could be simplified to just this:
**
** gcc -DSQLITE_ENABLE_VFSTRACE \
** shell.c test_vfstrace.c sqlite3.c -ldl -lpthread
**
** In this second example, all unnecessary options have been removed
** Note that since the code is now threadsafe, we had to add the -lpthread
** option to pull in the pthreads library.
**
** To cross-compile for windows using MinGW, a command like this might
** work:
**
** /opt/mingw/bin/i386-mingw32msvc-gcc -o sqlite3.exe -Os -I \
** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_VFSTRACE \
** shell.c test_vfstrace.c sqlite3.c
**
** Similar compiler commands will work on different systems. The key
** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that
** the shell.c source file will know to include the -vfstrace command-line
** option and (2) you must compile and link the three source files
** shell,c, test_vfstrace.c, and sqlite3.c.
*/
#include <stdlib.h>
#include <string.h>

View File

@ -1146,3 +1146,29 @@ int sqlite3AbsInt32(int x){
if( x==(int)0x80000000 ) return 0x7fffffff;
return -x;
}
#ifdef SQLITE_ENABLE_8_3_NAMES
/*
** If SQLITE_ENABLE_8_3_NAME is set at compile-time and if the database
** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
** three characters, then shorten the suffix on z[] to be the last three
** characters of the original suffix.
**
** Examples:
**
** test.db-journal => test.nal
** test.db-wal => test.wal
** test.db-shm => test.shm
*/
void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
const char *zOk;
zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names");
if( zOk && sqlite3GetBoolean(zOk) ){
int i, sz;
sz = sqlite3Strlen30(z);
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
if( z[i]=='.' && ALWAYS(sz>i+4) ) memcpy(&z[i+1], &z[sz-3], 4);
}
}
#endif

View File

@ -564,6 +564,7 @@ int sqlite3VdbeExec(
Mem *pOut = 0; /* Output operand */
int iCompare = 0; /* Result of last OP_Compare operation */
int *aPermute = 0; /* Permutation of columns for OP_Compare */
i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
int origPc; /* Program counter at start of opcode */
@ -833,6 +834,7 @@ case OP_Halt: {
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
pc = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
/* Instruction pc is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
@ -1393,7 +1395,9 @@ case OP_Function: {
assert( pOp[-1].opcode==OP_CollSeq );
ctx.pColl = pOp[-1].p4.pColl;
}
db->lastRowid = lastRowid;
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
if( db->mallocFailed ){
/* Even though a malloc() has failed, the implementation of the
** user function may have called an sqlite3_result_XXX() function
@ -1762,7 +1766,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pIn3 = &aMem[pOp->p3];
flags1 = pIn1->flags;
flags3 = pIn3->flags;
if( (pIn1->flags | pIn3->flags)&MEM_Null ){
if( (flags1 | flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
/* If SQLITE_NULLEQ is set (which will only happen if the operator is
@ -1770,7 +1774,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** or not both operands are null.
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
res = (pIn1->flags & pIn3->flags & MEM_Null)==0;
res = (flags1 & flags3 & MEM_Null)==0;
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
@ -2580,13 +2584,16 @@ case OP_Savepoint: {
}else{
nName = sqlite3Strlen30(zName);
#ifndef SQLITE_OMIT_VIRTUAL_TABLE
/* This call is Ok even if this savepoint is actually a transaction
** savepoint (and therefore should not prompt xSavepoint()) callbacks.
** If this is a transaction savepoint being opened, it is guaranteed
** that the db->aVTrans[] array is empty. */
assert( db->autoCommit==0 || db->nVTrans==0 );
rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement);
rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN,
db->nStatement+db->nSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
#endif
/* Create a new savepoint structure. */
pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1);
@ -2835,7 +2842,7 @@ case OP_Transaction: {
p->iStatement = db->nSavepoint + db->nStatement;
}
rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement);
rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
if( rc==SQLITE_OK ){
rc = sqlite3BtreeBeginStmt(pBt, p->iStatement);
}
@ -3809,7 +3816,7 @@ case OP_NewRowid: { /* out2-prerelease */
assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is
** an AUTOINCREMENT table. */
/* on the first attempt, simply do one more than previous */
v = db->lastRowid;
v = lastRowid;
v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
v++; /* ensure non-zero */
cnt = 0;
@ -3919,7 +3926,7 @@ case OP_InsertInt: {
}
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = iKey;
if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey;
if( pData->flags & MEM_Null ){
pData->z = 0;
pData->n = 0;
@ -5007,7 +5014,7 @@ case OP_Program: { /* jump */
p->nFrame++;
pFrame->pParent = p->pFrame;
pFrame->lastRowid = db->lastRowid;
pFrame->lastRowid = lastRowid;
pFrame->nChange = p->nChange;
p->nChange = 0;
p->pFrame = pFrame;
@ -5814,7 +5821,7 @@ case OP_VUpdate: {
importVtabErrMsg(p, pVtab);
if( rc==SQLITE_OK && pOp->p1 ){
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
db->lastRowid = rowid;
db->lastRowid = lastRowid = rowid;
}
if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
if( pOp->p5==OE_Ignore ){
@ -5875,20 +5882,20 @@ case OP_MaxPgcnt: { /* out2-prerelease */
*/
case OP_Trace: {
char *zTrace;
char *z;
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
if( zTrace ){
if( db->xTrace ){
char *z = sqlite3VdbeExpandSql(p, zTrace);
db->xTrace(db->pTraceArg, z);
sqlite3DbFree(db, z);
}
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0 ){
sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
if( db->xTrace && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){
z = sqlite3VdbeExpandSql(p, zTrace);
db->xTrace(db->pTraceArg, z);
sqlite3DbFree(db, z);
}
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
break;
}
#endif
@ -5972,6 +5979,7 @@ vdbe_error_halt:
** release the mutexes on btrees that were acquired at the
** top. */
vdbe_return:
db->lastRowid = lastRowid;
sqlite3VdbeLeave(p);
return rc;

View File

@ -1799,6 +1799,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
if( !zMaster ){
return SQLITE_NOMEM;
}
sqlite3FileSuffix3(zMainFile, zMaster);
rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
}while( rc==SQLITE_OK && res );
if( rc==SQLITE_OK ){
@ -2201,17 +2202,11 @@ int sqlite3VdbeHalt(Vdbe *p){
** do so. If this operation returns an error, and the current statement
** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the
** current statement error code.
**
** Note that sqlite3VdbeCloseStatement() can only fail if eStatementOp
** is SAVEPOINT_ROLLBACK. But if p->rc==SQLITE_OK then eStatementOp
** must be SAVEPOINT_RELEASE. Hence the NEVER(p->rc==SQLITE_OK) in
** the following code.
*/
if( eStatementOp ){
rc = sqlite3VdbeCloseStatement(p, eStatementOp);
if( rc ){
assert( eStatementOp==SAVEPOINT_ROLLBACK );
if( NEVER(p->rc==SQLITE_OK) || p->rc==SQLITE_CONSTRAINT ){
if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
p->rc = rc;
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
@ -2857,7 +2852,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack(
idx += getVarint32(&aKey[idx], serial_type);
pMem->enc = pKeyInfo->enc;
pMem->db = pKeyInfo->db;
pMem->flags = 0;
/* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
pMem->zMalloc = 0;
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
pMem++;
@ -2872,6 +2867,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack(
** This routine destroys a UnpackedRecord object.
*/
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
#ifdef SQLITE_DEBUG
int i;
Mem *pMem;
@ -2885,6 +2881,7 @@ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
*/
if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem);
}
#endif
if( p->flags & UNPACKED_NEED_FREE ){
sqlite3DbFree(p->pKeyInfo->db, p);
}

View File

@ -577,11 +577,11 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
return rc;
}
/*
** Add the virtual table pVTab to the array sqlite3.aVTrans[].
** Grow the db->aVTrans[] array so that there is room for at least one
** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise.
*/
static int addToVTrans(sqlite3 *db, VTable *pVTab){
static int growVTrans(sqlite3 *db){
const int ARRAY_INCR = 5;
/* Grow the sqlite3.aVTrans array if required */
@ -596,10 +596,17 @@ static int addToVTrans(sqlite3 *db, VTable *pVTab){
db->aVTrans = aVTrans;
}
return SQLITE_OK;
}
/*
** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should
** have already been reserved using growVTrans().
*/
static void addToVTrans(sqlite3 *db, VTable *pVTab){
/* Add pVtab to the end of sqlite3.aVTrans */
db->aVTrans[db->nVTrans++] = pVTab;
sqlite3VtabLock(pVTab);
return SQLITE_OK;
}
/*
@ -637,7 +644,10 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
/* Justification of ALWAYS(): The xConstructor method is required to
** create a valid sqlite3_vtab if it returns SQLITE_OK. */
if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
rc = addToVTrans(db, sqlite3GetVTable(db, pTab));
rc = growVTrans(db);
if( rc==SQLITE_OK ){
addToVTrans(db, sqlite3GetVTable(db, pTab));
}
}
return rc;
@ -753,6 +763,7 @@ static void callFinaliser(sqlite3 *db, int offset){
x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset);
if( x ) x(p);
}
pVTab->iSavepoint = 0;
sqlite3VtabUnlock(pVTab);
}
sqlite3DbFree(db, db->aVTrans);
@ -842,10 +853,14 @@ int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
}
}
/* Invoke the xBegin method */
rc = pModule->xBegin(pVTab->pVtab);
/* Invoke the xBegin method. If successful, add the vtab to the
** sqlite3.aVTrans[] array. */
rc = growVTrans(db);
if( rc==SQLITE_OK ){
rc = addToVTrans(db, pVTab);
rc = pModule->xBegin(pVTab->pVtab);
if( rc==SQLITE_OK ){
addToVTrans(db, pVTab);
}
}
}
return rc;
@ -870,15 +885,18 @@ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
int rc = SQLITE_OK;
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
assert( iSavepoint>=0 );
if( db->aVTrans ){
int i;
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
const sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule;
VTable *pVTab = db->aVTrans[i];
const sqlite3_module *pMod = pVTab->pMod->pModule;
if( pMod->iVersion>=2 ){
int (*xMethod)(sqlite3_vtab *, int);
switch( op ){
case SAVEPOINT_BEGIN:
xMethod = pMod->xSavepoint;
pVTab->iSavepoint = iSavepoint+1;
break;
case SAVEPOINT_ROLLBACK:
xMethod = pMod->xRollbackTo;
@ -887,7 +905,9 @@ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
xMethod = pMod->xRelease;
break;
}
if( xMethod ) rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint);
if( xMethod && pVTab->iSavepoint>iSavepoint ){
rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint);
}
}
}
}

View File

@ -420,6 +420,7 @@ struct Wal {
sqlite3_file *pDbFd; /* File handle for the database file */
sqlite3_file *pWalFd; /* File handle for WAL file */
u32 iCallback; /* Value to pass to log callback (or 0) */
i64 mxWalSize; /* Truncate WAL to this size upon reset */
int nWiData; /* Size of array apWiData */
volatile u32 **apWiData; /* Pointer to wal-index content in memory */
u32 szPage; /* Database page size */
@ -1258,6 +1259,7 @@ int sqlite3WalOpen(
sqlite3_file *pDbFd, /* The open database file */
const char *zWalName, /* Name of the WAL file */
int bNoShm, /* True to run in heap-memory mode */
i64 mxWalSize, /* Truncate WAL to this size on reset */
Wal **ppWal /* OUT: Allocated Wal handle */
){
int rc; /* Return Code */
@ -1290,6 +1292,7 @@ int sqlite3WalOpen(
pRet->pWalFd = (sqlite3_file *)&pRet[1];
pRet->pDbFd = pDbFd;
pRet->readLock = -1;
pRet->mxWalSize = mxWalSize;
pRet->zWalName = zWalName;
pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
@ -1311,6 +1314,13 @@ int sqlite3WalOpen(
return rc;
}
/*
** Change the size to which the WAL file is trucated on each reset.
*/
void sqlite3WalLimit(Wal *pWal, i64 iLimit){
if( pWal ) pWal->mxWalSize = iLimit;
}
/*
** Find the smallest page number out of all pages held in the WAL that
** has not been returned by any prior invocation of this method on the
@ -2561,6 +2571,24 @@ static int walRestartLog(Wal *pWal){
*/
int i; /* Loop counter */
u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
/* Limit the size of WAL file if the journal_size_limit PRAGMA is
** set to a non-negative value. Log errors encountered
** during the truncation attempt. */
if( pWal->mxWalSize>=0 ){
i64 sz;
int rx;
sqlite3BeginBenignMalloc();
rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){
rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize);
}
sqlite3EndBenignMalloc();
if( rx ){
sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
}
}
pWal->nCkpt++;
pWal->hdr.mxFrame = 0;
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));

View File

@ -21,6 +21,7 @@
#ifdef SQLITE_OMIT_WAL
# define sqlite3WalOpen(x,y,z) 0
# define sqlite3WalLimit(x,y)
# define sqlite3WalClose(w,x,y,z) 0
# define sqlite3WalBeginReadTransaction(x,y,z) 0
# define sqlite3WalEndReadTransaction(z)
@ -46,9 +47,12 @@
typedef struct Wal Wal;
/* Open and close a connection to a write-ahead log. */
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *zName, int, Wal**);
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
/* Set the limiting size of a WAL file. */
void sqlite3WalLimit(Wal*, i64);
/* Used by readers to open (lock) and close (unlock) a snapshot. A
** snapshot is like a read-transaction. It is the state of the database
** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and

197
test/8_3_names.test Normal file
View File

@ -0,0 +1,197 @@
# 2011 May 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.
#
#***********************************************************************
#
# Test cases for the SQLITE_ENABLE_8_3_NAMES feature that forces all
# filename extensions to be limited to 3 characters. Some embedded
# systems need this to work around microsoft FAT patents, but this
# feature should be disabled on most deployments.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !8_3_names {
finish_test
return
}
db close
sqlite3_shutdown
sqlite3_config_uri 1
do_test 8_3_names-1.0 {
forcedelete test.db test.nal test.db-journal
sqlite3 db test.db
db eval {
PRAGMA cache_size=10;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(randomblob(20000));
BEGIN;
DELETE FROM t1;
INSERT INTO t1 VALUES(randomblob(15000));
}
file exists test.db-journal
} 1
do_test 8_3_names-1.1 {
file exists test.nal
} 0
do_test 8_3_names-1.2 {
db eval {
ROLLBACK;
SELECT length(x) FROM t1
}
} 20000
db close
do_test 8_3_names-2.0 {
forcedelete test.db test.nal test.db-journal
sqlite3 db file:./test.db?8_3_names=1
db eval {
PRAGMA cache_size=10;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(randomblob(20000));
BEGIN;
DELETE FROM t1;
INSERT INTO t1 VALUES(randomblob(15000));
}
file exists test.db-journal
} 0
do_test 8_3_names-2.1 {
file exists test.nal
} 1
forcedelete test2.db test2.nal test2.db-journal
file copy test.db test2.db
file copy test.nal test2.nal
do_test 8_3_names-2.2 {
db eval {
COMMIT;
SELECT length(x) FROM t1
}
} 15000
do_test 8_3_names-2.3 {
sqlite3 db2 file:./test2.db?8_3_names=1
db2 eval {
PRAGMA integrity_check;
SELECT length(x) FROM t1;
}
} {ok 20000}
db close
do_test 8_3_names-3.0 {
forcedelete test.db test.nal test.db-journal
sqlite3 db file:./test.db?8_3_names=0
db eval {
PRAGMA cache_size=10;
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(randomblob(20000));
BEGIN;
DELETE FROM t1;
INSERT INTO t1 VALUES(randomblob(15000));
}
file exists test.db-journal
} 1
do_test 8_3_names-3.1 {
file exists test.nal
} 0
forcedelete test2.db test2.nal test2.db-journal
file copy test.db test2.db
file copy test.db-journal test2.db-journal
do_test 8_3_names-3.2 {
db eval {
COMMIT;
SELECT length(x) FROM t1
}
} 15000
do_test 8_3_names-3.3 {
sqlite3 db2 file:./test2.db?8_3_names=0
db2 eval {
PRAGMA integrity_check;
SELECT length(x) FROM t1;
}
} {ok 20000}
##########################################################################
# Master journals.
#
db close
forcedelete test.db test2.db
do_test 8_3_names-4.0 {
sqlite3 db file:./test.db?8_3_names=1
db eval {
CREATE TABLE t1(x);
INSERT INTO t1 VALUES(1);
ATTACH 'file:./test2.db?8_3_names=1' AS db2;
CREATE TABLE db2.t2(y);
INSERT INTO t2 VALUES(2);
BEGIN;
INSERT INTO t1 VALUES(3);
INSERT INTO t2 VALUES(4);
COMMIT;
SELECT * FROM t1, t2 ORDER BY x, y
}
} {1 2 1 4 3 2 3 4}
##########################################################################
# WAL mode.
#
ifcapable !wal {
finish_test
return
}
db close
forcedelete test.db
do_test 8_3_names-5.0 {
sqlite3 db file:./test.db?8_3_names=1
register_wholenumber_module db
db eval {
PRAGMA journal_mode=WAL;
CREATE TABLE t1(x);
CREATE VIRTUAL TABLE nums USING wholenumber;
INSERT INTO t1 SELECT value FROM nums WHERE value BETWEEN 1 AND 1000;
BEGIN;
UPDATE t1 SET x=x*2;
}
sqlite3 db2 file:./test.db?8_3_names=1
register_wholenumber_module db2
db2 eval {
BEGIN;
SELECT sum(x) FROM t1;
}
} {500500}
do_test 8_3_names-5.1 {
file exists test.db-wal
} 0
do_test 8_3_names-5.2 {
file exists test.wal
} 1
do_test 8_3_names-5.3 {
file exists test.db-shm
} 0
do_test 8_3_names-5.4 {
file exists test.shm
} 1
do_test 8_3_names-5.5 {
db eval {
COMMIT;
SELECT sum(x) FROM t1;
}
} {1001000}
do_test 8_3_names-5.6 {
db2 eval {
SELECT sum(x) FROM t1;
}
} {500500}
finish_test

View File

@ -48,10 +48,11 @@ proc open_uri_error {uri} {
# and the filename argument begins with "file:", then the filename is
# interpreted as a URI.
#
# EVIDENCE-OF: R-00067-59538 URI filename interpretation is enabled if
# EVIDENCE-OF: R-32637-34037 URI filename interpretation is enabled if
# the SQLITE_OPEN_URI flag is is set in the fourth argument to
# sqlite3_open_v2(), or if it has been enabled globally using the
# SQLITE_CONFIG_URI option with the sqlite3_config() method.
# SQLITE_CONFIG_URI option with the sqlite3_config() method or by the
# SQLITE_USE_URI compile-time option.
#
if {$tcl_platform(platform) == "unix"} {
set flags [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE]
@ -140,8 +141,8 @@ if {$tcl_platform(platform) == "unix"} {
}
}
# EVIDENCE-OF: R-43804-65312 The 'fragment' component of a URI, if
# present, is always ignored.
# EVIDENCE-OF: R-45981-25528 The fragment component of a URI, if
# present, is ignored.
#
# It is difficult to test that something is ignore correctly. So these tests
# just show that adding a fragment does not interfere with the pathname or
@ -157,14 +158,15 @@ if {$tcl_platform(platform) == "unix"} {
}
}
# EVIDENCE-OF: R-00273-20588 SQLite uses the 'path' component of the URI
# as the path to the database file to open.
# EVIDENCE-OF: R-62557-09390 SQLite uses the path component of the URI
# as the name of the disk file which contains the database.
#
# EVIDENCE-OF: R-28659-11035 If the path begins with a '/' character,
# then it is interpreted as an absolute path.
#
# EVIDENCE-OF: R-39349-47203 If it does not begin with a '/', it is
# interpreted as a relative path.
# EVIDENCE-OF: R-46234-61323 If the path does not begin with a '/'
# (meaning that the authority section is omitted from the URI) then the
# path is interpreted as a relative path.
#
if {$tcl_platform(platform) == "unix"} {
foreach {tn uri parse} "

View File

@ -40,6 +40,7 @@ do_test fts3corrupt-1.2 {
do_catchsql_test 1.3 {
INSERT INTO t1 VALUES('world');
} {1 {database disk image is malformed}}
do_test 1.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
do_execsql_test 1.4 {
DROP TABLE t1;
}
@ -69,6 +70,7 @@ do_test fts3corrupt-2.1 {
do_catchsql_test 2.2 {
SELECT rowid FROM t1 WHERE t1 MATCH 'hello'
} {1 {database disk image is malformed}}
do_test 2.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
do_execsql_test 3.0 {
DROP TABLE t1;
@ -86,6 +88,7 @@ do_test fts3corrupt-3.1 {
do_catchsql_test 3.2 {
SELECT rowid FROM t1 WHERE t1 MATCH 'world'
} {1 {database disk image is malformed}}
do_test 3.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
do_execsql_test 4.0 {
@ -111,6 +114,7 @@ do_catchsql_test 4.2 {
UPDATE t1_segdir SET root = X'FFFFFFFFFFFFFFFF';
SELECT rowid FROM t1 WHERE t1 MATCH 'world';
} {1 {database disk image is malformed}}
do_test 4.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
set blob [binary format cca*cca*cca*cca*cca*cca*cca*cca*cca*cca*a* \
22 120 [string repeat a 120] \
@ -130,6 +134,7 @@ do_catchsql_test 4.3 {
UPDATE t1_segdir SET root = $blob;
SELECT rowid FROM t1 WHERE t1 MATCH 'world';
} {1 {database disk image is malformed}}
do_test 4.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
# Test a special kind of corruption, where the %_stat table contains
# an invalid entry. At one point this could lead to a division-by-zero
@ -152,10 +157,12 @@ do_catchsql_test 5.2 {
UPDATE t1_stat SET value = X'0000';
SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*';
} {1 {database disk image is malformed}}
do_test 5.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
do_catchsql_test 5.3 {
UPDATE t1_stat SET value = NULL;
SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*';
} {1 {database disk image is malformed}}
do_test 5.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB
finish_test

View File

@ -567,5 +567,45 @@ if {0==[info exists ::G(perm:presql)] || $::G(perm:presql) == ""} {
}
}
#-------------------------------------------------------------------------
# Test that you can vacuum a multiplex'ed DB.
ifcapable vacuum {
do_test multiplex-6.0.0 {
multiplex_delete test.db
sqlite3_multiplex_initialize "" 1
sqlite3 db test.db
multiplex_set db main 4096 16
} {SQLITE_OK}
do_test multiplex-6.1.0 {
execsql {
PRAGMA page_size=1024;
PRAGMA journal_mode=DELETE;
PRAGMA auto_vacuum=OFF;
}
execsql {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, randomblob($g_chunk_size));
INSERT INTO t1 VALUES(2, randomblob($g_chunk_size));
}
} {}
do_test multiplex-6.2.1 { file size [multiplex_name test.db 0] } [list $g_chunk_size]
do_test multiplex-6.2.2 { file size [multiplex_name test.db 1] } [list $g_chunk_size]
do_test multiplex-6.3.0 {
execsql { VACUUM }
} {}
do_test multiplex-6.99 {
db close
multiplex_delete test.db
sqlite3_multiplex_shutdown
} {SQLITE_OK}
}
catch { sqlite3_multiplex_shutdown }
finish_test

127
test/tkt-2d1a5c67d.test Normal file
View File

@ -0,0 +1,127 @@
# 2011 May 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. Specifically,
# it tests that ticket [2d1a5c67dfc2363e44f29d9bbd57f7331851390a] has
# been resolved.
#
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-2d1a5c67d
ifcapable {!wal || !vtab} {finish_test; return}
for {set ii 1} {$ii<=10} {incr ii} {
do_test tkt-2d1a5c67d.1.$ii {
db close
forcedelete test.db test.db-wal
sqlite3 db test.db
db eval "PRAGMA cache_size=$::ii"
db eval {
PRAGMA journal_mode=WAL;
CREATE TABLE t1(a,b);
CREATE INDEX t1b ON t1(b);
CREATE TABLE t2(x,y UNIQUE);
INSERT INTO t2 VALUES(3,4);
BEGIN;
INSERT INTO t1(a,b) VALUES(1,2);
SELECT 'A', * FROM t2 WHERE y=4;
SELECT 'B', * FROM t1;
COMMIT;
SELECT 'C', * FROM t1;
}
} {wal A 3 4 B 1 2 C 1 2}
}
db close
forcedelete test.db test.db-wal
sqlite3 db test.db
register_wholenumber_module db
db eval {
PRAGMA journal_mode=WAL;
CREATE TABLE t1(a,b);
CREATE INDEX t1b ON t1(b);
CREATE TABLE t2(x,y);
CREATE VIRTUAL TABLE nums USING wholenumber;
INSERT INTO t2 SELECT value, randomblob(1000) FROM nums
WHERE value BETWEEN 1 AND 1000;
}
for {set ii 1} {$ii<=10} {incr ii} {
do_test tkt-2d1a5c67d.2.$ii {
db eval "PRAGMA cache_size=$::ii"
db eval {
DELETE FROM t1;
BEGIN;
INSERT INTO t1(a,b) VALUES(1,2);
SELECT sum(length(y)) FROM t2;
COMMIT;
SELECT * FROM t1;
}
} {1000000 1 2}
}
db close
sqlite3 db test.db
do_execsql_test 3.1 {
PRAGMA cache_size = 10;
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
CREATE TABLE t4(a);
}
do_execsql_test 3.2 {
INSERT INTO t3 VALUES(NULL, randomblob(500));
INSERT INTO t3 SELECT NULL, b||b FROM t3; -- 2
INSERT INTO t3 SELECT NULL, b||b FROM t3; -- 4
INSERT INTO t3 SELECT NULL, b||b FROM t3; -- 8
INSERT INTO t3 SELECT NULL, b||b FROM t3; -- 16
INSERT INTO t3 SELECT NULL, b||b FROM t3; -- 32
INSERT INTO t3 SELECT NULL, b||b FROM t3; -- 64
INSERT INTO t3 SELECT NULL, b||b FROM t3; -- 128
}
do_execsql_test 3.3 {
BEGIN;
INSERT INTO t4 VALUES('xyz');
}
do_test 3.4 {
set blobs [list]
for {set i 1} {$i<100} {incr i} {
set b [db incrblob -readonly t3 b $i]
read $b
lappend blobs $b
}
execsql COMMIT
execsql { SELECT * FROM t4 WHERE a = 'xyz' }
} {xyz}
do_test 3.5 {
foreach b $blobs { close $b }
execsql { SELECT * FROM t4 WHERE a = 'xyz' }
} {xyz}
# Check that recovery works on the WAL file.
#
forcedelete test.db2-wal test.db2
do_test 3.6 {
file copy test.db-wal test.db2-wal
file copy test.db test.db2
sqlite3 db2 test.db2
execsql { SELECT * FROM t4 WHERE a = 'xyz' } db2
} {xyz}
finish_test

View File

@ -46,7 +46,7 @@ foreach {tn uri file} {
11 file file
12 http:test.db http:test.db
13 file:test.db%00extra test.db
14 file:test%00.db%00extra test
14 file:testdb%00.db%00extra testdb
15 test.db?mork=1#boris test.db?mork=1#boris
16 file://localhostPWD/test.db%3Fhello test.db?hello
@ -59,6 +59,7 @@ foreach {tn uri file} {
set uri [string map [list PWD [pwd]] $uri]
}
if {[file isdir $file]} {error "$file is a directory"}
forcedelete $file
do_test 1.$tn.1 { file exists $file } 0
set DB [sqlite3_open $uri]
@ -90,9 +91,9 @@ foreach {tn uri kvlist} {
3 file:test.db?hello=1&world=2&vfs=tvfs {hello 1 world 2 vfs tvfs}
4 file:test.db?hello=1&world=2&vfs=tvfs2 {}
5 file:test.db?%68%65%6C%6C%6F=%77%6F%72%6C%64 {hello world}
6 file:test%00.db?hello%00extra=world%00ex {hello world}
7 file:test%00.db?hello%00=world%00 {hello world}
8 file:test%00.db?=world&xyz=abc {xyz abc}
6 file:testdb%00.db?hello%00extra=world%00ex {hello world}
7 file:testdb%00.db?hello%00=world%00 {hello world}
8 file:testdb%00.db?=world&xyz=abc {xyz abc}
9 file:test.db?%00hello=world&xyz=abc {xyz abc}
10 file:test.db?hello=%00world&xyz= {hello {} xyz {}}
11 file:test.db?=#ravada {}

118
test/wal7.test Normal file
View File

@ -0,0 +1,118 @@
# 2011 May 16
#
# 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 the PRAGMA journal_size_limit when
# in WAL mode.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !wal {finish_test ; return }
# Case 1: No size limit. Journal can get large.
#
do_test wal7-1.0 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA page_size=1024;
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=50; -- 50 pages
CREATE TABLE t1(x, y UNIQUE);
INSERT INTO t1 VALUES(1,2);
INSERT INTO t1 VALUES(zeroblob(200000),4);
CREATE TABLE t2(z);
DELETE FROM t1;
INSERT INTO t2 SELECT x FROM t1;
}
expr {[file size test.db-wal]>50*1100}
} 1
do_test wal7-1.1 {
db eval {PRAGMA wal_checkpoint}
expr {[file size test.db-wal]>50*1100}
} 1
do_test wal7-1.2 {
db eval {INSERT INTO t2 VALUES('hi');}
expr {[file size test.db-wal]>50*1100}
} 1
# Case 2: Size limit at half the autocheckpoint size.
#
do_test wal7-2.0 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA page_size=1024;
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=50; -- 50 pages
PRAGMA journal_size_limit=25000;
CREATE TABLE t1(x, y UNIQUE);
INSERT INTO t1 VALUES(1,2);
INSERT INTO t1 VALUES(zeroblob(200000),4);
CREATE TABLE t2(z);
DELETE FROM t1;
INSERT INTO t2 SELECT x FROM t1;
}
file size test.db-wal
} 25000
# Case 3: Size limit of zero.
#
do_test wal7-3.0 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA page_size=1024;
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=50; -- 50 pages
PRAGMA journal_size_limit=0;
CREATE TABLE t1(x, y UNIQUE);
INSERT INTO t1 VALUES(1,2);
INSERT INTO t1 VALUES(zeroblob(200000),4);
CREATE TABLE t2(z);
DELETE FROM t1;
INSERT INTO t2 SELECT x FROM t1;
}
set sz [file size test.db-wal]
expr {$sz>0 && $sz<10000}
} 1
# Case 4: Size limit set before going WAL
#
do_test wal7-4.0 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA page_size=1024;
PRAGMA journal_size_limit=25000;
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=50; -- 50 pages
CREATE TABLE t1(x, y UNIQUE);
INSERT INTO t1 VALUES(1,2);
INSERT INTO t1 VALUES(zeroblob(200000),4);
CREATE TABLE t2(z);
DELETE FROM t1;
INSERT INTO t2 SELECT x FROM t1;
}
set sz [file size test.db-wal]
} 25000
finish_test