mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Merge the beta changes into sessions.
FossilOrigin-Name: beb5ea1439995fb8ab112451a8ffcc08fe42d0c4
This commit is contained in:
@@ -47,6 +47,10 @@ typedef sqlite3_uint64 u64;
|
||||
|
||||
#endif
|
||||
|
||||
/* Truncate very long tokens to this many bytes. Hard limit is
|
||||
** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
|
||||
** field that occurs at the start of each leaf page (see fts5_index.c). */
|
||||
#define FTS5_MAX_TOKEN_SIZE 32768
|
||||
|
||||
/*
|
||||
** Maximum number of prefix indexes on single FTS5 table. This must be
|
||||
@@ -480,6 +484,7 @@ int sqlite3Fts5IndexReads(Fts5Index *p);
|
||||
int sqlite3Fts5IndexReinit(Fts5Index *p);
|
||||
int sqlite3Fts5IndexOptimize(Fts5Index *p);
|
||||
int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
|
||||
int sqlite3Fts5IndexReset(Fts5Index *p);
|
||||
|
||||
int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
|
||||
|
||||
@@ -622,6 +627,7 @@ int sqlite3Fts5StorageDeleteAll(Fts5Storage *p);
|
||||
int sqlite3Fts5StorageRebuild(Fts5Storage *p);
|
||||
int sqlite3Fts5StorageOptimize(Fts5Storage *p);
|
||||
int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
|
||||
int sqlite3Fts5StorageReset(Fts5Storage *p);
|
||||
|
||||
/*
|
||||
** End of interface to code in fts5_storage.c.
|
||||
|
@@ -1493,6 +1493,7 @@ static int fts5ParseTokenize(
|
||||
|
||||
/* If an error has already occurred, this is a no-op */
|
||||
if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
|
||||
if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
|
||||
|
||||
if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
|
||||
Fts5ExprTerm *pSyn;
|
||||
@@ -2495,6 +2496,7 @@ static int fts5ExprPopulatePoslistsCb(
|
||||
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
|
||||
if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
|
||||
if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
|
||||
for(i=0; i<pExpr->nPhrase; i++){
|
||||
Fts5ExprTerm *pTerm;
|
||||
|
@@ -304,6 +304,10 @@ struct Fts5Index {
|
||||
sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */
|
||||
sqlite3_stmt *pIdxSelect;
|
||||
int nRead; /* Total number of blocks read */
|
||||
|
||||
sqlite3_stmt *pDataVersion;
|
||||
i64 iStructVersion; /* data_version when pStruct read */
|
||||
Fts5Structure *pStruct; /* Current db structure (or NULL) */
|
||||
};
|
||||
|
||||
struct Fts5DoclistIter {
|
||||
@@ -959,6 +963,50 @@ static void fts5StructureExtendLevel(
|
||||
}
|
||||
}
|
||||
|
||||
static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
|
||||
Fts5Structure *pRet = 0;
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
int iCookie; /* Configuration cookie */
|
||||
Fts5Data *pData;
|
||||
|
||||
pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
/* TODO: Do we need this if the leaf-index is appended? Probably... */
|
||||
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
|
||||
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
|
||||
if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
|
||||
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
|
||||
}
|
||||
fts5DataRelease(pData);
|
||||
if( p->rc!=SQLITE_OK ){
|
||||
fts5StructureRelease(pRet);
|
||||
pRet = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
static i64 fts5IndexDataVersion(Fts5Index *p){
|
||||
i64 iVersion = 0;
|
||||
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( p->pDataVersion==0 ){
|
||||
p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion,
|
||||
sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb)
|
||||
);
|
||||
if( p->rc ) return 0;
|
||||
}
|
||||
|
||||
if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){
|
||||
iVersion = sqlite3_column_int64(p->pDataVersion, 0);
|
||||
}
|
||||
p->rc = sqlite3_reset(p->pDataVersion);
|
||||
}
|
||||
|
||||
return iVersion;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read, deserialize and return the structure record.
|
||||
**
|
||||
@@ -971,26 +1019,49 @@ static void fts5StructureExtendLevel(
|
||||
** is called, it is a no-op.
|
||||
*/
|
||||
static Fts5Structure *fts5StructureRead(Fts5Index *p){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
Fts5Structure *pRet = 0; /* Object to return */
|
||||
int iCookie; /* Configuration cookie */
|
||||
Fts5Data *pData;
|
||||
|
||||
pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
|
||||
if( p->rc ) return 0;
|
||||
/* TODO: Do we need this if the leaf-index is appended? Probably... */
|
||||
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
|
||||
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
|
||||
if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
|
||||
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
|
||||
if( p->pStruct==0 ){
|
||||
p->iStructVersion = fts5IndexDataVersion(p);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->pStruct = fts5StructureReadUncached(p);
|
||||
}
|
||||
}
|
||||
|
||||
fts5DataRelease(pData);
|
||||
if( p->rc!=SQLITE_OK ){
|
||||
fts5StructureRelease(pRet);
|
||||
pRet = 0;
|
||||
#if 0
|
||||
else{
|
||||
Fts5Structure *pTest = fts5StructureReadUncached(p);
|
||||
if( pTest ){
|
||||
int i, j;
|
||||
assert_nc( p->pStruct->nSegment==pTest->nSegment );
|
||||
assert_nc( p->pStruct->nLevel==pTest->nLevel );
|
||||
for(i=0; i<pTest->nLevel; i++){
|
||||
assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge );
|
||||
assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg );
|
||||
for(j=0; j<pTest->aLevel[i].nSeg; j++){
|
||||
Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j];
|
||||
Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j];
|
||||
assert_nc( p1->iSegid==p2->iSegid );
|
||||
assert_nc( p1->pgnoFirst==p2->pgnoFirst );
|
||||
assert_nc( p1->pgnoLast==p2->pgnoLast );
|
||||
}
|
||||
}
|
||||
fts5StructureRelease(pTest);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( p->rc!=SQLITE_OK ) return 0;
|
||||
assert( p->iStructVersion!=0 );
|
||||
assert( p->pStruct!=0 );
|
||||
fts5StructureRef(p->pStruct);
|
||||
return p->pStruct;
|
||||
}
|
||||
|
||||
static void fts5StructureInvalidate(Fts5Index *p){
|
||||
if( p->pStruct ){
|
||||
fts5StructureRelease(p->pStruct);
|
||||
p->pStruct = 0;
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2250,6 +2321,18 @@ static void fts5LeafSeek(
|
||||
fts5SegIterLoadNPos(p, pIter);
|
||||
}
|
||||
|
||||
static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){
|
||||
if( p->pIdxSelect==0 ){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
|
||||
"SELECT pgno FROM '%q'.'%q_idx' WHERE "
|
||||
"segid=? AND term<=? ORDER BY term DESC LIMIT 1",
|
||||
pConfig->zDb, pConfig->zName
|
||||
));
|
||||
}
|
||||
return p->pIdxSelect;
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize the object pIter to point to term pTerm/nTerm within segment
|
||||
** pSeg. If there is no such term in the index, the iterator is set to EOF.
|
||||
@@ -2267,6 +2350,7 @@ static void fts5SegIterSeekInit(
|
||||
int iPg = 1;
|
||||
int bGe = (flags & FTS5INDEX_QUERY_SCAN);
|
||||
int bDlidx = 0; /* True if there is a doclist-index */
|
||||
sqlite3_stmt *pIdxSelect = 0;
|
||||
|
||||
assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 );
|
||||
assert( pTerm && nTerm );
|
||||
@@ -2275,23 +2359,16 @@ static void fts5SegIterSeekInit(
|
||||
|
||||
/* This block sets stack variable iPg to the leaf page number that may
|
||||
** contain term (pTerm/nTerm), if it is present in the segment. */
|
||||
if( p->pIdxSelect==0 ){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
|
||||
"SELECT pgno FROM '%q'.'%q_idx' WHERE "
|
||||
"segid=? AND term<=? ORDER BY term DESC LIMIT 1",
|
||||
pConfig->zDb, pConfig->zName
|
||||
));
|
||||
}
|
||||
pIdxSelect = fts5IdxSelectStmt(p);
|
||||
if( p->rc ) return;
|
||||
sqlite3_bind_int(p->pIdxSelect, 1, pSeg->iSegid);
|
||||
sqlite3_bind_blob(p->pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
|
||||
if( SQLITE_ROW==sqlite3_step(p->pIdxSelect) ){
|
||||
i64 val = sqlite3_column_int(p->pIdxSelect, 0);
|
||||
sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid);
|
||||
sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
|
||||
if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){
|
||||
i64 val = sqlite3_column_int(pIdxSelect, 0);
|
||||
iPg = (int)(val>>1);
|
||||
bDlidx = (val & 0x0001);
|
||||
}
|
||||
p->rc = sqlite3_reset(p->pIdxSelect);
|
||||
p->rc = sqlite3_reset(pIdxSelect);
|
||||
|
||||
if( iPg<pSeg->pgnoFirst ){
|
||||
iPg = pSeg->pgnoFirst;
|
||||
@@ -3481,6 +3558,17 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
|
||||
}
|
||||
}
|
||||
assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
|
||||
|
||||
{
|
||||
sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
u8 aBlob[2] = {0xff, 0xff};
|
||||
sqlite3_bind_int(pIdxSelect, 1, iSegid);
|
||||
sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
|
||||
assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
|
||||
p->rc = sqlite3_reset(pIdxSelect);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -3727,6 +3815,9 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
|
||||
Fts5PageWriter *pPage = &pWriter->writer;
|
||||
i64 iRowid;
|
||||
|
||||
static int nCall = 0;
|
||||
nCall++;
|
||||
|
||||
assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
|
||||
|
||||
/* Set the szLeaf header field. */
|
||||
@@ -4347,6 +4438,7 @@ static void fts5FlushOneHash(Fts5Index *p){
|
||||
** for the new level-0 segment. */
|
||||
pStruct = fts5StructureRead(p);
|
||||
iSegid = fts5AllocateSegid(p, pStruct);
|
||||
fts5StructureInvalidate(p);
|
||||
|
||||
if( iSegid ){
|
||||
const int pgsz = p->pConfig->pgsz;
|
||||
@@ -4531,7 +4623,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
|
||||
|
||||
if( pNew ){
|
||||
Fts5StructureLevel *pLvl;
|
||||
int nByte = nSeg * sizeof(Fts5StructureSegment);
|
||||
nByte = nSeg * sizeof(Fts5StructureSegment);
|
||||
pNew->nLevel = pStruct->nLevel+1;
|
||||
pNew->nRef = 1;
|
||||
pNew->nWriteCounter = pStruct->nWriteCounter;
|
||||
@@ -4566,6 +4658,7 @@ int sqlite3Fts5IndexOptimize(Fts5Index *p){
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5IndexFlush(p);
|
||||
pStruct = fts5StructureRead(p);
|
||||
fts5StructureInvalidate(p);
|
||||
|
||||
if( pStruct ){
|
||||
pNew = fts5IndexOptimizeStruct(p, pStruct);
|
||||
@@ -4596,6 +4689,7 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
|
||||
Fts5Structure *pStruct = fts5StructureRead(p);
|
||||
if( pStruct ){
|
||||
int nMin = p->pConfig->nUsermerge;
|
||||
fts5StructureInvalidate(p);
|
||||
if( nMerge<0 ){
|
||||
Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
|
||||
fts5StructureRelease(pStruct);
|
||||
@@ -5023,6 +5117,7 @@ int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
|
||||
int sqlite3Fts5IndexRollback(Fts5Index *p){
|
||||
fts5CloseReader(p);
|
||||
fts5IndexDiscardData(p);
|
||||
fts5StructureInvalidate(p);
|
||||
/* assert( p->rc==SQLITE_OK ); */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -5034,6 +5129,7 @@ int sqlite3Fts5IndexRollback(Fts5Index *p){
|
||||
*/
|
||||
int sqlite3Fts5IndexReinit(Fts5Index *p){
|
||||
Fts5Structure s;
|
||||
fts5StructureInvalidate(p);
|
||||
memset(&s, 0, sizeof(Fts5Structure));
|
||||
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
|
||||
fts5StructureWrite(p, &s);
|
||||
@@ -5092,11 +5188,13 @@ int sqlite3Fts5IndexClose(Fts5Index *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p ){
|
||||
assert( p->pReader==0 );
|
||||
fts5StructureInvalidate(p);
|
||||
sqlite3_finalize(p->pWriter);
|
||||
sqlite3_finalize(p->pDeleter);
|
||||
sqlite3_finalize(p->pIdxWriter);
|
||||
sqlite3_finalize(p->pIdxDeleter);
|
||||
sqlite3_finalize(p->pIdxSelect);
|
||||
sqlite3_finalize(p->pDataVersion);
|
||||
sqlite3Fts5HashFree(p->pHash);
|
||||
sqlite3_free(p->zDataTbl);
|
||||
sqlite3_free(p);
|
||||
@@ -6352,3 +6450,12 @@ int sqlite3Fts5IndexInit(sqlite3 *db){
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int sqlite3Fts5IndexReset(Fts5Index *p){
|
||||
assert( p->pStruct==0 || p->iStructVersion!=0 );
|
||||
if( fts5IndexDataVersion(p)!=p->iStructVersion ){
|
||||
fts5StructureInvalidate(p);
|
||||
}
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
@@ -597,16 +597,26 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int fts5NewTransaction(Fts5Table *pTab){
|
||||
Fts5Cursor *pCsr;
|
||||
for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
|
||||
if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
|
||||
}
|
||||
return sqlite3Fts5StorageReset(pTab->pStorage);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of xOpen method.
|
||||
*/
|
||||
static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
|
||||
Fts5Table *pTab = (Fts5Table*)pVTab;
|
||||
Fts5Config *pConfig = pTab->pConfig;
|
||||
Fts5Cursor *pCsr; /* New cursor object */
|
||||
Fts5Cursor *pCsr = 0; /* New cursor object */
|
||||
int nByte; /* Bytes of space to allocate */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int rc; /* Return code */
|
||||
|
||||
rc = fts5NewTransaction(pTab);
|
||||
if( rc==SQLITE_OK ){
|
||||
nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
|
||||
pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
|
||||
if( pCsr ){
|
||||
@@ -619,6 +629,7 @@ static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
|
||||
}else{
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
*ppCsr = (sqlite3_vtab_cursor*)pCsr;
|
||||
return rc;
|
||||
}
|
||||
@@ -1578,8 +1589,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
|
||||
** Implementation of xBegin() method.
|
||||
*/
|
||||
static int fts5BeginMethod(sqlite3_vtab *pVtab){
|
||||
UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
|
||||
fts5NewTransaction((Fts5Table*)pVtab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
@@ -369,6 +369,7 @@ static int fts5StorageInsertCallback(
|
||||
Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
|
||||
Fts5Index *pIdx = pCtx->pStorage->pIndex;
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
|
||||
if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
|
||||
pCtx->szCol++;
|
||||
}
|
||||
@@ -640,6 +641,10 @@ int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
|
||||
return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
|
||||
}
|
||||
|
||||
int sqlite3Fts5StorageReset(Fts5Storage *p){
|
||||
return sqlite3Fts5IndexReset(p->pIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a new rowid. This is used for "external content" tables when
|
||||
** a NULL value is inserted into the rowid column. The new rowid is allocated
|
||||
@@ -811,6 +816,7 @@ static int fts5StorageIntegrityCallback(
|
||||
int iCol;
|
||||
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
|
||||
|
||||
if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
|
||||
pCtx->szCol++;
|
||||
|
@@ -432,9 +432,16 @@ proc funk {} {
|
||||
}
|
||||
db func funk funk
|
||||
|
||||
# This test case corrupts the structure record within the first invocation
|
||||
# of function funk(). Which used to cause the bm25() function to throw an
|
||||
# exception. But since bm25() can now used the cached structure record,
|
||||
# it never sees the corruption introduced by funk() and so the following
|
||||
# statement no longer fails.
|
||||
#
|
||||
do_catchsql_test 16.2 {
|
||||
SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d'
|
||||
} {1 {SQL logic error or missing database}}
|
||||
} {0 {{} -1e-06 {}}}
|
||||
# {1 {SQL logic error or missing database}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@@ -179,6 +179,10 @@ for {set i 1} {1} {incr i} {
|
||||
if {$end<=$i} break
|
||||
lset var end [expr $end - $i]
|
||||
set struct [binary format c* $var]
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
db eval {
|
||||
BEGIN;
|
||||
UPDATE t1_data SET block = $struct WHERE id=10;
|
||||
|
67
ext/fts5/test/fts5determin.test
Normal file
67
ext/fts5/test/fts5determin.test
Normal file
@@ -0,0 +1,67 @@
|
||||
# 2016 March 21
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
# Specifically, that the fts5 module is deterministic. At one point, when
|
||||
# segment ids were allocated using sqlite3_randomness(), this was not the
|
||||
# case.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5aa
|
||||
return_if_no_fts5
|
||||
|
||||
proc do_determin_test {tn} {
|
||||
uplevel [list
|
||||
do_execsql_test $tn {
|
||||
SELECT (SELECT md5sum(id, block) FROM t1_data)==
|
||||
(SELECT md5sum(id, block) FROM t2_data),
|
||||
(SELECT md5sum(id, block) FROM t1_data)==
|
||||
(SELECT md5sum(id, block) FROM t3_data)
|
||||
} {1 1}
|
||||
]
|
||||
}
|
||||
|
||||
foreach_detail_mode $::testprefix {
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix="1 2", detail=%DETAIL%);
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(a, b, prefix="1 2", detail=%DETAIL%);
|
||||
CREATE VIRTUAL TABLE t3 USING fts5(a, b, prefix="1 2", detail=%DETAIL%);
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
foreach t {t1 t2 t3} {
|
||||
execsql [string map [list TBL $t] {
|
||||
INSERT INTO TBL VALUES('a b c', 'd e f');
|
||||
INSERT INTO TBL VALUES('c1 c2 c3', 'c1 c2 c3');
|
||||
INSERT INTO TBL VALUES('xyzxyzxyz', 'xyzxyzxyz');
|
||||
}]
|
||||
}
|
||||
} {}
|
||||
|
||||
do_determin_test 1.2
|
||||
|
||||
do_test 1.3 {
|
||||
foreach t {t1 t2 t3} {
|
||||
execsql [string map [list TBL $t] {
|
||||
INSERT INTO TBL(TBL) VALUES('optimize');
|
||||
}]
|
||||
}
|
||||
} {}
|
||||
|
||||
do_determin_test 1.4
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@@ -178,7 +178,7 @@ do_execsql_test 3.2 {
|
||||
ORDER BY rowid DESC;
|
||||
} {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
do_execsql_test 3.3 {
|
||||
INSERT INTO abc(abc) VALUES('integrity-check');
|
||||
INSERT INTO abc(abc) VALUES('optimize');
|
||||
INSERT INTO abc(abc) VALUES('integrity-check');
|
||||
@@ -187,7 +187,7 @@ do_execsql_test 3.2 {
|
||||
set v [lindex $vocab 0]
|
||||
set i 0
|
||||
foreach v $vocab {
|
||||
do_execsql_test 3.3.[incr i] {
|
||||
do_execsql_test 3.4.[incr i] {
|
||||
SELECT rowid FROM abc WHERE abc MATCH $v
|
||||
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
|
||||
}
|
||||
|
@@ -86,7 +86,7 @@ set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}]
|
||||
do_faultsim_test 4 -faults oom-* -body {
|
||||
db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'}
|
||||
} -test {
|
||||
faultsim_test_result {0 {0 {} 4}}
|
||||
faultsim_test_result {0 {0 {} 3}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
48
ext/fts5/test/fts5multiclient.test
Normal file
48
ext/fts5/test/fts5multiclient.test
Normal file
@@ -0,0 +1,48 @@
|
||||
# 2016 March 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.
|
||||
#
|
||||
#*************************************************************************
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/lock_common.tcl
|
||||
|
||||
set testprefix fts5multiclient
|
||||
return_if_no_fts5
|
||||
|
||||
foreach_detail_mode $testprefix {
|
||||
|
||||
do_multiclient_test tn {
|
||||
|
||||
do_test 1.$tn.1 {
|
||||
sql1 { CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%) }
|
||||
sql1 { INSERT INTO t1 VALUES('a b c') }
|
||||
sql2 { SELECT rowid FROM t1('b') }
|
||||
} {1}
|
||||
|
||||
do_test 1.$tn.2 {
|
||||
sql2 { INSERT INTO t1 VALUES('a b c') }
|
||||
sql1 { SELECT rowid FROM t1('b') }
|
||||
} {1 2}
|
||||
|
||||
do_test 1.$tn.3 {
|
||||
sql2 { INSERT INTO t1 VALUES('a b c') }
|
||||
sql1 { SELECT rowid FROM t1('b') }
|
||||
} {1 2 3}
|
||||
|
||||
do_test 1.$tn.4 {
|
||||
sql2 { INSERT INTO t1 VALUES('a b c') }
|
||||
sql1 { INSERT INTO t1 VALUES('a b c') }
|
||||
sql3 { INSERT INTO t1(t1) VALUES('integrity-check') }
|
||||
} {}
|
||||
|
||||
};# do_multiclient_test
|
||||
};# foreach_detail_mode
|
||||
finish_test
|
||||
|
@@ -340,7 +340,7 @@ do_test 14.2 {
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
db func rnddoc fts5_rnddoc
|
||||
do_execsql_test 4.0 {
|
||||
do_execsql_test 14.3 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(x);
|
||||
INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
|
||||
|
||||
@@ -348,9 +348,9 @@ do_execsql_test 4.0 {
|
||||
INSERT INTO x1 SELECT rnddoc(5) FROM ii;
|
||||
}
|
||||
|
||||
do_execsql_test 4.1 {
|
||||
do_execsql_test 14.4 {
|
||||
SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'
|
||||
} {0 {} 4}
|
||||
} {0 {} 3}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -448,4 +448,24 @@ do_execsql_test 20.2 {
|
||||
INSERT INTO x1(x1) VALUES('integrity-check');
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
set doc "a b [string repeat x 100000]"
|
||||
do_execsql_test 21.0 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(x);
|
||||
INSERT INTO x1(rowid, x) VALUES(11111, $doc);
|
||||
INSERT INTO x1(rowid, x) VALUES(11112, $doc);
|
||||
}
|
||||
do_execsql_test 21.1 {
|
||||
INSERT INTO x1(x1) VALUES('integrity-check');
|
||||
}
|
||||
do_execsql_test 21.2 {
|
||||
SELECT rowid FROM x1($doc);
|
||||
} {11111 11112}
|
||||
do_execsql_test 21.3 {
|
||||
DELETE FROM x1 WHERE rowid=11111;
|
||||
INSERT INTO x1(x1) VALUES('integrity-check');
|
||||
SELECT rowid FROM x1($doc);
|
||||
} {11112}
|
||||
|
||||
finish_test
|
||||
|
64
manifest
64
manifest
@@ -1,5 +1,5 @@
|
||||
C Merge\s3.12.0\sbeta\schanges\sfrom\strunk.
|
||||
D 2016-03-21T15:32:19.793
|
||||
C Merge\sthe\sbeta\schanges\sinto\ssessions.
|
||||
D 2016-03-24T14:34:26.863
|
||||
F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc e6ee58b849c116d5554024f524cbf61f064f6f01
|
||||
@@ -98,15 +98,15 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
|
||||
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
|
||||
F ext/fts5/fts5Int.h 4060504b7979601d99e1385c2b5713036854979a
|
||||
F ext/fts5/fts5Int.h 3677076aecbf645a7f2a019115c6a4ec3272dd78
|
||||
F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b
|
||||
F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f
|
||||
F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337
|
||||
F ext/fts5/fts5_index.c d3759c2f7d878e9e0a392b027a1c6e05c356007d
|
||||
F ext/fts5/fts5_main.c b8501e1a6a11591c53b18ce7aea7e5386cfb0421
|
||||
F ext/fts5/fts5_storage.c 2a38c6fa5db193a6a00588865134450ef5812daa
|
||||
F ext/fts5/fts5_index.c fdd82bb421a5d1e64d004acb43f4dd9970c8d2b3
|
||||
F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55
|
||||
F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c
|
||||
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
||||
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
|
||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||
@@ -117,7 +117,7 @@ F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8
|
||||
F ext/fts5/fts5parse.y fcc5e92e570d38cab38488b2109cbf67468923b2
|
||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||
F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841
|
||||
F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084
|
||||
F ext/fts5/test/fts5aa.test bd2d88182b9f7f30d300044048ad14683306b745
|
||||
F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b
|
||||
F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f
|
||||
F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c
|
||||
@@ -141,16 +141,17 @@ F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5
|
||||
F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1
|
||||
F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62
|
||||
F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c
|
||||
F ext/fts5/test/fts5corrupt3.test b9558d5b0ca44a8b6247fbb5d4a47592a8976892
|
||||
F ext/fts5/test/fts5corrupt3.test f77f65e386231daf62902466b40ff998b2c8ce4f
|
||||
F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69
|
||||
F ext/fts5/test/fts5dlidx.test 13871a14641017ae42f6f1055a8067bafd44cb3d
|
||||
F ext/fts5/test/fts5determin.test 10648edb75ef1e196b10978fd21a9be0c31e09c3
|
||||
F ext/fts5/test/fts5dlidx.test 007e9390c94638760797dbec2990c97c3fa08dfe
|
||||
F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b
|
||||
F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0
|
||||
F ext/fts5/test/fts5eb.test c516ae0c934be6fd29ec95ea8b5f11f461311535
|
||||
F ext/fts5/test/fts5fault1.test e09040d3e17b8c0837101e8c79c8a874c4376fb7
|
||||
F ext/fts5/test/fts5fault2.test d8c6c7f916ccbdfc10b2c69530e9dd3bc8313232
|
||||
F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3
|
||||
F ext/fts5/test/fts5fault4.test 532b6dacb963016cbf7003196bd87fb366540277
|
||||
F ext/fts5/test/fts5fault4.test dcbe3043c5611edd350191ea03a8daa190f0de5a
|
||||
F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618
|
||||
F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda
|
||||
F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080
|
||||
@@ -165,6 +166,7 @@ F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d
|
||||
F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b
|
||||
F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3
|
||||
F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75
|
||||
F ext/fts5/test/fts5multiclient.test 5bd54a6bc8ff818be233a50a8dec93da99098f2a
|
||||
F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc
|
||||
F ext/fts5/test/fts5onepass.test 7ed9608e258132cb8d55e7c479b08676ad68810c
|
||||
F ext/fts5/test/fts5optimize.test 9d3ac53bb9cae58cb070d795db86bcb2f9fec105
|
||||
@@ -178,7 +180,7 @@ F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab
|
||||
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
|
||||
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
|
||||
F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
|
||||
F ext/fts5/test/fts5simple.test ac5006cc3d0d08b3538e1e76c7300de9f24fbed1
|
||||
F ext/fts5/test/fts5simple.test cd23d4072ea095d652c9b6db12284cc642e49c98
|
||||
F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46
|
||||
F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e
|
||||
F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48
|
||||
@@ -315,10 +317,10 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
|
||||
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
|
||||
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||
F src/btree.c 6eee126fe9d1f57118de9be2be840a4c6e691828
|
||||
F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0
|
||||
F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
|
||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||
F src/build.c 213cbf84e99dd834e6ea46615633656d7ef79321
|
||||
F src/build.c 7d1a5e64fcd10110edc8ce9ffb710d06af0a59f5
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||
@@ -336,14 +338,14 @@ F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
|
||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||
F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002
|
||||
F src/main.c 915aeae74e2526b8fa33f9b99b1ed13eab968ac2
|
||||
F src/main.c 5ac9dccc03faadd6f867f67b9018ff41eeeadb46
|
||||
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memjournal.c 6423a0817ffd8c7a04ef9e5fb974b6b9dd71f8b6
|
||||
F src/memjournal.c 5253fd4335a8d9c64e5df25cb9da6329af5242c7
|
||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
@@ -355,8 +357,8 @@ F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e
|
||||
F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c 50103f69121bca969761b821e2b0e393b55fe869
|
||||
F src/os_win.c 551d973ada67127430e41d9e514e53f6beb6c5a7
|
||||
F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec
|
||||
F src/os_win.c 17493f12b0b023c2d5a349b6860009f0d45e08d6
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d
|
||||
F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
|
||||
@@ -364,20 +366,20 @@ F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821
|
||||
F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
|
||||
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
|
||||
F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05
|
||||
F src/pragma.c e7e8f380efec6075a722822306435afc1eeca88a
|
||||
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
|
||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
|
||||
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
|
||||
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
|
||||
F src/select.c 6dd2097bb158efe3b8d68683dcc3b4a49e907a34
|
||||
F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143
|
||||
F src/shell.c cd3f82fdc5c895b817a375b7ab8319cb41f447ce
|
||||
F src/sqlite.h.in a1d7a367997f80c7075303aaf73e5fc46261c11c
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
|
||||
F src/sqliteInt.h f5cebbea5909189efbffd7a659195436f503ebb7
|
||||
F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24
|
||||
F src/sqliteInt.h 410bd07098423b887874d9d2ff9ed6f8e3284839
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
F src/tclsqlite.c 56569acc73d36e836b64aefecbbb709a92ba0077
|
||||
@@ -435,7 +437,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
|
||||
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
||||
F src/update.c 14c6916d0194a7f25ad429292f4831b8c31e93d9
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c cf7dce85ab9af5280b8a45985df2591efbfefe56
|
||||
F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a
|
||||
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
|
||||
F src/vdbe.c 399bb1d353da8ce2e52e5182aabca18da0296749
|
||||
F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863
|
||||
@@ -446,7 +448,7 @@ F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77
|
||||
F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb
|
||||
F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062
|
||||
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
|
||||
F src/vtab.c fd69fd398e23e57ea4ea377d8a44b6998fc569c7
|
||||
F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b
|
||||
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
||||
@@ -541,9 +543,9 @@ F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
|
||||
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
|
||||
F test/capi3.test 860dafdc04f651a67781018cb1a0b179d22d7d15
|
||||
F test/capi3.test f0c66919e43d42e1572a69be039e4527a931b00f
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test b28ec47692f0fc50eb61b2d464d8d52e816b3732
|
||||
F test/capi3c.test 0b9edb0c2156a964b9271cd5ea7ae56736cc2fcb
|
||||
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
@@ -791,7 +793,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzcheck.c 93bb9d309888634615e21ef98d1c30d51483e942
|
||||
F test/fuzzcheck.c f01d432d001ba29e7916df8411be7d4e7cddc574
|
||||
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
||||
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -937,7 +939,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4
|
||||
F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f
|
||||
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
|
||||
F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3
|
||||
F test/nolock.test 96e922d2d3db71c2dd6557c98e8027a28277b415
|
||||
F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e
|
||||
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
|
||||
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
|
||||
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
|
||||
@@ -1478,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 6a7ee04b0ddac36a87d5ed2ac89a53e537f4d5a3 4bd12b57ea177cfb1f44d54bfa7aedfb8a8c0c64
|
||||
R 23117f3fb3eb670baa9fc58a11fb65fe
|
||||
P 3296a0ceedef43c2790f0b36471f91138a575243 a1fd14694c1adc54e5c443ebfdef38e38637f5c5
|
||||
R 6a48044d31c7e4e91715fbb78d5dfd9f
|
||||
U drh
|
||||
Z 887267d056670df55047d1f847ebaae7
|
||||
Z be6e3e57ab02c83f1495f1c79794042e
|
||||
|
@@ -1 +1 @@
|
||||
3296a0ceedef43c2790f0b36471f91138a575243
|
||||
beb5ea1439995fb8ab112451a8ffcc08fe42d0c4
|
13
src/btree.c
13
src/btree.c
@@ -2360,12 +2360,12 @@ int sqlite3BtreeOpen(
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
|
||||
while( pSib->pPrev ){ pSib = pSib->pPrev; }
|
||||
if( p->pBt<pSib->pBt ){
|
||||
if( (uptr)p->pBt<(uptr)pSib->pBt ){
|
||||
p->pNext = pSib;
|
||||
p->pPrev = 0;
|
||||
pSib->pPrev = p;
|
||||
}else{
|
||||
while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
|
||||
while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){
|
||||
pSib = pSib->pNext;
|
||||
}
|
||||
p->pNext = pSib->pNext;
|
||||
@@ -4472,8 +4472,13 @@ static int accessPayload(
|
||||
#endif
|
||||
assert( offset+amt <= pCur->info.nPayload );
|
||||
|
||||
if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){
|
||||
/* Trying to read or write past the end of the data is an error */
|
||||
assert( aPayload > pPage->aData );
|
||||
if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){
|
||||
/* Trying to read or write past the end of the data is an error. The
|
||||
** conditional above is really:
|
||||
** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
|
||||
** but is recast into its current form to avoid integer overflow problems
|
||||
*/
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
|
||||
|
15
src/build.c
15
src/build.c
@@ -1087,6 +1087,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
|
||||
pCol->szEst = 1;
|
||||
}else{
|
||||
pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
|
||||
pCol->colFlags |= COLFLAG_HASTYPE;
|
||||
}
|
||||
p->nCol++;
|
||||
pParse->constraintName.n = 0;
|
||||
@@ -1282,7 +1283,7 @@ void sqlite3AddPrimaryKey(
|
||||
int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
|
||||
){
|
||||
Table *pTab = pParse->pNewTable;
|
||||
const char *zName = 0;
|
||||
Column *pCol = 0;
|
||||
int iCol = -1, i;
|
||||
int nTerm;
|
||||
if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
|
||||
@@ -1294,8 +1295,8 @@ void sqlite3AddPrimaryKey(
|
||||
pTab->tabFlags |= TF_HasPrimaryKey;
|
||||
if( pList==0 ){
|
||||
iCol = pTab->nCol - 1;
|
||||
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
|
||||
zName = pTab->aCol[iCol].zName;
|
||||
pCol = &pTab->aCol[iCol];
|
||||
pCol->colFlags |= COLFLAG_PRIMKEY;
|
||||
nTerm = 1;
|
||||
}else{
|
||||
nTerm = pList->nExpr;
|
||||
@@ -1307,8 +1308,8 @@ void sqlite3AddPrimaryKey(
|
||||
const char *zCName = pCExpr->u.zToken;
|
||||
for(iCol=0; iCol<pTab->nCol; iCol++){
|
||||
if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
|
||||
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
|
||||
zName = pTab->aCol[iCol].zName;
|
||||
pCol = &pTab->aCol[iCol];
|
||||
pCol->colFlags |= COLFLAG_PRIMKEY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1316,8 +1317,8 @@ void sqlite3AddPrimaryKey(
|
||||
}
|
||||
}
|
||||
if( nTerm==1
|
||||
&& zName
|
||||
&& sqlite3StrICmp(sqlite3StrNext(zName), "INTEGER")==0
|
||||
&& pCol
|
||||
&& sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
|
||||
&& sortOrder!=SQLITE_SO_DESC
|
||||
){
|
||||
pTab->iPKey = iCol;
|
||||
|
@@ -3364,8 +3364,7 @@ int sqlite3_table_column_metadata(
|
||||
** explicitly declared column. Copy meta information from *pCol.
|
||||
*/
|
||||
if( pCol ){
|
||||
zDataType = sqlite3StrNext(pCol->zName);
|
||||
if( zDataType[0]==0 ) zDataType = 0;
|
||||
zDataType = sqlite3ColumnType(pCol,0);
|
||||
zCollSeq = pCol->zColl;
|
||||
notnull = pCol->notNull!=0;
|
||||
primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
|
||||
|
@@ -403,5 +403,5 @@ int sqlite3JournalIsInMemory(sqlite3_file *p){
|
||||
** pVfs to create the underlying on-disk files.
|
||||
*/
|
||||
int sqlite3JournalSize(sqlite3_vfs *pVfs){
|
||||
return MAX(pVfs->szOsFile, sizeof(MemJournal));
|
||||
return MAX(pVfs->szOsFile, (int)sizeof(MemJournal));
|
||||
}
|
||||
|
@@ -1366,7 +1366,7 @@ static void verifyDbFile(unixFile *pFile){
|
||||
sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
|
||||
return;
|
||||
}
|
||||
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
||||
if( buf.st_nlink==0 ){
|
||||
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
||||
return;
|
||||
}
|
||||
|
@@ -5425,7 +5425,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
memset(zBuf, 0, nBuf);
|
||||
#if defined(_MSC_VER) && _MSC_VER>=1400
|
||||
rand_s((int*)zBuf); /* rand_s() is not available with MinGW */
|
||||
rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */
|
||||
#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
|
||||
e.a = (unsigned char*)zBuf;
|
||||
e.na = nBuf;
|
||||
|
@@ -1066,7 +1066,6 @@ void sqlite3Pragma(
|
||||
setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
|
||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||
const char *zName;
|
||||
if( IsHiddenColumn(pCol) ){
|
||||
nHidden++;
|
||||
continue;
|
||||
@@ -1079,11 +1078,10 @@ void sqlite3Pragma(
|
||||
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
|
||||
}
|
||||
assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
|
||||
zName = pCol->zName;
|
||||
sqlite3VdbeMultiLoad(v, 1, "issisi",
|
||||
i-nHidden,
|
||||
zName,
|
||||
sqlite3StrNext(zName),
|
||||
pCol->zName,
|
||||
sqlite3ColumnType(pCol,""),
|
||||
pCol->notNull ? 1 : 0,
|
||||
pCol->pDflt ? pCol->pDflt->u.zToken : 0,
|
||||
k);
|
||||
|
@@ -1430,7 +1430,7 @@ static const char *columnTypeImpl(
|
||||
zOrigCol = "rowid";
|
||||
}else{
|
||||
zOrigCol = pTab->aCol[iCol].zName;
|
||||
zType = sqlite3StrNext(zOrigCol);
|
||||
zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
|
||||
estWidth = pTab->aCol[iCol].szEst;
|
||||
}
|
||||
zOrigTab = pTab->zName;
|
||||
@@ -1442,7 +1442,7 @@ static const char *columnTypeImpl(
|
||||
if( iCol<0 ){
|
||||
zType = "INTEGER";
|
||||
}else{
|
||||
zType = sqlite3StrNext(pTab->aCol[iCol].zName);
|
||||
zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
|
||||
estWidth = pTab->aCol[iCol].szEst;
|
||||
}
|
||||
#endif
|
||||
|
@@ -181,21 +181,6 @@
|
||||
# define SQLITE_PTR_TO_INT(X) ((int)(X))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
|
||||
** something between S (inclusive) and E (exclusive).
|
||||
**
|
||||
** In other words, S is a buffer and E is a pointer to the first byte after
|
||||
** the end of buffer S. This macro returns true if P points to something
|
||||
** contained within the buffer S.
|
||||
*/
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# define SQLITE_WITHIN(P,S,E) \
|
||||
((uintptr_t)(P)>=(uintptr_t)(S) && (uintptr_t)(P)<(uintptr_t)(E))
|
||||
#else
|
||||
# define SQLITE_WITHIN(P,S,E) ((P)>=(S) && (P)<(E))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** A macro to hint to the compiler that a function should not be
|
||||
** inlined.
|
||||
@@ -583,8 +568,12 @@
|
||||
/*
|
||||
** Macros to compute minimum and maximum of two numbers.
|
||||
*/
|
||||
#ifndef MIN
|
||||
# define MIN(A,B) ((A)<(B)?(A):(B))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
# define MAX(A,B) ((A)>(B)?(A):(B))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Swap two objects of type TYPE.
|
||||
@@ -713,6 +702,27 @@ typedef INT16_TYPE LogEst;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The uptr type is an unsigned integer large enough to hold a pointer
|
||||
*/
|
||||
#if defined(HAVE_STDINT_H)
|
||||
typedef uintptr_t uptr;
|
||||
#elif SQLITE_PTRSIZE==4
|
||||
typedef u32 uptr;
|
||||
#else
|
||||
typedef u64 uptr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to
|
||||
** something between S (inclusive) and E (exclusive).
|
||||
**
|
||||
** In other words, S is a buffer and E is a pointer to the first byte after
|
||||
** the end of buffer S. This macro returns true if P points to something
|
||||
** contained within the buffer S.
|
||||
*/
|
||||
#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
|
||||
|
||||
|
||||
/*
|
||||
** Macros to determine whether the machine is big or little endian,
|
||||
** and whether or not that determination is run-time or compile-time.
|
||||
@@ -1602,6 +1612,7 @@ struct Column {
|
||||
*/
|
||||
#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
|
||||
#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
|
||||
#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */
|
||||
|
||||
/*
|
||||
** A "Collating Sequence" is defined by an instance of the following
|
||||
@@ -3309,7 +3320,7 @@ int sqlite3IsIdChar(u8);
|
||||
*/
|
||||
int sqlite3StrICmp(const char*,const char*);
|
||||
int sqlite3Strlen30(const char*);
|
||||
const char *sqlite3StrNext(const char*);
|
||||
char *sqlite3ColumnType(Column*,char*);
|
||||
#define sqlite3StrNICmp sqlite3_strnicmp
|
||||
|
||||
int sqlite3MallocInit(void);
|
||||
|
@@ -101,8 +101,8 @@
|
||||
** The suggested maximum number of in-memory pages to use for
|
||||
** the main database table and for temporary tables.
|
||||
**
|
||||
** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
|
||||
** is 2000*1024 bytes.
|
||||
** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000,
|
||||
** which means the cache size is limited to 2048000 bytes of memory.
|
||||
** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
|
||||
** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
|
||||
*/
|
||||
|
12
src/util.c
12
src/util.c
@@ -110,11 +110,15 @@ int sqlite3Strlen30(const char *z){
|
||||
}
|
||||
|
||||
/*
|
||||
** The string z[] is followed immediately by another string. Return
|
||||
** a poiner to that other string.
|
||||
** Return the declared type of a column. Or return zDflt if the column
|
||||
** has no declared type.
|
||||
**
|
||||
** The column type is an extra string stored after the zero-terminator on
|
||||
** the column name if and only if the COLFLAG_HASTYPE flag is set.
|
||||
*/
|
||||
const char *sqlite3StrNext(const char *z){
|
||||
return z + strlen(z) + 1;
|
||||
char *sqlite3ColumnType(Column *pCol, char *zDflt){
|
||||
if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt;
|
||||
return pCol->zName + strlen(pCol->zName) + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
14
src/vtab.c
14
src/vtab.c
@@ -564,24 +564,18 @@ static int vtabCallConstructor(
|
||||
pTab->pVTable = pVTable;
|
||||
|
||||
for(iCol=0; iCol<pTab->nCol; iCol++){
|
||||
char *zType = (char*)sqlite3StrNext(pTab->aCol[iCol].zName);
|
||||
char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
|
||||
int nType;
|
||||
int i = 0;
|
||||
if( !zType[0] ){
|
||||
pTab->tabFlags |= oooHidden;
|
||||
continue;
|
||||
}
|
||||
nType = sqlite3Strlen30(zType);
|
||||
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
|
||||
for(i=0; i<nType; i++){
|
||||
if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
|
||||
&& (zType[i+7]=='\0' || zType[i+7]==' ')
|
||||
if( 0==sqlite3StrNICmp("hidden", &zType[i], 6)
|
||||
&& (i==0 || zType[i-1]==' ')
|
||||
&& (zType[i+6]=='\0' || zType[i+6]==' ')
|
||||
){
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( i<nType ){
|
||||
int j;
|
||||
int nDel = 6 + (zType[i+6] ? 1 : 0);
|
||||
|
@@ -929,7 +929,7 @@ do_test capi3-11.10 {
|
||||
do_test capi3-11.11 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_DONE}
|
||||
ifcapable api_armor {
|
||||
ifcapable !autoreset {
|
||||
do_test capi3-11.12armor {
|
||||
sqlite3_step $STMT
|
||||
sqlite3_step $STMT
|
||||
|
@@ -868,7 +868,7 @@ do_test capi3c-11.10 {
|
||||
do_test capi3c-11.11 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_DONE}
|
||||
ifcapable api_armor {
|
||||
ifcapable !autoreset {
|
||||
do_test capi3c-11.12armor {
|
||||
sqlite3_step $STMT
|
||||
sqlite3_step $STMT
|
||||
|
@@ -189,7 +189,7 @@ static int progressHandler(void *pVdbeLimitFlag){
|
||||
** Reallocate memory. Show and error and quit if unable.
|
||||
*/
|
||||
static void *safe_realloc(void *pOld, int szNew){
|
||||
void *pNew = realloc(pOld, szNew);
|
||||
void *pNew = realloc(pOld, szNew<=0 ? 1 : szNew);
|
||||
if( pNew==0 ) fatalError("unable to realloc for %d bytes", szNew);
|
||||
return pNew;
|
||||
}
|
||||
|
@@ -183,7 +183,9 @@ db2 close
|
||||
db close
|
||||
tvfs delete
|
||||
|
||||
# 2016-03-11: Make sure all works when transitioning to WAL mode under nolock.
|
||||
if {[permutation]!="inmemory_journal"} {
|
||||
# 2016-03-11: Make sure all works when transitioning to WAL mode
|
||||
# under nolock.
|
||||
#
|
||||
do_test nolock-4.1 {
|
||||
forcedelete test.db
|
||||
@@ -213,5 +215,6 @@ do_test nolock-4.3 {
|
||||
set rc [catch {db eval {SELECT * FROM t1}} msg]
|
||||
lappend rc $msg
|
||||
} {1 {unable to open database file}}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user