mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add an incremental optimize capability to fts5. Make the 'merge' command independent of the 'automerge' settings.
FossilOrigin-Name: 556671444c03e3afca072d0f5e9bea2657de6fd3
This commit is contained in:
@ -172,6 +172,7 @@ struct Fts5Config {
|
||||
int pgsz; /* Approximate page size used in %_data */
|
||||
int nAutomerge; /* 'automerge' setting */
|
||||
int nCrisisMerge; /* Maximum allowed segments per level */
|
||||
int nUsermerge; /* 'usermerge' setting */
|
||||
int nHashSize; /* Bytes of memory for in-memory hash */
|
||||
char *zRank; /* Name of rank function */
|
||||
char *zRankArgs; /* Arguments to rank function */
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#define FTS5_DEFAULT_PAGE_SIZE 4050
|
||||
#define FTS5_DEFAULT_AUTOMERGE 4
|
||||
#define FTS5_DEFAULT_USERMERGE 4
|
||||
#define FTS5_DEFAULT_CRISISMERGE 16
|
||||
#define FTS5_DEFAULT_HASHSIZE (1024*1024)
|
||||
|
||||
@ -857,6 +858,18 @@ int sqlite3Fts5ConfigSetValue(
|
||||
}
|
||||
}
|
||||
|
||||
else if( 0==sqlite3_stricmp(zKey, "usermerge") ){
|
||||
int nUsermerge = -1;
|
||||
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
|
||||
nUsermerge = sqlite3_value_int(pVal);
|
||||
}
|
||||
if( nUsermerge<2 || nUsermerge>16 ){
|
||||
*pbBadkey = 1;
|
||||
}else{
|
||||
pConfig->nUsermerge = nUsermerge;
|
||||
}
|
||||
}
|
||||
|
||||
else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){
|
||||
int nCrisisMerge = -1;
|
||||
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
|
||||
@ -903,6 +916,7 @@ int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
|
||||
/* Set default values */
|
||||
pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
|
||||
pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
|
||||
pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE;
|
||||
pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
|
||||
pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
|
||||
|
||||
|
@ -4179,13 +4179,17 @@ static void fts5IndexMergeLevel(
|
||||
|
||||
/*
|
||||
** Do up to nPg pages of automerge work on the index.
|
||||
**
|
||||
** Return true if any changes were actually made, or false otherwise.
|
||||
*/
|
||||
static void fts5IndexMerge(
|
||||
static int fts5IndexMerge(
|
||||
Fts5Index *p, /* FTS5 backend object */
|
||||
Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
|
||||
int nPg /* Pages of work to do */
|
||||
int nPg, /* Pages of work to do */
|
||||
int nMin /* Minimum number of segments to merge */
|
||||
){
|
||||
int nRem = nPg;
|
||||
int bRet = 0;
|
||||
Fts5Structure *pStruct = *ppStruct;
|
||||
while( nRem>0 && p->rc==SQLITE_OK ){
|
||||
int iLvl; /* To iterate through levels */
|
||||
@ -4216,17 +4220,17 @@ static void fts5IndexMerge(
|
||||
}
|
||||
#endif
|
||||
|
||||
if( nBest<p->pConfig->nAutomerge
|
||||
&& pStruct->aLevel[iBestLvl].nMerge==0
|
||||
){
|
||||
if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){
|
||||
break;
|
||||
}
|
||||
bRet = 1;
|
||||
fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
|
||||
if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
|
||||
fts5StructurePromote(p, iBestLvl+1, pStruct);
|
||||
}
|
||||
}
|
||||
*ppStruct = pStruct;
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4254,7 +4258,7 @@ static void fts5IndexAutomerge(
|
||||
pStruct->nWriteCounter += nLeaf;
|
||||
nRem = (int)(p->nWorkUnit * nWork * pStruct->nLevel);
|
||||
|
||||
fts5IndexMerge(p, ppStruct, nRem);
|
||||
fts5IndexMerge(p, ppStruct, nRem, p->pConfig->nAutomerge);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4474,25 +4478,38 @@ static void fts5IndexFlush(Fts5Index *p){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int sqlite3Fts5IndexOptimize(Fts5Index *p){
|
||||
Fts5Structure *pStruct;
|
||||
static Fts5Structure *fts5IndexOptimizeStruct(
|
||||
Fts5Index *p,
|
||||
Fts5Structure *pStruct
|
||||
){
|
||||
Fts5Structure *pNew = 0;
|
||||
int nSeg = 0;
|
||||
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5IndexFlush(p);
|
||||
pStruct = fts5StructureRead(p);
|
||||
|
||||
if( pStruct ){
|
||||
assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
|
||||
nSeg = pStruct->nSegment;
|
||||
if( nSeg>1 ){
|
||||
int nByte = sizeof(Fts5Structure);
|
||||
int nSeg = pStruct->nSegment;
|
||||
int i;
|
||||
|
||||
/* Figure out if this structure requires optimization. A structure does
|
||||
** not require optimization if either:
|
||||
**
|
||||
** + it consists of fewer than two segments, or
|
||||
** + all segments are on the same level, or
|
||||
** + all segments except one are currently inputs to a merge operation.
|
||||
**
|
||||
** In the first case, return NULL. In the second, increment the ref-count
|
||||
** on *pStruct and return a copy of the pointer to it.
|
||||
*/
|
||||
if( nSeg<2 ) return 0;
|
||||
for(i=0; i<pStruct->nLevel; i++){
|
||||
int nThis = pStruct->aLevel[i].nSeg;
|
||||
if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){
|
||||
fts5StructureRef(pStruct);
|
||||
return pStruct;
|
||||
}
|
||||
assert( pStruct->aLevel[i].nMerge<=nThis );
|
||||
}
|
||||
|
||||
nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
|
||||
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
|
||||
}
|
||||
}
|
||||
|
||||
if( pNew ){
|
||||
Fts5StructureLevel *pLvl;
|
||||
int nByte = nSeg * sizeof(Fts5StructureSegment);
|
||||
@ -4520,8 +4537,28 @@ int sqlite3Fts5IndexOptimize(Fts5Index *p){
|
||||
}
|
||||
}
|
||||
|
||||
if( pNew ){
|
||||
int iLvl = pNew->nLevel-1;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
int sqlite3Fts5IndexOptimize(Fts5Index *p){
|
||||
Fts5Structure *pStruct;
|
||||
Fts5Structure *pNew = 0;
|
||||
int nSeg = 0;
|
||||
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5IndexFlush(p);
|
||||
pStruct = fts5StructureRead(p);
|
||||
|
||||
if( pStruct ){
|
||||
pNew = fts5IndexOptimizeStruct(p, pStruct);
|
||||
}
|
||||
fts5StructureRelease(pStruct);
|
||||
|
||||
if( pNew && pNew->nSegment>0 ){
|
||||
int iLvl;
|
||||
for(iLvl=0; iLvl<pNew->nLevel; iLvl++){
|
||||
if( pNew->aLevel[iLvl].nSeg ) break;
|
||||
}
|
||||
while( p->rc==SQLITE_OK && pNew->aLevel[iLvl].nSeg>0 ){
|
||||
int nRem = FTS5_OPT_WORK_UNIT;
|
||||
fts5IndexMergeLevel(p, &pNew, iLvl, &nRem);
|
||||
@ -4531,20 +4568,31 @@ int sqlite3Fts5IndexOptimize(Fts5Index *p){
|
||||
fts5StructureRelease(pNew);
|
||||
}
|
||||
|
||||
fts5StructureRelease(pStruct);
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** This is called to implement the special "VALUES('merge', $nMerge)"
|
||||
** INSERT command.
|
||||
*/
|
||||
int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
|
||||
Fts5Structure *pStruct;
|
||||
|
||||
pStruct = fts5StructureRead(p);
|
||||
Fts5Structure *pStruct = fts5StructureRead(p);
|
||||
if( pStruct ){
|
||||
int nMin = p->pConfig->nUsermerge;
|
||||
if( nMerge<0 ){
|
||||
Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct);
|
||||
fts5StructureRelease(pStruct);
|
||||
pStruct = pNew;
|
||||
nMin = 2;
|
||||
nMerge = nMerge*-1;
|
||||
}
|
||||
if( pStruct && pStruct->nLevel ){
|
||||
fts5IndexMerge(p, &pStruct, nMerge);
|
||||
if( fts5IndexMerge(p, &pStruct, nMerge, nMin) ){
|
||||
fts5StructureWrite(p, pStruct);
|
||||
}
|
||||
}
|
||||
fts5StructureRelease(pStruct);
|
||||
|
||||
}
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
|
@ -1511,13 +1511,13 @@ static int fts5UpdateMethod(
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/* Case 1: DELETE */
|
||||
/* DELETE */
|
||||
else if( nArg==1 ){
|
||||
i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
|
||||
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
|
||||
}
|
||||
|
||||
/* Case 2: INSERT */
|
||||
/* INSERT */
|
||||
else if( eType0!=SQLITE_INTEGER ){
|
||||
/* If this is a REPLACE, first remove the current entry (if any) */
|
||||
if( eConflict==SQLITE_REPLACE
|
||||
@ -1529,7 +1529,7 @@ static int fts5UpdateMethod(
|
||||
fts5StorageInsert(&rc, pTab, apVal, pRowid);
|
||||
}
|
||||
|
||||
/* Case 2: UPDATE */
|
||||
/* UPDATE */
|
||||
else{
|
||||
i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
|
||||
i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
|
||||
|
@ -68,18 +68,22 @@ struct Fts5MatchinfoCtx {
|
||||
** If an error occurs, return NULL and leave an error in the database
|
||||
** handle (accessible using sqlite3_errcode()/errmsg()).
|
||||
*/
|
||||
static fts5_api *fts5_api_from_db(sqlite3 *db){
|
||||
fts5_api *pRet = 0;
|
||||
static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
int rc;
|
||||
|
||||
if( SQLITE_OK==sqlite3_prepare(db, "SELECT fts5()", -1, &pStmt, 0)
|
||||
&& SQLITE_ROW==sqlite3_step(pStmt)
|
||||
&& sizeof(pRet)==sqlite3_column_bytes(pStmt, 0)
|
||||
*ppApi = 0;
|
||||
rc = sqlite3_prepare(db, "SELECT fts5()", -1, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt)
|
||||
&& sizeof(fts5_api*)==sqlite3_column_bytes(pStmt, 0)
|
||||
){
|
||||
memcpy(&pRet, sqlite3_column_blob(pStmt, 0), sizeof(pRet));
|
||||
memcpy(ppApi, sqlite3_column_blob(pStmt, 0), sizeof(fts5_api*));
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return pRet;
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -399,7 +403,8 @@ int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
|
||||
/* Extract the FTS5 API pointer from the database handle. The
|
||||
** fts5_api_from_db() function above is copied verbatim from the
|
||||
** FTS5 documentation. Refer there for details. */
|
||||
pApi = fts5_api_from_db(db);
|
||||
rc = fts5_api_from_db(db, &pApi);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
/* If fts5_api_from_db() returns NULL, then either FTS5 is not registered
|
||||
** with this database handle, or an error (OOM perhaps?) has occurred.
|
||||
|
@ -159,6 +159,12 @@ proc fts5_aux_test_functions {db} {
|
||||
}
|
||||
}
|
||||
|
||||
proc fts5_segcount {tbl} {
|
||||
set N 0
|
||||
foreach n [fts5_level_segs $tbl] { incr N $n }
|
||||
set N
|
||||
}
|
||||
|
||||
proc fts5_level_segs {tbl} {
|
||||
set sql "SELECT fts5_decode(rowid,block) aS r FROM ${tbl}_data WHERE rowid=10"
|
||||
set ret [list]
|
||||
|
@ -45,7 +45,7 @@ proc do_merge1_test {testname nRowPerSeg} {
|
||||
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<$::nRowPerSeg)
|
||||
INSERT INTO x8 SELECT repeat('x y ', i % 16) FROM ii;
|
||||
|
||||
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
|
||||
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
|
||||
}
|
||||
|
||||
for {set tn 1} {[lindex [fts5_level_segs x8] 0]>0} {incr tn} {
|
||||
@ -84,9 +84,9 @@ proc do_merge2_test {testname nRow} {
|
||||
execsql { INSERT INTO x8 VALUES( rnddoc(($i%16) + 5) ) }
|
||||
while {[not_merged x8]} {
|
||||
execsql {
|
||||
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
|
||||
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
|
||||
INSERT INTO x8(x8, rank) VALUES('merge', 1);
|
||||
INSERT INTO x8(x8, rank) VALUES('automerge', 16);
|
||||
INSERT INTO x8(x8, rank) VALUES('usermerge', 16);
|
||||
INSERT INTO x8(x8) VALUES('integrity-check');
|
||||
}
|
||||
}
|
||||
@ -104,9 +104,9 @@ do_merge2_test 2.2 10
|
||||
do_merge2_test 2.3 20
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that an auto-merge will complete any merge that has already been
|
||||
# Test that a merge will complete any merge that has already been
|
||||
# started, even if the number of input segments is less than the current
|
||||
# value of the 'automerge' configuration parameter.
|
||||
# value of the 'usermerge' configuration parameter.
|
||||
#
|
||||
db func rnddoc fts5_rnddoc
|
||||
|
||||
@ -119,7 +119,7 @@ do_execsql_test 3.1 {
|
||||
}
|
||||
do_test 3.2 {
|
||||
execsql {
|
||||
INSERT INTO x8(x8, rank) VALUES('automerge', 4);
|
||||
INSERT INTO x8(x8, rank) VALUES('usermerge', 4);
|
||||
INSERT INTO x8(x8, rank) VALUES('merge', 1);
|
||||
}
|
||||
fts5_level_segs x8
|
||||
@ -127,14 +127,14 @@ do_test 3.2 {
|
||||
|
||||
do_test 3.3 {
|
||||
execsql {
|
||||
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
|
||||
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
|
||||
INSERT INTO x8(x8, rank) VALUES('merge', 1);
|
||||
}
|
||||
fts5_level_segs x8
|
||||
} {2 1}
|
||||
|
||||
do_test 3.4 {
|
||||
execsql { INSERT INTO x8(x8, rank) VALUES('automerge', 4) }
|
||||
execsql { INSERT INTO x8(x8, rank) VALUES('usermerge', 4) }
|
||||
while {[not_merged x8]} {
|
||||
execsql { INSERT INTO x8(x8, rank) VALUES('merge', 1) }
|
||||
}
|
||||
@ -176,7 +176,7 @@ foreach {tn pgsz} {
|
||||
INSERT INTO x8 SELECT mydoc() FROM ii;
|
||||
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
|
||||
INSERT INTO x8 SELECT mydoc() FROM ii;
|
||||
INSERT INTO x8(x8, rank) VALUES('automerge', 2);
|
||||
INSERT INTO x8(x8, rank) VALUES('usermerge', 2);
|
||||
}
|
||||
|
||||
set expect [mycount]
|
||||
@ -190,5 +190,36 @@ foreach {tn pgsz} {
|
||||
# db eval {SELECT fts5_decode(rowid, block) AS r FROM x8_data} { puts $r }
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that the 'merge' command does not modify the database if there is
|
||||
# no work to do.
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
CREATE VIRTUAL TABLE x9 USING fts5(one, two);
|
||||
INSERT INTO x9(x9, rank) VALUES('pgsz', 32);
|
||||
INSERT INTO x9(x9, rank) VALUES('automerge', 2);
|
||||
INSERT INTO x9(x9, rank) VALUES('usermerge', 2);
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
INSERT INTO x9 VALUES(rnddoc(100), rnddoc(100));
|
||||
}
|
||||
|
||||
do_test 5.2 {
|
||||
while 1 {
|
||||
set nChange [db total_changes]
|
||||
execsql { INSERT INTO x9(x9, rank) VALUES('merge', 1); }
|
||||
set nChange [expr [db total_changes] - $nChange]
|
||||
#puts $nChange
|
||||
if {$nChange<2} break
|
||||
}
|
||||
} {}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -37,7 +37,6 @@ foreach {tn nStep} {
|
||||
3 50
|
||||
4 500
|
||||
} {
|
||||
if {$tn!=4} continue
|
||||
reset_db
|
||||
db func rnddoc rnddoc
|
||||
do_execsql_test 1.$tn.1 {
|
||||
@ -60,6 +59,46 @@ if {$tn!=4} continue
|
||||
do_execsql_test 1.$tn.5 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
do_test 1.$tn.6 { fts5_segcount t1 } 1
|
||||
}
|
||||
|
||||
foreach {tn nStep} {
|
||||
1 2
|
||||
2 10
|
||||
3 50
|
||||
4 500
|
||||
} {
|
||||
reset_db
|
||||
db func rnddoc rnddoc
|
||||
do_execsql_test 1.$tn.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, y);
|
||||
}
|
||||
do_test 2.$tn.2 {
|
||||
for {set i 0} {$i < $nStep} {incr i} {
|
||||
execsql { INSERT INTO t1 VALUES( rnddoc(5), rnddoc(5) ) }
|
||||
}
|
||||
} {}
|
||||
|
||||
do_execsql_test 2.$tn.3 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
do_test 2.$tn.4 {
|
||||
execsql { INSERT INTO t1(t1, rank) VALUES('merge', -1) }
|
||||
while 1 {
|
||||
set c [db total_changes]
|
||||
execsql { INSERT INTO t1(t1, rank) VALUES('merge', 1) }
|
||||
set c [expr [db total_changes]-$c]
|
||||
if {$c<2} break
|
||||
}
|
||||
} {}
|
||||
|
||||
do_execsql_test 2.$tn.5 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
do_test 2.$tn.6 { fts5_segcount t1 } 1
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
26
manifest
26
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\sproblem\sin\sfts3/4\sthat\swas\scausing\sit\sto\sdiscard\sdata\scached\sin-memory\sif\san\s'optimize'\scommand\sis\srun\swhen\sthere\sis\sno\sdata\son\sdisk.\sThe\susual\sway\sthis\swould\shappen\sis\sif\sthe\svery\sfirst\stransaction\sthat\swrites\sto\sthe\sfts3/4\stable\salso\sincludes\san\s'optimize'\scommand.
|
||||
D 2016-03-09T18:17:42.821
|
||||
C Add\san\sincremental\soptimize\scapability\sto\sfts5.\sMake\sthe\s'merge'\scommand\sindependent\sof\sthe\s'automerge'\ssettings.
|
||||
D 2016-03-09T20:54:14.606
|
||||
F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
|
||||
@ -98,17 +98,17 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
|
||||
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
|
||||
F ext/fts5/fts5Int.h fa7c17e5c3ec9c8690387ff962f9dc6aee75e114
|
||||
F ext/fts5/fts5Int.h 59e13423371512df1992532a08fe80518244f96b
|
||||
F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 35c5173cae4eb17e82164a7f5aeef56a48903079
|
||||
F ext/fts5/fts5_config.c abd3ae1107ca8b8def7445a0a3b70c2e46d05986
|
||||
F ext/fts5/fts5_expr.c 8e8e4635f655133eb39018072fc0f0942a2c4337
|
||||
F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337
|
||||
F ext/fts5/fts5_index.c 26a4a6112864feb599a6f6144d06a78bb179736a
|
||||
F ext/fts5/fts5_main.c db24ac714c6c4a1b3c24a1f8c25889f2952148c1
|
||||
F ext/fts5/fts5_index.c f7f3c042edf3e6a8984efa95ce1d5305d73bb535
|
||||
F ext/fts5/fts5_main.c b8501e1a6a11591c53b18ce7aea7e5386cfb0421
|
||||
F ext/fts5/fts5_storage.c f8343db90d8c95a4d4b52f6676e354b4649ffd6e
|
||||
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
||||
F ext/fts5/fts5_test_mi.c b8d04816428202b2898d4ca38deb1739ac0110ae
|
||||
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
|
||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||
F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8
|
||||
F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf
|
||||
@ -116,7 +116,7 @@ F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738
|
||||
F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8
|
||||
F ext/fts5/fts5parse.y 86fe6ba094a47e02fe8be2571539e6833d197764
|
||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||
F ext/fts5/test/fts5_common.tcl b9b1fed811c0390511cef8b254826ea15d380f4d
|
||||
F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841
|
||||
F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084
|
||||
F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b
|
||||
F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f
|
||||
@ -162,11 +162,11 @@ F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
|
||||
F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
|
||||
F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d
|
||||
F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b
|
||||
F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367
|
||||
F ext/fts5/test/fts5merge.test 9e04a16963e32bf7c51835ce23e58325bbdfb35f
|
||||
F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75
|
||||
F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc
|
||||
F ext/fts5/test/fts5onepass.test 7ed9608e258132cb8d55e7c479b08676ad68810c
|
||||
F ext/fts5/test/fts5optimize.test 42741e7c085ee0a1276140a752d4407d97c2c9f5
|
||||
F ext/fts5/test/fts5optimize.test 0f25ce4cc1f78a4cf5dd1247d30135b3f7180a19
|
||||
F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f
|
||||
F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436
|
||||
F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
|
||||
@ -1455,7 +1455,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 2c55c3c2950cafdc256ab540f60dc4609b9c354b
|
||||
R b4dbf73ab3865664cce5c88a4214186d
|
||||
P 79338b991bf01e81d336790ca87a0fa747da4ff3
|
||||
R a3916c8b307d01845fad235da028d539
|
||||
U dan
|
||||
Z a31e8746a8bf8afd08aed0fea525a7d3
|
||||
Z 1a31d386083951a3ddfabf8f6c0df92f
|
||||
|
@ -1 +1 @@
|
||||
79338b991bf01e81d336790ca87a0fa747da4ff3
|
||||
556671444c03e3afca072d0f5e9bea2657de6fd3
|
Reference in New Issue
Block a user