| Index: third_party/sqlite/fts2.patch
|
| diff --git a/third_party/sqlite/fts2.patch b/third_party/sqlite/fts2.patch
|
| index 1f02161ee29aba22edad93ad7bba7c244e2dc2a1..f005ddf1126c8c26d2010b83837f41f56e87e227 100644
|
| --- a/third_party/sqlite/fts2.patch
|
| +++ b/third_party/sqlite/fts2.patch
|
| @@ -1,6 +1,7 @@
|
| -diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| ---- ext-orig/fts2/fts2.c 2009-09-04 13:37:41.000000000 -0700
|
| -+++ ext/fts2/fts2.c 2009-09-30 14:48:14.000000000 -0700
|
| +diff --git a/third_party/sqlite/src/ext/fts2/fts2.c b/third_party/sqlite/src/ext/fts2/fts2.c
|
| +index 74c2890..5ec1265 100644
|
| +--- a/third_party/sqlite/src/ext/fts2/fts2.c
|
| ++++ b/third_party/sqlite/src/ext/fts2/fts2.c
|
| @@ -37,6 +37,20 @@
|
| ** This is an SQLite module implementing full-text search.
|
| */
|
| @@ -22,7 +23,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| /*
|
| ** The code in this file is only compiled if:
|
| **
|
| -@@ -335,6 +349,16 @@
|
| +@@ -333,6 +347,16 @@ SQLITE_EXTENSION_INIT1
|
| # define TRACE(A)
|
| #endif
|
|
|
| @@ -39,7 +40,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| /* It is not safe to call isspace(), tolower(), or isalnum() on
|
| ** hi-bit-set characters. This is the same solution used in the
|
| ** tokenizer.
|
| -@@ -423,30 +447,41 @@
|
| +@@ -421,30 +445,41 @@ static int putVarint(char *p, sqlite_int64 v){
|
| /* Read a 64-bit variable-length integer from memory starting at p[0].
|
| * Return the number of bytes read, or 0 on error.
|
| * The value is stored in *v. */
|
| @@ -89,7 +90,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| /*******************************************************************/
|
| /* DataBuffer is used to collect data into a buffer in piecemeal
|
| ** fashion. It implements the usual distinction between amount of
|
| -@@ -615,7 +650,7 @@
|
| +@@ -613,7 +648,7 @@ typedef struct DLReader {
|
|
|
| static int dlrAtEnd(DLReader *pReader){
|
| assert( pReader->nData>=0 );
|
| @@ -98,7 +99,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| static sqlite_int64 dlrDocid(DLReader *pReader){
|
| assert( !dlrAtEnd(pReader) );
|
| -@@ -639,7 +674,8 @@
|
| +@@ -637,7 +672,8 @@ static int dlrAllDataBytes(DLReader *pReader){
|
| */
|
| static const char *dlrPosData(DLReader *pReader){
|
| sqlite_int64 iDummy;
|
| @@ -108,7 +109,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| assert( !dlrAtEnd(pReader) );
|
| return pReader->pData+n;
|
| }
|
| -@@ -649,7 +685,7 @@
|
| +@@ -647,7 +683,7 @@ static int dlrPosDataLen(DLReader *pReader){
|
| assert( !dlrAtEnd(pReader) );
|
| return pReader->nElement-n;
|
| }
|
| @@ -117,7 +118,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| assert( !dlrAtEnd(pReader) );
|
|
|
| /* Skip past current doclist element. */
|
| -@@ -658,32 +694,48 @@
|
| +@@ -656,32 +692,48 @@ static void dlrStep(DLReader *pReader){
|
| pReader->nData -= pReader->nElement;
|
|
|
| /* If there is more data, read the next doclist element. */
|
| @@ -167,19 +168,19 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| assert( pReader->nElement<=pReader->nData );
|
| }
|
| + return SQLITE_OK;
|
| ++}
|
| ++static void dlrDestroy(DLReader *pReader){
|
| ++ SCRAMBLE(pReader);
|
| }
|
| -static void dlrInit(DLReader *pReader, DocListType iType,
|
| - const char *pData, int nData){
|
| -+static void dlrDestroy(DLReader *pReader){
|
| -+ SCRAMBLE(pReader);
|
| -+}
|
| +static int dlrInit(DLReader *pReader, DocListType iType,
|
| + const char *pData, int nData){
|
| + int rc;
|
| assert( pData!=NULL && nData!=0 );
|
| pReader->iType = iType;
|
| pReader->pData = pData;
|
| -@@ -692,10 +744,9 @@
|
| +@@ -690,10 +742,9 @@ static void dlrInit(DLReader *pReader, DocListType iType,
|
| pReader->iDocid = 0;
|
|
|
| /* Load the first element's data. There must be a first element. */
|
| @@ -193,7 +194,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| #ifndef NDEBUG
|
| -@@ -782,9 +833,9 @@
|
| +@@ -780,9 +831,9 @@ static void dlwDestroy(DLWriter *pWriter){
|
| /* TODO(shess) This has become just a helper for docListMerge.
|
| ** Consider a refactor to make this cleaner.
|
| */
|
| @@ -206,7 +207,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| sqlite_int64 iDocid = 0;
|
| char c[VARINT_MAX];
|
| int nFirstOld, nFirstNew; /* Old and new varint len of first docid. */
|
| -@@ -793,7 +844,8 @@
|
| +@@ -791,7 +842,8 @@ static void dlwAppend(DLWriter *pWriter,
|
| #endif
|
|
|
| /* Recode the initial docid as delta from iPrevDocid. */
|
| @@ -216,7 +217,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| assert( nFirstOld<nData || (nFirstOld==nData && pWriter->iType==DL_DOCIDS) );
|
| nFirstNew = putVarint(c, iFirstDocid-pWriter->iPrevDocid);
|
|
|
| -@@ -814,10 +866,11 @@
|
| +@@ -812,10 +864,11 @@ static void dlwAppend(DLWriter *pWriter,
|
| dataBufferAppend(pWriter->b, c, nFirstNew);
|
| }
|
| pWriter->iPrevDocid = iLastDocid;
|
| @@ -231,7 +232,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| static void dlwAdd(DLWriter *pWriter, sqlite_int64 iDocid){
|
| char c[VARINT_MAX];
|
| -@@ -878,45 +931,63 @@
|
| +@@ -876,45 +929,63 @@ static int plrEndOffset(PLReader *pReader){
|
| assert( !plrAtEnd(pReader) );
|
| return pReader->iEndOffset;
|
| }
|
| @@ -309,7 +310,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| pReader->pData = dlrPosData(pDLReader);
|
| pReader->nData = dlrPosDataLen(pDLReader);
|
| pReader->iType = pDLReader->iType;
|
| -@@ -924,10 +995,9 @@
|
| +@@ -922,10 +993,9 @@ static void plrInit(PLReader *pReader, DLReader *pDLReader){
|
| pReader->iPosition = 0;
|
| pReader->iStartOffset = 0;
|
| pReader->iEndOffset = 0;
|
| @@ -323,7 +324,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /*******************************************************************/
|
| -@@ -1113,14 +1183,16 @@
|
| +@@ -1111,14 +1181,16 @@ static void dlcDelete(DLCollector *pCollector){
|
| ** deletion will be trimmed, and will thus not effect a deletion
|
| ** during the merge.
|
| */
|
| @@ -343,7 +344,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| dlwInit(&dlWriter, iOutType, out);
|
|
|
| while( !dlrAtEnd(&dlReader) ){
|
| -@@ -1128,7 +1200,8 @@
|
| +@@ -1126,7 +1198,8 @@ static void docListTrim(DocListType iType, const char *pData, int nData,
|
| PLWriter plWriter;
|
| int match = 0;
|
|
|
| @@ -353,7 +354,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| while( !plrAtEnd(&plReader) ){
|
| if( iColumn==-1 || plrColumn(&plReader)==iColumn ){
|
| -@@ -1139,7 +1212,11 @@
|
| +@@ -1137,7 +1210,11 @@ static void docListTrim(DocListType iType, const char *pData, int nData,
|
| plwAdd(&plWriter, plrColumn(&plReader), plrPosition(&plReader),
|
| plrStartOffset(&plReader), plrEndOffset(&plReader));
|
| }
|
| @@ -366,7 +367,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| if( match ){
|
| plwTerminate(&plWriter);
|
| -@@ -1147,10 +1224,13 @@
|
| +@@ -1145,10 +1222,13 @@ static void docListTrim(DocListType iType, const char *pData, int nData,
|
| }
|
|
|
| plrDestroy(&plReader);
|
| @@ -381,7 +382,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Used by docListMerge() to keep doclists in the ascending order by
|
| -@@ -1207,19 +1287,20 @@
|
| +@@ -1205,19 +1285,20 @@ static void orderedDLReaderReorder(OrderedDLReader *p, int n){
|
| /* TODO(shess) nReaders must be <= MERGE_COUNT. This should probably
|
| ** be fixed.
|
| */
|
| @@ -405,7 +406,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| assert( nReaders<=MERGE_COUNT );
|
| -@@ -1252,20 +1333,23 @@
|
| +@@ -1250,20 +1331,23 @@ static void docListMerge(DataBuffer *out,
|
| nStart += dlrDocDataBytes(readers[0].pReader);
|
| }else{
|
| if( pStart!=0 ){
|
| @@ -432,7 +433,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Get the readers back into order. */
|
| -@@ -1275,8 +1359,11 @@
|
| +@@ -1273,8 +1357,11 @@ static void docListMerge(DataBuffer *out,
|
| }
|
|
|
| /* Copy over any remaining elements. */
|
| @@ -445,7 +446,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Helper function for posListUnion(). Compares the current position
|
| -@@ -1312,30 +1399,40 @@
|
| +@@ -1310,30 +1397,40 @@ static int posListCmp(PLReader *pLeft, PLReader *pRight){
|
| ** work with any doclist type, though both inputs and the output
|
| ** should be the same type.
|
| */
|
| @@ -493,7 +494,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| }
|
|
|
| -@@ -1343,56 +1440,75 @@
|
| +@@ -1341,56 +1438,75 @@ static void posListUnion(DLReader *pLeft, DLReader *pRight, DLWriter *pOut){
|
| plwDestroy(&writer);
|
| plrDestroy(&left);
|
| plrDestroy(&right);
|
| @@ -585,7 +586,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* pLeft and pRight are DLReaders positioned to the same docid.
|
| -@@ -1407,35 +1523,47 @@
|
| +@@ -1405,35 +1521,47 @@ static void docListUnion(
|
| ** include the positions from pRight that are one more than a
|
| ** position in pLeft. In other words: pRight.iPos==pLeft.iPos+1.
|
| */
|
| @@ -643,7 +644,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| }
|
|
|
| -@@ -1446,6 +1574,7 @@
|
| +@@ -1444,6 +1572,7 @@ static void posListPhraseMerge(DLReader *pLeft, DLReader *pRight,
|
|
|
| plrDestroy(&left);
|
| plrDestroy(&right);
|
| @@ -651,7 +652,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* We have two doclists with positions: pLeft and pRight.
|
| -@@ -1457,7 +1586,7 @@
|
| +@@ -1455,7 +1584,7 @@ static void posListPhraseMerge(DLReader *pLeft, DLReader *pRight,
|
| ** iType controls the type of data written to pOut. If iType is
|
| ** DL_POSITIONS, the positions are those from pRight.
|
| */
|
| @@ -660,7 +661,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| const char *pLeft, int nLeft,
|
| const char *pRight, int nRight,
|
| DocListType iType,
|
| -@@ -1465,152 +1594,198 @@
|
| +@@ -1463,152 +1592,198 @@ static void docListPhraseMerge(
|
| ){
|
| DLReader left, right;
|
| DLWriter writer;
|
| @@ -893,7 +894,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| static char *string_dup_n(const char *s, int n){
|
| -@@ -1814,7 +1989,7 @@
|
| +@@ -1812,7 +1987,7 @@ static const char *const fulltext_zStatement[MAX_STMT] = {
|
| /* SEGDIR_MAX_INDEX */ "select max(idx) from %_segdir where level = ?",
|
| /* SEGDIR_SET */ "insert into %_segdir values (?, ?, ?, ?, ?, ?)",
|
| /* SEGDIR_SELECT_LEVEL */
|
| @@ -902,7 +903,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| " where level = ? order by idx",
|
| /* SEGDIR_SPAN */
|
| "select min(start_block), max(end_block) from %_segdir "
|
| -@@ -3413,7 +3588,8 @@
|
| +@@ -3411,7 +3586,8 @@ static int fulltextNext(sqlite3_vtab_cursor *pCursor){
|
| return SQLITE_OK;
|
| }
|
| rc = sqlite3_bind_int64(c->pStmt, 1, dlrDocid(&c->reader));
|
| @@ -912,7 +913,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| if( rc!=SQLITE_OK ) return rc;
|
| /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */
|
| rc = sqlite3_step(c->pStmt);
|
| -@@ -3421,8 +3597,11 @@
|
| +@@ -3419,8 +3595,11 @@ static int fulltextNext(sqlite3_vtab_cursor *pCursor){
|
| c->eof = 0;
|
| return SQLITE_OK;
|
| }
|
| @@ -926,7 +927,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| }
|
|
|
| -@@ -3470,14 +3649,18 @@
|
| +@@ -3468,14 +3647,18 @@ static int docListOfTerm(
|
| return rc;
|
| }
|
| dataBufferInit(&new, 0);
|
| @@ -948,7 +949,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Add a new term pTerm[0..nTerm-1] to the query *q.
|
| -@@ -3544,6 +3727,7 @@
|
| +@@ -3542,6 +3725,7 @@ static int tokenizeSegment(
|
| int firstIndex = pQuery->nTerms;
|
| int iCol;
|
| int nTerm = 1;
|
| @@ -956,7 +957,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| int rc = pModule->xOpen(pTokenizer, pSegment, nSegment, &pCursor);
|
| if( rc!=SQLITE_OK ) return rc;
|
| -@@ -3568,6 +3752,20 @@
|
| +@@ -3566,6 +3750,20 @@ static int tokenizeSegment(
|
| pQuery->nextIsOr = 1;
|
| continue;
|
| }
|
| @@ -977,7 +978,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| queryAdd(pQuery, pToken, nToken);
|
| if( !inPhrase && iBegin>0 && pSegment[iBegin-1]=='-' ){
|
| pQuery->pTerms[pQuery->nTerms-1].isNot = 1;
|
| -@@ -3707,18 +3905,30 @@
|
| +@@ -3705,18 +3903,30 @@ static int fulltextQuery(
|
| return rc;
|
| }
|
| dataBufferInit(&new, 0);
|
| @@ -1010,7 +1011,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| left = new;
|
| }
|
| }
|
| -@@ -3738,9 +3948,15 @@
|
| +@@ -3736,9 +3946,15 @@ static int fulltextQuery(
|
| return rc;
|
| }
|
| dataBufferInit(&new, 0);
|
| @@ -1027,7 +1028,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| left = new;
|
| }
|
|
|
| -@@ -3834,7 +4050,8 @@
|
| +@@ -3832,7 +4048,8 @@ static int fulltextFilter(
|
| rc = fulltextQuery(v, idxNum-QUERY_FULLTEXT, zQuery, -1, &c->result, &c->q);
|
| if( rc!=SQLITE_OK ) return rc;
|
| if( c->result.nData!=0 ){
|
| @@ -1037,7 +1038,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| break;
|
| }
|
| -@@ -4335,22 +4552,19 @@
|
| +@@ -4333,22 +4550,19 @@ static void interiorReaderDestroy(InteriorReader *pReader){
|
| SCRAMBLE(pReader);
|
| }
|
|
|
| @@ -1065,7 +1066,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| pReader->pData = pData+1+n;
|
| pReader->nData = nData-(1+n);
|
|
|
| -@@ -4361,17 +4575,18 @@
|
| +@@ -4359,17 +4573,18 @@ static void interiorReaderInit(const char *pData, int nData,
|
| if( pReader->nData==0 ){
|
| dataBufferInit(&pReader->term, 0);
|
| }else{
|
| @@ -1087,7 +1088,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| static sqlite_int64 interiorReaderCurrentBlockid(InteriorReader *pReader){
|
| -@@ -4388,7 +4603,7 @@
|
| +@@ -4386,7 +4601,7 @@ static const char *interiorReaderTerm(InteriorReader *pReader){
|
| }
|
|
|
| /* Step forward to the next term in the node. */
|
| @@ -1096,7 +1097,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| assert( !interiorReaderAtEnd(pReader) );
|
|
|
| /* If the last term has been read, signal eof, else construct the
|
| -@@ -4399,18 +4614,26 @@
|
| +@@ -4397,18 +4612,26 @@ static void interiorReaderStep(InteriorReader *pReader){
|
| }else{
|
| int n, nPrefix, nSuffix;
|
|
|
| @@ -1129,7 +1130,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Compare the current term to pTerm[nTerm], returning strcmp-style
|
| -@@ -4782,7 +5005,8 @@
|
| +@@ -4780,7 +5003,8 @@ static int leafWriterStepMerge(fulltext_vtab *v, LeafWriter *pWriter,
|
| n = putVarint(c, nData);
|
| dataBufferAppend(&pWriter->data, c, n);
|
|
|
| @@ -1139,7 +1140,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| ASSERT_VALID_DOCLIST(DL_DEFAULT,
|
| pWriter->data.pData+iDoclistData+n,
|
| pWriter->data.nData-iDoclistData-n, NULL);
|
| -@@ -4892,7 +5116,8 @@
|
| +@@ -4890,7 +5114,8 @@ static int leafWriterStep(fulltext_vtab *v, LeafWriter *pWriter,
|
| int rc;
|
| DLReader reader;
|
|
|
| @@ -1149,7 +1150,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| rc = leafWriterStepMerge(v, pWriter, pTerm, nTerm, &reader, 1);
|
| dlrDestroy(&reader);
|
|
|
| -@@ -4937,38 +5162,40 @@
|
| +@@ -4935,38 +5160,40 @@ static int leafReaderDataBytes(LeafReader *pReader){
|
| static const char *leafReaderData(LeafReader *pReader){
|
| int n, nData;
|
| assert( pReader->term.nData>0 );
|
| @@ -1198,7 +1199,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| pReader->pData += n+nData;
|
| pReader->nData -= n+nData;
|
|
|
| -@@ -4976,15 +5203,23 @@
|
| +@@ -4974,15 +5201,23 @@ static void leafReaderStep(LeafReader *pReader){
|
| /* Construct the new term using a prefix from the old term plus a
|
| ** suffix from the leaf data.
|
| */
|
| @@ -1228,7 +1229,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* strcmp-style comparison of pReader's current term against pTerm.
|
| -@@ -5077,6 +5312,9 @@
|
| +@@ -5075,6 +5310,9 @@ static void leavesReaderDestroy(LeavesReader *pReader){
|
| ** the leaf data was entirely contained in the root), or from the
|
| ** stream of blocks between iStartBlockid and iEndBlockid, inclusive.
|
| */
|
| @@ -1238,7 +1239,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| static int leavesReaderInit(fulltext_vtab *v,
|
| int idx,
|
| sqlite_int64 iStartBlockid,
|
| -@@ -5088,32 +5326,67 @@
|
| +@@ -5086,32 +5324,67 @@ static int leavesReaderInit(fulltext_vtab *v,
|
|
|
| dataBufferInit(&pReader->rootData, 0);
|
| if( iStartBlockid==0 ){
|
| @@ -1316,7 +1317,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| return SQLITE_OK;
|
| }
|
| -@@ -5122,11 +5395,12 @@
|
| +@@ -5120,11 +5393,12 @@ static int leavesReaderInit(fulltext_vtab *v,
|
| ** end of the current leaf, step forward to the next leaf block.
|
| */
|
| static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){
|
| @@ -1331,7 +1332,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| if( pReader->rootData.pData ){
|
| pReader->eof = 1;
|
| return SQLITE_OK;
|
| -@@ -5136,10 +5410,25 @@
|
| +@@ -5134,10 +5408,25 @@ static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){
|
| pReader->eof = 1;
|
| return rc==SQLITE_DONE ? SQLITE_OK : rc;
|
| }
|
| @@ -1361,7 +1362,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| return SQLITE_OK;
|
| }
|
| -@@ -5200,8 +5489,19 @@
|
| +@@ -5198,8 +5487,19 @@ static int leavesReadersInit(fulltext_vtab *v, int iLevel,
|
| sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
|
| const char *pRootData = sqlite3_column_blob(s, 2);
|
| int nRootData = sqlite3_column_bytes(s, 2);
|
| @@ -1382,7 +1383,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| rc = leavesReaderInit(v, i, iStart, iEnd, pRootData, nRootData,
|
| &pReaders[i]);
|
| if( rc!=SQLITE_OK ) break;
|
| -@@ -5212,6 +5512,7 @@
|
| +@@ -5210,6 +5510,7 @@ static int leavesReadersInit(fulltext_vtab *v, int iLevel,
|
| while( i-->0 ){
|
| leavesReaderDestroy(&pReaders[i]);
|
| }
|
| @@ -1390,7 +1391,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| return rc;
|
| }
|
|
|
| -@@ -5235,13 +5536,26 @@
|
| +@@ -5233,13 +5534,26 @@ static int leavesReadersMerge(fulltext_vtab *v,
|
| DLReader dlReaders[MERGE_COUNT];
|
| const char *pTerm = leavesReaderTerm(pReaders);
|
| int i, nTerm = leavesReaderTermBytes(pReaders);
|
| @@ -1420,7 +1421,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| return leafWriterStepMerge(v, pWriter, pTerm, nTerm, dlReaders, nReaders);
|
| -@@ -5295,10 +5609,14 @@
|
| +@@ -5293,10 +5607,14 @@ static int segmentMerge(fulltext_vtab *v, int iLevel){
|
| memset(&lrs, '\0', sizeof(lrs));
|
| rc = leavesReadersInit(v, iLevel, lrs, &i);
|
| if( rc!=SQLITE_OK ) return rc;
|
| @@ -1436,7 +1437,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| /* Since leavesReaderReorder() pushes readers at eof to the end,
|
| ** when the first reader is empty, all will be empty.
|
| */
|
| -@@ -5341,12 +5659,14 @@
|
| +@@ -5339,12 +5657,14 @@ static int segmentMerge(fulltext_vtab *v, int iLevel){
|
| }
|
|
|
| /* Accumulate the union of *acc and *pData into *acc. */
|
| @@ -1454,7 +1455,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* TODO(shess) It might be interesting to explore different merge
|
| -@@ -5388,8 +5708,13 @@
|
| +@@ -5386,8 +5706,13 @@ static int loadSegmentLeavesInt(fulltext_vtab *v, LeavesReader *pReader,
|
| int c = leafReaderTermCmp(&pReader->leafReader, pTerm, nTerm, isPrefix);
|
| if( c>0 ) break; /* Past any possible matches. */
|
| if( c==0 ){
|
| @@ -1469,7 +1470,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| /* Find the first empty buffer. */
|
| for(iBuffer=0; iBuffer<nBuffers; ++iBuffer){
|
| -@@ -5435,11 +5760,13 @@
|
| +@@ -5433,11 +5758,13 @@ static int loadSegmentLeavesInt(fulltext_vtab *v, LeavesReader *pReader,
|
| ** with pData/nData.
|
| */
|
| dataBufferSwap(p, pAcc);
|
| @@ -1485,7 +1486,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| /* dataBufferReset() could allow a large doclist to blow up
|
| ** our memory requirements.
|
| -@@ -5464,13 +5791,15 @@
|
| +@@ -5462,13 +5789,15 @@ static int loadSegmentLeavesInt(fulltext_vtab *v, LeavesReader *pReader,
|
| if( out->nData==0 ){
|
| dataBufferSwap(out, &(pBuffers[iBuffer]));
|
| }else{
|
| @@ -1503,7 +1504,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| while( nBuffers-- ){
|
| dataBufferDestroy(&(pBuffers[nBuffers]));
|
| }
|
| -@@ -5529,20 +5858,26 @@
|
| +@@ -5527,20 +5856,26 @@ static int loadSegmentLeaves(fulltext_vtab *v,
|
| ** node. Consider whether breaking symmetry is worthwhile. I suspect
|
| ** it is not worthwhile.
|
| */
|
| @@ -1536,7 +1537,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| *piStartChild = interiorReaderCurrentBlockid(&reader);
|
|
|
| -@@ -5552,7 +5887,11 @@
|
| +@@ -5550,7 +5885,11 @@ static void getChildrenContaining(const char *pData, int nData,
|
| */
|
| while( !interiorReaderAtEnd(&reader) ){
|
| if( interiorReaderTermCmp(&reader, pTerm, nTerm, isPrefix)>0 ) break;
|
| @@ -1549,7 +1550,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
| *piEndChild = interiorReaderCurrentBlockid(&reader);
|
|
|
| -@@ -5561,6 +5900,7 @@
|
| +@@ -5559,6 +5898,7 @@ static void getChildrenContaining(const char *pData, int nData,
|
| /* Children must ascend, and if !prefix, both must be the same. */
|
| assert( *piEndChild>=*piStartChild );
|
| assert( isPrefix || *piStartChild==*piEndChild );
|
| @@ -1557,7 +1558,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Read block at iBlockid and pass it with other params to
|
| -@@ -5588,11 +5928,31 @@
|
| +@@ -5586,11 +5926,31 @@ static int loadAndGetChildrenContaining(
|
| if( rc!=SQLITE_OK ) return rc;
|
|
|
| rc = sqlite3_step(s);
|
| @@ -1592,7 +1593,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| /* We expect only one row. We must execute another sqlite3_step()
|
| * to complete the iteration; otherwise the table will remain
|
| -@@ -5622,8 +5982,9 @@
|
| +@@ -5620,8 +5980,9 @@ static int loadSegmentInt(fulltext_vtab *v, const char *pData, int nData,
|
| /* Process pData as an interior node, then loop down the tree
|
| ** until we find the set of leaf nodes to scan for the term.
|
| */
|
| @@ -1604,7 +1605,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| while( iStartChild>iLeavesEnd ){
|
| sqlite_int64 iNextStart, iNextEnd;
|
| rc = loadAndGetChildrenContaining(v, iStartChild, pTerm, nTerm, isPrefix,
|
| -@@ -5675,7 +6036,8 @@
|
| +@@ -5673,7 +6034,8 @@ static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
|
| DataBuffer result;
|
| int rc;
|
|
|
| @@ -1614,7 +1615,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| /* This code should never be called with buffered updates. */
|
| assert( v->nPendingData<0 );
|
| -@@ -5692,16 +6054,21 @@
|
| +@@ -5690,16 +6052,21 @@ static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
|
| DataBuffer merged;
|
| DLReader readers[2];
|
|
|
| @@ -1644,7 +1645,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| dataBufferDestroy(&result);
|
| return rc;
|
| }
|
| -@@ -5729,11 +6096,20 @@
|
| +@@ -5727,11 +6094,20 @@ static int termSelect(fulltext_vtab *v, int iColumn,
|
| const char *pData = sqlite3_column_blob(s, 2);
|
| const int nData = sqlite3_column_bytes(s, 2);
|
| const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
|
| @@ -1665,7 +1666,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| if( doclist.nData!=0 ){
|
| /* TODO(shess) The old term_select_all() code applied the column
|
| ** restrict as we merged segments, leading to smaller buffers.
|
| -@@ -5741,13 +6117,13 @@
|
| +@@ -5739,13 +6115,13 @@ static int termSelect(fulltext_vtab *v, int iColumn,
|
| ** system is checked in.
|
| */
|
| if( iColumn==v->nColumn) iColumn = -1;
|
| @@ -1682,7 +1683,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| dataBufferDestroy(&doclist);
|
| return rc;
|
| }
|
| -@@ -6089,6 +6465,7 @@
|
| +@@ -6087,6 +6463,7 @@ static int optimizeInternal(fulltext_vtab *v,
|
| LeafWriter *pWriter){
|
| int i, rc = SQLITE_OK;
|
| DataBuffer doclist, merged, tmp;
|
| @@ -1690,7 +1691,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| /* Order the readers. */
|
| i = nReaders;
|
| -@@ -6109,14 +6486,21 @@
|
| +@@ -6107,14 +6484,21 @@ static int optimizeInternal(fulltext_vtab *v,
|
| if( 0!=optLeavesReaderTermCmp(&readers[0], &readers[i]) ) break;
|
| }
|
|
|
| @@ -1716,7 +1717,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }else{
|
| DLReader dlReaders[MERGE_COUNT];
|
| int iReader, nReaders;
|
| -@@ -6124,9 +6508,10 @@
|
| +@@ -6122,9 +6506,10 @@ static int optimizeInternal(fulltext_vtab *v,
|
| /* Prime the pipeline with the first reader's doclist. After
|
| ** one pass index 0 will reference the accumulated doclist.
|
| */
|
| @@ -1730,7 +1731,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| iReader = 1;
|
|
|
| assert( iReader<i ); /* Must execute the loop at least once. */
|
| -@@ -6134,24 +6519,35 @@
|
| +@@ -6132,24 +6517,35 @@ static int optimizeInternal(fulltext_vtab *v,
|
| /* Merge 16 inputs per pass. */
|
| for( nReaders=1; iReader<i && nReaders<MERGE_COUNT;
|
| iReader++, nReaders++ ){
|
| @@ -1775,7 +1776,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Destroy reader that was left in the pipeline. */
|
| -@@ -6159,8 +6555,9 @@
|
| +@@ -6157,8 +6553,9 @@ static int optimizeInternal(fulltext_vtab *v,
|
|
|
| /* Trim deletions from the doclist. */
|
| dataBufferReset(&merged);
|
| @@ -1787,7 +1788,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Only pass doclists with hits (skip if all hits deleted). */
|
| -@@ -6240,6 +6637,14 @@
|
| +@@ -6238,6 +6635,14 @@ static void optimizeFunc(sqlite3_context *pContext,
|
| const char *pRootData = sqlite3_column_blob(s, 2);
|
| int nRootData = sqlite3_column_bytes(s, 2);
|
|
|
| @@ -1802,7 +1803,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| assert( i<nReaders );
|
| rc = leavesReaderInit(v, -1, iStart, iEnd, pRootData, nRootData,
|
| &readers[i].reader);
|
| -@@ -6253,6 +6658,8 @@
|
| +@@ -6251,6 +6656,8 @@ static void optimizeFunc(sqlite3_context *pContext,
|
| if( rc==SQLITE_DONE ){
|
| assert( i==nReaders );
|
| rc = optimizeInternal(v, readers, nReaders, &writer);
|
| @@ -1811,7 +1812,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| while( i-- > 0 ){
|
| -@@ -6316,9 +6723,18 @@
|
| +@@ -6314,9 +6721,18 @@ static int collectSegmentTerms(fulltext_vtab *v, sqlite3_stmt *s,
|
| const sqlite_int64 iEndBlockid = sqlite3_column_int64(s, 1);
|
| const char *pRootData = sqlite3_column_blob(s, 2);
|
| const int nRootData = sqlite3_column_bytes(s, 2);
|
| @@ -1832,7 +1833,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| if( rc!=SQLITE_OK ) return rc;
|
|
|
| while( rc==SQLITE_OK && !leavesReaderAtEnd(&reader) ){
|
| -@@ -6480,16 +6896,19 @@
|
| +@@ -6478,16 +6894,19 @@ static void createDoclistResult(sqlite3_context *pContext,
|
| const char *pData, int nData){
|
| DataBuffer dump;
|
| DLReader dlReader;
|
| @@ -1855,7 +1856,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| if( DL_DEFAULT==DL_DOCIDS || plrAtEnd(&plReader) ){
|
| sqlite3_snprintf(sizeof(buf), buf, "[%lld] ", dlrDocid(&dlReader));
|
| dataBufferAppend(&dump, buf, strlen(buf));
|
| -@@ -6500,7 +6919,8 @@
|
| +@@ -6498,7 +6917,8 @@ static void createDoclistResult(sqlite3_context *pContext,
|
| dlrDocid(&dlReader), iColumn);
|
| dataBufferAppend(&dump, buf, strlen(buf));
|
|
|
| @@ -1865,7 +1866,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| if( plrColumn(&plReader)!=iColumn ){
|
| iColumn = plrColumn(&plReader);
|
| sqlite3_snprintf(sizeof(buf), buf, "] %d[", iColumn);
|
| -@@ -6521,6 +6941,7 @@
|
| +@@ -6519,6 +6939,7 @@ static void createDoclistResult(sqlite3_context *pContext,
|
| dataBufferAppend(&dump, buf, strlen(buf));
|
| }
|
| plrDestroy(&plReader);
|
| @@ -1873,7 +1874,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| assert( dump.nData>0 );
|
| dump.nData--; /* Overwrite trailing space. */
|
| -@@ -6529,6 +6950,10 @@
|
| +@@ -6527,6 +6948,10 @@ static void createDoclistResult(sqlite3_context *pContext,
|
| }
|
| }
|
| dlrDestroy(&dlReader);
|
| @@ -1884,7 +1885,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
|
|
| assert( dump.nData>0 );
|
| dump.nData--; /* Overwrite trailing space. */
|
| -@@ -6540,6 +6965,7 @@
|
| +@@ -6538,6 +6963,7 @@ static void createDoclistResult(sqlite3_context *pContext,
|
| sqlite3_result_text(pContext, dump.pData, dump.nData, sqlite3_free);
|
| dump.pData = NULL;
|
| dump.nData = dump.nCapacity = 0;
|
| @@ -1892,7 +1893,7 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| }
|
|
|
| /* Implements dump_doclist() for use in inspecting the fts2 index from
|
| -@@ -6822,7 +7248,11 @@
|
| +@@ -6820,7 +7246,11 @@ int sqlite3Fts2Init(sqlite3 *db){
|
| ** module with sqlite.
|
| */
|
| if( SQLITE_OK==rc
|
| @@ -1904,10 +1905,11 @@ diff -ru ext-orig/fts2/fts2.c ext/fts2/fts2.c
|
| && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
|
| && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", -1))
|
| && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", -1))
|
| -diff -ru ext-orig/fts2/fts2_icu.c ext/fts2/fts2_icu.c
|
| ---- ext-orig/fts2/fts2_icu.c 2009-09-03 13:32:06.000000000 -0700
|
| -+++ ext/fts2/fts2_icu.c 2009-09-18 14:39:41.000000000 -0700
|
| -@@ -198,7 +198,7 @@
|
| +diff --git a/third_party/sqlite/src/ext/fts2/fts2_icu.c b/third_party/sqlite/src/ext/fts2/fts2_icu.c
|
| +index de8e116..6b9687e 100644
|
| +--- a/third_party/sqlite/src/ext/fts2/fts2_icu.c
|
| ++++ b/third_party/sqlite/src/ext/fts2/fts2_icu.c
|
| +@@ -198,7 +198,7 @@ static int icuNext(
|
|
|
| while( iStart<iEnd ){
|
| int iWhite = iStart;
|
| @@ -1916,10 +1918,11 @@ diff -ru ext-orig/fts2/fts2_icu.c ext/fts2/fts2_icu.c
|
| if( u_isspace(c) ){
|
| iStart = iWhite;
|
| }else{
|
| -diff -ru ext-orig/fts2/fts2_tokenizer.c ext/fts2/fts2_tokenizer.c
|
| ---- ext-orig/fts2/fts2_tokenizer.c 2009-09-03 13:32:06.000000000 -0700
|
| -+++ ext/fts2/fts2_tokenizer.c 2009-09-18 14:39:41.000000000 -0700
|
| -@@ -33,6 +33,7 @@
|
| +diff --git a/third_party/sqlite/src/ext/fts2/fts2_tokenizer.c b/third_party/sqlite/src/ext/fts2/fts2_tokenizer.c
|
| +index f8b0663..00ed365 100644
|
| +--- a/third_party/sqlite/src/ext/fts2/fts2_tokenizer.c
|
| ++++ b/third_party/sqlite/src/ext/fts2/fts2_tokenizer.c
|
| +@@ -33,6 +33,7 @@ SQLITE_EXTENSION_INIT1
|
| #include "fts2_hash.h"
|
| #include "fts2_tokenizer.h"
|
| #include <assert.h>
|
|
|