1 /* fts2 has a design flaw which can lead to database corruption (see
2 ** below).  It is recommended not to use it any longer, instead use
3 ** fts3 (or higher).  If you believe that your use of fts2 is safe,
4 ** add -DSQLITE_ENABLE_BROKEN_FTS2=1 to your CFLAGS.
5 */
6 #if (!defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS2)) \
7         && !defined(SQLITE_ENABLE_BROKEN_FTS2)
8 #error fts2 has a design flaw and has been deprecated.
9 #endif
10 /* The flaw is that fts2 uses the content table's unaliased rowid as
11 ** the unique docid.  fts2 embeds the rowid in the index it builds,
12 ** and expects the rowid to not change.  The SQLite VACUUM operation
13 ** will renumber such rowids, thereby breaking fts2.  If you are using
14 ** fts2 in a system which has disabled VACUUM, then you can continue
15 ** to use it safely.  Note that PRAGMA auto_vacuum does NOT disable
16 ** VACUUM, though systems using auto_vacuum are unlikely to invoke
17 ** VACUUM.
18 **
19 ** Unlike fts1, which is safe across VACUUM if you never delete
20 ** documents, fts2 has a second exposure to this flaw, in the segments
21 ** table.  So fts2 should be considered unsafe across VACUUM in all
22 ** cases.
23 */
24 
25 /*
26 ** 2006 Oct 10
27 **
28 ** The author disclaims copyright to this source code.  In place of
29 ** a legal notice, here is a blessing:
30 **
31 **    May you do good and not evil.
32 **    May you find forgiveness for yourself and forgive others.
33 **    May you share freely, never taking more than you give.
34 **
35 ******************************************************************************
36 **
37 ** This is an SQLite module implementing full-text search.
38 */
39 
40 /*
41 ** The code in this file is only compiled if:
42 **
43 **     * The FTS2 module is being built as an extension
44 **       (in which case SQLITE_CORE is not defined), or
45 **
46 **     * The FTS2 module is being built into the core of
47 **       SQLite (in which case SQLITE_ENABLE_FTS2 is defined).
48 */
49 
50 /* TODO(shess) Consider exporting this comment to an HTML file or the
51 ** wiki.
52 */
53 /* The full-text index is stored in a series of b+tree (-like)
54 ** structures called segments which map terms to doclists.  The
55 ** structures are like b+trees in layout, but are constructed from the
56 ** bottom up in optimal fashion and are not updatable.  Since trees
57 ** are built from the bottom up, things will be described from the
58 ** bottom up.
59 **
60 **
61 **** Varints ****
62 ** The basic unit of encoding is a variable-length integer called a
63 ** varint.  We encode variable-length integers in little-endian order
64 ** using seven bits * per byte as follows:
65 **
66 ** KEY:
67 **         A = 0xxxxxxx    7 bits of data and one flag bit
68 **         B = 1xxxxxxx    7 bits of data and one flag bit
69 **
70 **  7 bits - A
71 ** 14 bits - BA
72 ** 21 bits - BBA
73 ** and so on.
74 **
75 ** This is identical to how sqlite encodes varints (see util.c).
76 **
77 **
78 **** Document lists ****
79 ** A doclist (document list) holds a docid-sorted list of hits for a
80 ** given term.  Doclists hold docids, and can optionally associate
81 ** token positions and offsets with docids.
82 **
83 ** A DL_POSITIONS_OFFSETS doclist is stored like this:
84 **
85 ** array {
86 **   varint docid;
87 **   array {                (position list for column 0)
88 **     varint position;     (delta from previous position plus POS_BASE)
89 **     varint startOffset;  (delta from previous startOffset)
90 **     varint endOffset;    (delta from startOffset)
91 **   }
92 **   array {
93 **     varint POS_COLUMN;   (marks start of position list for new column)
94 **     varint column;       (index of new column)
95 **     array {
96 **       varint position;   (delta from previous position plus POS_BASE)
97 **       varint startOffset;(delta from previous startOffset)
98 **       varint endOffset;  (delta from startOffset)
99 **     }
100 **   }
101 **   varint POS_END;        (marks end of positions for this document.
102 ** }
103 **
104 ** Here, array { X } means zero or more occurrences of X, adjacent in
105 ** memory.  A "position" is an index of a token in the token stream
106 ** generated by the tokenizer, while an "offset" is a byte offset,
107 ** both based at 0.  Note that POS_END and POS_COLUMN occur in the
108 ** same logical place as the position element, and act as sentinals
109 ** ending a position list array.
110 **
111 ** A DL_POSITIONS doclist omits the startOffset and endOffset
112 ** information.  A DL_DOCIDS doclist omits both the position and
113 ** offset information, becoming an array of varint-encoded docids.
114 **
115 ** On-disk data is stored as type DL_DEFAULT, so we don't serialize
116 ** the type.  Due to how deletion is implemented in the segmentation
117 ** system, on-disk doclists MUST store at least positions.
118 **
119 **
120 **** Segment leaf nodes ****
121 ** Segment leaf nodes store terms and doclists, ordered by term.  Leaf
122 ** nodes are written using LeafWriter, and read using LeafReader (to
123 ** iterate through a single leaf node's data) and LeavesReader (to
124 ** iterate through a segment's entire leaf layer).  Leaf nodes have
125 ** the format:
126 **
127 ** varint iHeight;             (height from leaf level, always 0)
128 ** varint nTerm;               (length of first term)
129 ** char pTerm[nTerm];          (content of first term)
130 ** varint nDoclist;            (length of term's associated doclist)
131 ** char pDoclist[nDoclist];    (content of doclist)
132 ** array {
133 **                             (further terms are delta-encoded)
134 **   varint nPrefix;           (length of prefix shared with previous term)
135 **   varint nSuffix;           (length of unshared suffix)
136 **   char pTermSuffix[nSuffix];(unshared suffix of next term)
137 **   varint nDoclist;          (length of term's associated doclist)
138 **   char pDoclist[nDoclist];  (content of doclist)
139 ** }
140 **
141 ** Here, array { X } means zero or more occurrences of X, adjacent in
142 ** memory.
143 **
144 ** Leaf nodes are broken into blocks which are stored contiguously in
145 ** the %_segments table in sorted order.  This means that when the end
146 ** of a node is reached, the next term is in the node with the next
147 ** greater node id.
148 **
149 ** New data is spilled to a new leaf node when the current node
150 ** exceeds LEAF_MAX bytes (default 2048).  New data which itself is
151 ** larger than STANDALONE_MIN (default 1024) is placed in a standalone
152 ** node (a leaf node with a single term and doclist).  The goal of
153 ** these settings is to pack together groups of small doclists while
154 ** making it efficient to directly access large doclists.  The
155 ** assumption is that large doclists represent terms which are more
156 ** likely to be query targets.
157 **
158 ** TODO(shess) It may be useful for blocking decisions to be more
159 ** dynamic.  For instance, it may make more sense to have a 2.5k leaf
160 ** node rather than splitting into 2k and .5k nodes.  My intuition is
161 ** that this might extend through 2x or 4x the pagesize.
162 **
163 **
164 **** Segment interior nodes ****
165 ** Segment interior nodes store blockids for subtree nodes and terms
166 ** to describe what data is stored by the each subtree.  Interior
167 ** nodes are written using InteriorWriter, and read using
168 ** InteriorReader.  InteriorWriters are created as needed when
169 ** SegmentWriter creates new leaf nodes, or when an interior node
170 ** itself grows too big and must be split.  The format of interior
171 ** nodes:
172 **
173 ** varint iHeight;           (height from leaf level, always >0)
174 ** varint iBlockid;          (block id of node's leftmost subtree)
175 ** optional {
176 **   varint nTerm;           (length of first term)
177 **   char pTerm[nTerm];      (content of first term)
178 **   array {
179 **                                (further terms are delta-encoded)
180 **     varint nPrefix;            (length of shared prefix with previous term)
181 **     varint nSuffix;            (length of unshared suffix)
182 **     char pTermSuffix[nSuffix]; (unshared suffix of next term)
183 **   }
184 ** }
185 **
186 ** Here, optional { X } means an optional element, while array { X }
187 ** means zero or more occurrences of X, adjacent in memory.
188 **
189 ** An interior node encodes n terms separating n+1 subtrees.  The
190 ** subtree blocks are contiguous, so only the first subtree's blockid
191 ** is encoded.  The subtree at iBlockid will contain all terms less
192 ** than the first term encoded (or all terms if no term is encoded).
193 ** Otherwise, for terms greater than or equal to pTerm[i] but less
194 ** than pTerm[i+1], the subtree for that term will be rooted at
195 ** iBlockid+i.  Interior nodes only store enough term data to
196 ** distinguish adjacent children (if the rightmost term of the left
197 ** child is "something", and the leftmost term of the right child is
198 ** "wicked", only "w" is stored).
199 **
200 ** New data is spilled to a new interior node at the same height when
201 ** the current node exceeds INTERIOR_MAX bytes (default 2048).
202 ** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing
203 ** interior nodes and making the tree too skinny.  The interior nodes
204 ** at a given height are naturally tracked by interior nodes at
205 ** height+1, and so on.
206 **
207 **
208 **** Segment directory ****
209 ** The segment directory in table %_segdir stores meta-information for
210 ** merging and deleting segments, and also the root node of the
211 ** segment's tree.
212 **
213 ** The root node is the top node of the segment's tree after encoding
214 ** the entire segment, restricted to ROOT_MAX bytes (default 1024).
215 ** This could be either a leaf node or an interior node.  If the top
216 ** node requires more than ROOT_MAX bytes, it is flushed to %_segments
217 ** and a new root interior node is generated (which should always fit
218 ** within ROOT_MAX because it only needs space for 2 varints, the
219 ** height and the blockid of the previous root).
220 **
221 ** The meta-information in the segment directory is:
222 **   level               - segment level (see below)
223 **   idx                 - index within level
224 **                       - (level,idx uniquely identify a segment)
225 **   start_block         - first leaf node
226 **   leaves_end_block    - last leaf node
227 **   end_block           - last block (including interior nodes)
228 **   root                - contents of root node
229 **
230 ** If the root node is a leaf node, then start_block,
231 ** leaves_end_block, and end_block are all 0.
232 **
233 **
234 **** Segment merging ****
235 ** To amortize update costs, segments are groups into levels and
236 ** merged in matches.  Each increase in level represents exponentially
237 ** more documents.
238 **
239 ** New documents (actually, document updates) are tokenized and
240 ** written individually (using LeafWriter) to a level 0 segment, with
241 ** incrementing idx.  When idx reaches MERGE_COUNT (default 16), all
242 ** level 0 segments are merged into a single level 1 segment.  Level 1
243 ** is populated like level 0, and eventually MERGE_COUNT level 1
244 ** segments are merged to a single level 2 segment (representing
245 ** MERGE_COUNT^2 updates), and so on.
246 **
247 ** A segment merge traverses all segments at a given level in
248 ** parallel, performing a straightforward sorted merge.  Since segment
249 ** leaf nodes are written in to the %_segments table in order, this
250 ** merge traverses the underlying sqlite disk structures efficiently.
251 ** After the merge, all segment blocks from the merged level are
252 ** deleted.
253 **
254 ** MERGE_COUNT controls how often we merge segments.  16 seems to be
255 ** somewhat of a sweet spot for insertion performance.  32 and 64 show
256 ** very similar performance numbers to 16 on insertion, though they're
257 ** a tiny bit slower (perhaps due to more overhead in merge-time
258 ** sorting).  8 is about 20% slower than 16, 4 about 50% slower than
259 ** 16, 2 about 66% slower than 16.
260 **
261 ** At query time, high MERGE_COUNT increases the number of segments
262 ** which need to be scanned and merged.  For instance, with 100k docs
263 ** inserted:
264 **
265 **    MERGE_COUNT   segments
266 **       16           25
267 **        8           12
268 **        4           10
269 **        2            6
270 **
271 ** This appears to have only a moderate impact on queries for very
272 ** frequent terms (which are somewhat dominated by segment merge
273 ** costs), and infrequent and non-existent terms still seem to be fast
274 ** even with many segments.
275 **
276 ** TODO(shess) That said, it would be nice to have a better query-side
277 ** argument for MERGE_COUNT of 16.  Also, it is possible/likely that
278 ** optimizations to things like doclist merging will swing the sweet
279 ** spot around.
280 **
281 **
282 **
283 **** Handling of deletions and updates ****
284 ** Since we're using a segmented structure, with no docid-oriented
285 ** index into the term index, we clearly cannot simply update the term
286 ** index when a document is deleted or updated.  For deletions, we
287 ** write an empty doclist (varint(docid) varint(POS_END)), for updates
288 ** we simply write the new doclist.  Segment merges overwrite older
289 ** data for a particular docid with newer data, so deletes or updates
290 ** will eventually overtake the earlier data and knock it out.  The
291 ** query logic likewise merges doclists so that newer data knocks out
292 ** older data.
293 **
294 ** TODO(shess) Provide a VACUUM type operation to clear out all
295 ** deletions and duplications.  This would basically be a forced merge
296 ** into a single segment.
297 */
298 
299 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS2)
300 
301 #if defined(SQLITE_ENABLE_FTS2) && !defined(SQLITE_CORE)
302 # define SQLITE_CORE 1
303 #endif
304 
305 #include <assert.h>
306 #include <stdlib.h>
307 #include <stdio.h>
308 #include <string.h>
309 #include "fts2.h"
310 #include "fts2_hash.h"
311 #include "fts2_tokenizer.h"
312 #include "sqlite3.h"
313 #include "sqlite3ext.h"
314 SQLITE_EXTENSION_INIT1
315 
316 
317 /* TODO(shess) MAN, this thing needs some refactoring.  At minimum, it
318 ** would be nice to order the file better, perhaps something along the
319 ** lines of:
320 **
321 **  - utility functions
322 **  - table setup functions
323 **  - table update functions
324 **  - table query functions
325 **
326 ** Put the query functions last because they're likely to reference
327 ** typedefs or functions from the table update section.
328 */
329 
330 #if 0
331 # define TRACE(A)  printf A; fflush(stdout)
332 #else
333 # define TRACE(A)
334 #endif
335 
336 /* It is not safe to call isspace(), tolower(), or isalnum() on
337 ** hi-bit-set characters.  This is the same solution used in the
338 ** tokenizer.
339 */
340 /* TODO(shess) The snippet-generation code should be using the
341 ** tokenizer-generated tokens rather than doing its own local
342 ** tokenization.
343 */
344 /* TODO(shess) Is __isascii() a portable version of (c&0x80)==0? */
safe_isspace(char c)345 static int safe_isspace(char c){
346   return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
347 }
safe_tolower(char c)348 static int safe_tolower(char c){
349   return (c>='A' && c<='Z') ? (c - 'A' + 'a') : c;
350 }
safe_isalnum(char c)351 static int safe_isalnum(char c){
352   return (c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z');
353 }
354 
355 typedef enum DocListType {
356   DL_DOCIDS,              /* docids only */
357   DL_POSITIONS,           /* docids + positions */
358   DL_POSITIONS_OFFSETS    /* docids + positions + offsets */
359 } DocListType;
360 
361 /*
362 ** By default, only positions and not offsets are stored in the doclists.
363 ** To change this so that offsets are stored too, compile with
364 **
365 **          -DDL_DEFAULT=DL_POSITIONS_OFFSETS
366 **
367 ** If DL_DEFAULT is set to DL_DOCIDS, your table can only be inserted
368 ** into (no deletes or updates).
369 */
370 #ifndef DL_DEFAULT
371 # define DL_DEFAULT DL_POSITIONS
372 #endif
373 
374 enum {
375   POS_END = 0,        /* end of this position list */
376   POS_COLUMN,         /* followed by new column number */
377   POS_BASE
378 };
379 
380 /* MERGE_COUNT controls how often we merge segments (see comment at
381 ** top of file).
382 */
383 #define MERGE_COUNT 16
384 
385 /* utility functions */
386 
387 /* CLEAR() and SCRAMBLE() abstract memset() on a pointer to a single
388 ** record to prevent errors of the form:
389 **
390 ** my_function(SomeType *b){
391 **   memset(b, '\0', sizeof(b));  // sizeof(b)!=sizeof(*b)
392 ** }
393 */
394 /* TODO(shess) Obvious candidates for a header file. */
395 #define CLEAR(b) memset(b, '\0', sizeof(*(b)))
396 
397 #ifndef NDEBUG
398 #  define SCRAMBLE(b) memset(b, 0x55, sizeof(*(b)))
399 #else
400 #  define SCRAMBLE(b)
401 #endif
402 
403 /* We may need up to VARINT_MAX bytes to store an encoded 64-bit integer. */
404 #define VARINT_MAX 10
405 
406 /* Write a 64-bit variable-length integer to memory starting at p[0].
407  * The length of data written will be between 1 and VARINT_MAX bytes.
408  * The number of bytes written is returned. */
putVarint(char * p,sqlite_int64 v)409 static int putVarint(char *p, sqlite_int64 v){
410   unsigned char *q = (unsigned char *) p;
411   sqlite_uint64 vu = v;
412   do{
413     *q++ = (unsigned char) ((vu & 0x7f) | 0x80);
414     vu >>= 7;
415   }while( vu!=0 );
416   q[-1] &= 0x7f;  /* turn off high bit in final byte */
417   assert( q - (unsigned char *)p <= VARINT_MAX );
418   return (int) (q - (unsigned char *)p);
419 }
420 
421 /* Read a 64-bit variable-length integer from memory starting at p[0].
422  * Return the number of bytes read, or 0 on error.
423  * The value is stored in *v. */
getVarint(const char * p,sqlite_int64 * v)424 static int getVarint(const char *p, sqlite_int64 *v){
425   const unsigned char *q = (const unsigned char *) p;
426   sqlite_uint64 x = 0, y = 1;
427   while( (*q & 0x80) == 0x80 ){
428     x += y * (*q++ & 0x7f);
429     y <<= 7;
430     if( q - (unsigned char *)p >= VARINT_MAX ){  /* bad data */
431       assert( 0 );
432       return 0;
433     }
434   }
435   x += y * (*q++);
436   *v = (sqlite_int64) x;
437   return (int) (q - (unsigned char *)p);
438 }
439 
getVarint32(const char * p,int * pi)440 static int getVarint32(const char *p, int *pi){
441  sqlite_int64 i;
442  int ret = getVarint(p, &i);
443  *pi = (int) i;
444  assert( *pi==i );
445  return ret;
446 }
447 
448 /*******************************************************************/
449 /* DataBuffer is used to collect data into a buffer in piecemeal
450 ** fashion.  It implements the usual distinction between amount of
451 ** data currently stored (nData) and buffer capacity (nCapacity).
452 **
453 ** dataBufferInit - create a buffer with given initial capacity.
454 ** dataBufferReset - forget buffer's data, retaining capacity.
455 ** dataBufferDestroy - free buffer's data.
456 ** dataBufferSwap - swap contents of two buffers.
457 ** dataBufferExpand - expand capacity without adding data.
458 ** dataBufferAppend - append data.
459 ** dataBufferAppend2 - append two pieces of data at once.
460 ** dataBufferReplace - replace buffer's data.
461 */
462 typedef struct DataBuffer {
463   char *pData;          /* Pointer to malloc'ed buffer. */
464   int nCapacity;        /* Size of pData buffer. */
465   int nData;            /* End of data loaded into pData. */
466 } DataBuffer;
467 
dataBufferInit(DataBuffer * pBuffer,int nCapacity)468 static void dataBufferInit(DataBuffer *pBuffer, int nCapacity){
469   assert( nCapacity>=0 );
470   pBuffer->nData = 0;
471   pBuffer->nCapacity = nCapacity;
472   pBuffer->pData = nCapacity==0 ? NULL : sqlite3_malloc(nCapacity);
473 }
dataBufferReset(DataBuffer * pBuffer)474 static void dataBufferReset(DataBuffer *pBuffer){
475   pBuffer->nData = 0;
476 }
dataBufferDestroy(DataBuffer * pBuffer)477 static void dataBufferDestroy(DataBuffer *pBuffer){
478   if( pBuffer->pData!=NULL ) sqlite3_free(pBuffer->pData);
479   SCRAMBLE(pBuffer);
480 }
dataBufferSwap(DataBuffer * pBuffer1,DataBuffer * pBuffer2)481 static void dataBufferSwap(DataBuffer *pBuffer1, DataBuffer *pBuffer2){
482   DataBuffer tmp = *pBuffer1;
483   *pBuffer1 = *pBuffer2;
484   *pBuffer2 = tmp;
485 }
dataBufferExpand(DataBuffer * pBuffer,int nAddCapacity)486 static void dataBufferExpand(DataBuffer *pBuffer, int nAddCapacity){
487   assert( nAddCapacity>0 );
488   /* TODO(shess) Consider expanding more aggressively.  Note that the
489   ** underlying malloc implementation may take care of such things for
490   ** us already.
491   */
492   if( pBuffer->nData+nAddCapacity>pBuffer->nCapacity ){
493     pBuffer->nCapacity = pBuffer->nData+nAddCapacity;
494     pBuffer->pData = sqlite3_realloc(pBuffer->pData, pBuffer->nCapacity);
495   }
496 }
dataBufferAppend(DataBuffer * pBuffer,const char * pSource,int nSource)497 static void dataBufferAppend(DataBuffer *pBuffer,
498                              const char *pSource, int nSource){
499   assert( nSource>0 && pSource!=NULL );
500   dataBufferExpand(pBuffer, nSource);
501   memcpy(pBuffer->pData+pBuffer->nData, pSource, nSource);
502   pBuffer->nData += nSource;
503 }
dataBufferAppend2(DataBuffer * pBuffer,const char * pSource1,int nSource1,const char * pSource2,int nSource2)504 static void dataBufferAppend2(DataBuffer *pBuffer,
505                               const char *pSource1, int nSource1,
506                               const char *pSource2, int nSource2){
507   assert( nSource1>0 && pSource1!=NULL );
508   assert( nSource2>0 && pSource2!=NULL );
509   dataBufferExpand(pBuffer, nSource1+nSource2);
510   memcpy(pBuffer->pData+pBuffer->nData, pSource1, nSource1);
511   memcpy(pBuffer->pData+pBuffer->nData+nSource1, pSource2, nSource2);
512   pBuffer->nData += nSource1+nSource2;
513 }
dataBufferReplace(DataBuffer * pBuffer,const char * pSource,int nSource)514 static void dataBufferReplace(DataBuffer *pBuffer,
515                               const char *pSource, int nSource){
516   dataBufferReset(pBuffer);
517   dataBufferAppend(pBuffer, pSource, nSource);
518 }
519 
520 /* StringBuffer is a null-terminated version of DataBuffer. */
521 typedef struct StringBuffer {
522   DataBuffer b;            /* Includes null terminator. */
523 } StringBuffer;
524 
initStringBuffer(StringBuffer * sb)525 static void initStringBuffer(StringBuffer *sb){
526   dataBufferInit(&sb->b, 100);
527   dataBufferReplace(&sb->b, "", 1);
528 }
stringBufferLength(StringBuffer * sb)529 static int stringBufferLength(StringBuffer *sb){
530   return sb->b.nData-1;
531 }
stringBufferData(StringBuffer * sb)532 static char *stringBufferData(StringBuffer *sb){
533   return sb->b.pData;
534 }
stringBufferDestroy(StringBuffer * sb)535 static void stringBufferDestroy(StringBuffer *sb){
536   dataBufferDestroy(&sb->b);
537 }
538 
nappend(StringBuffer * sb,const char * zFrom,int nFrom)539 static void nappend(StringBuffer *sb, const char *zFrom, int nFrom){
540   assert( sb->b.nData>0 );
541   if( nFrom>0 ){
542     sb->b.nData--;
543     dataBufferAppend2(&sb->b, zFrom, nFrom, "", 1);
544   }
545 }
append(StringBuffer * sb,const char * zFrom)546 static void append(StringBuffer *sb, const char *zFrom){
547   nappend(sb, zFrom, strlen(zFrom));
548 }
549 
550 /* Append a list of strings separated by commas. */
appendList(StringBuffer * sb,int nString,char ** azString)551 static void appendList(StringBuffer *sb, int nString, char **azString){
552   int i;
553   for(i=0; i<nString; ++i){
554     if( i>0 ) append(sb, ", ");
555     append(sb, azString[i]);
556   }
557 }
558 
endsInWhiteSpace(StringBuffer * p)559 static int endsInWhiteSpace(StringBuffer *p){
560   return stringBufferLength(p)>0 &&
561     safe_isspace(stringBufferData(p)[stringBufferLength(p)-1]);
562 }
563 
564 /* If the StringBuffer ends in something other than white space, add a
565 ** single space character to the end.
566 */
appendWhiteSpace(StringBuffer * p)567 static void appendWhiteSpace(StringBuffer *p){
568   if( stringBufferLength(p)==0 ) return;
569   if( !endsInWhiteSpace(p) ) append(p, " ");
570 }
571 
572 /* Remove white space from the end of the StringBuffer */
trimWhiteSpace(StringBuffer * p)573 static void trimWhiteSpace(StringBuffer *p){
574   while( endsInWhiteSpace(p) ){
575     p->b.pData[--p->b.nData-1] = '\0';
576   }
577 }
578 
579 /*******************************************************************/
580 /* DLReader is used to read document elements from a doclist.  The
581 ** current docid is cached, so dlrDocid() is fast.  DLReader does not
582 ** own the doclist buffer.
583 **
584 ** dlrAtEnd - true if there's no more data to read.
585 ** dlrDocid - docid of current document.
586 ** dlrDocData - doclist data for current document (including docid).
587 ** dlrDocDataBytes - length of same.
588 ** dlrAllDataBytes - length of all remaining data.
589 ** dlrPosData - position data for current document.
590 ** dlrPosDataLen - length of pos data for current document (incl POS_END).
591 ** dlrStep - step to current document.
592 ** dlrInit - initial for doclist of given type against given data.
593 ** dlrDestroy - clean up.
594 **
595 ** Expected usage is something like:
596 **
597 **   DLReader reader;
598 **   dlrInit(&reader, pData, nData);
599 **   while( !dlrAtEnd(&reader) ){
600 **     // calls to dlrDocid() and kin.
601 **     dlrStep(&reader);
602 **   }
603 **   dlrDestroy(&reader);
604 */
605 typedef struct DLReader {
606   DocListType iType;
607   const char *pData;
608   int nData;
609 
610   sqlite_int64 iDocid;
611   int nElement;
612 } DLReader;
613 
dlrAtEnd(DLReader * pReader)614 static int dlrAtEnd(DLReader *pReader){
615   assert( pReader->nData>=0 );
616   return pReader->nData==0;
617 }
dlrDocid(DLReader * pReader)618 static sqlite_int64 dlrDocid(DLReader *pReader){
619   assert( !dlrAtEnd(pReader) );
620   return pReader->iDocid;
621 }
dlrDocData(DLReader * pReader)622 static const char *dlrDocData(DLReader *pReader){
623   assert( !dlrAtEnd(pReader) );
624   return pReader->pData;
625 }
dlrDocDataBytes(DLReader * pReader)626 static int dlrDocDataBytes(DLReader *pReader){
627   assert( !dlrAtEnd(pReader) );
628   return pReader->nElement;
629 }
dlrAllDataBytes(DLReader * pReader)630 static int dlrAllDataBytes(DLReader *pReader){
631   assert( !dlrAtEnd(pReader) );
632   return pReader->nData;
633 }
634 /* TODO(shess) Consider adding a field to track iDocid varint length
635 ** to make these two functions faster.  This might matter (a tiny bit)
636 ** for queries.
637 */
dlrPosData(DLReader * pReader)638 static const char *dlrPosData(DLReader *pReader){
639   sqlite_int64 iDummy;
640   int n = getVarint(pReader->pData, &iDummy);
641   assert( !dlrAtEnd(pReader) );
642   return pReader->pData+n;
643 }
dlrPosDataLen(DLReader * pReader)644 static int dlrPosDataLen(DLReader *pReader){
645   sqlite_int64 iDummy;
646   int n = getVarint(pReader->pData, &iDummy);
647   assert( !dlrAtEnd(pReader) );
648   return pReader->nElement-n;
649 }
dlrStep(DLReader * pReader)650 static void dlrStep(DLReader *pReader){
651   assert( !dlrAtEnd(pReader) );
652 
653   /* Skip past current doclist element. */
654   assert( pReader->nElement<=pReader->nData );
655   pReader->pData += pReader->nElement;
656   pReader->nData -= pReader->nElement;
657 
658   /* If there is more data, read the next doclist element. */
659   if( pReader->nData!=0 ){
660     sqlite_int64 iDocidDelta;
661     int iDummy, n = getVarint(pReader->pData, &iDocidDelta);
662     pReader->iDocid += iDocidDelta;
663     if( pReader->iType>=DL_POSITIONS ){
664       assert( n<pReader->nData );
665       while( 1 ){
666         n += getVarint32(pReader->pData+n, &iDummy);
667         assert( n<=pReader->nData );
668         if( iDummy==POS_END ) break;
669         if( iDummy==POS_COLUMN ){
670           n += getVarint32(pReader->pData+n, &iDummy);
671           assert( n<pReader->nData );
672         }else if( pReader->iType==DL_POSITIONS_OFFSETS ){
673           n += getVarint32(pReader->pData+n, &iDummy);
674           n += getVarint32(pReader->pData+n, &iDummy);
675           assert( n<pReader->nData );
676         }
677       }
678     }
679     pReader->nElement = n;
680     assert( pReader->nElement<=pReader->nData );
681   }
682 }
dlrInit(DLReader * pReader,DocListType iType,const char * pData,int nData)683 static void dlrInit(DLReader *pReader, DocListType iType,
684                     const char *pData, int nData){
685   assert( pData!=NULL && nData!=0 );
686   pReader->iType = iType;
687   pReader->pData = pData;
688   pReader->nData = nData;
689   pReader->nElement = 0;
690   pReader->iDocid = 0;
691 
692   /* Load the first element's data.  There must be a first element. */
693   dlrStep(pReader);
694 }
dlrDestroy(DLReader * pReader)695 static void dlrDestroy(DLReader *pReader){
696   SCRAMBLE(pReader);
697 }
698 
699 #ifndef NDEBUG
700 /* Verify that the doclist can be validly decoded.  Also returns the
701 ** last docid found because it is convenient in other assertions for
702 ** DLWriter.
703 */
docListValidate(DocListType iType,const char * pData,int nData,sqlite_int64 * pLastDocid)704 static void docListValidate(DocListType iType, const char *pData, int nData,
705                             sqlite_int64 *pLastDocid){
706   sqlite_int64 iPrevDocid = 0;
707   assert( nData>0 );
708   assert( pData!=0 );
709   assert( pData+nData>pData );
710   while( nData!=0 ){
711     sqlite_int64 iDocidDelta;
712     int n = getVarint(pData, &iDocidDelta);
713     iPrevDocid += iDocidDelta;
714     if( iType>DL_DOCIDS ){
715       int iDummy;
716       while( 1 ){
717         n += getVarint32(pData+n, &iDummy);
718         if( iDummy==POS_END ) break;
719         if( iDummy==POS_COLUMN ){
720           n += getVarint32(pData+n, &iDummy);
721         }else if( iType>DL_POSITIONS ){
722           n += getVarint32(pData+n, &iDummy);
723           n += getVarint32(pData+n, &iDummy);
724         }
725         assert( n<=nData );
726       }
727     }
728     assert( n<=nData );
729     pData += n;
730     nData -= n;
731   }
732   if( pLastDocid ) *pLastDocid = iPrevDocid;
733 }
734 #define ASSERT_VALID_DOCLIST(i, p, n, o) docListValidate(i, p, n, o)
735 #else
736 #define ASSERT_VALID_DOCLIST(i, p, n, o) assert( 1 )
737 #endif
738 
739 /*******************************************************************/
740 /* DLWriter is used to write doclist data to a DataBuffer.  DLWriter
741 ** always appends to the buffer and does not own it.
742 **
743 ** dlwInit - initialize to write a given type doclistto a buffer.
744 ** dlwDestroy - clear the writer's memory.  Does not free buffer.
745 ** dlwAppend - append raw doclist data to buffer.
746 ** dlwCopy - copy next doclist from reader to writer.
747 ** dlwAdd - construct doclist element and append to buffer.
748 **    Only apply dlwAdd() to DL_DOCIDS doclists (else use PLWriter).
749 */
750 typedef struct DLWriter {
751   DocListType iType;
752   DataBuffer *b;
753   sqlite_int64 iPrevDocid;
754 #ifndef NDEBUG
755   int has_iPrevDocid;
756 #endif
757 } DLWriter;
758 
dlwInit(DLWriter * pWriter,DocListType iType,DataBuffer * b)759 static void dlwInit(DLWriter *pWriter, DocListType iType, DataBuffer *b){
760   pWriter->b = b;
761   pWriter->iType = iType;
762   pWriter->iPrevDocid = 0;
763 #ifndef NDEBUG
764   pWriter->has_iPrevDocid = 0;
765 #endif
766 }
dlwDestroy(DLWriter * pWriter)767 static void dlwDestroy(DLWriter *pWriter){
768   SCRAMBLE(pWriter);
769 }
770 /* iFirstDocid is the first docid in the doclist in pData.  It is
771 ** needed because pData may point within a larger doclist, in which
772 ** case the first item would be delta-encoded.
773 **
774 ** iLastDocid is the final docid in the doclist in pData.  It is
775 ** needed to create the new iPrevDocid for future delta-encoding.  The
776 ** code could decode the passed doclist to recreate iLastDocid, but
777 ** the only current user (docListMerge) already has decoded this
778 ** information.
779 */
780 /* TODO(shess) This has become just a helper for docListMerge.
781 ** Consider a refactor to make this cleaner.
782 */
dlwAppend(DLWriter * pWriter,const char * pData,int nData,sqlite_int64 iFirstDocid,sqlite_int64 iLastDocid)783 static void dlwAppend(DLWriter *pWriter,
784                       const char *pData, int nData,
785                       sqlite_int64 iFirstDocid, sqlite_int64 iLastDocid){
786   sqlite_int64 iDocid = 0;
787   char c[VARINT_MAX];
788   int nFirstOld, nFirstNew;     /* Old and new varint len of first docid. */
789 #ifndef NDEBUG
790   sqlite_int64 iLastDocidDelta;
791 #endif
792 
793   /* Recode the initial docid as delta from iPrevDocid. */
794   nFirstOld = getVarint(pData, &iDocid);
795   assert( nFirstOld<nData || (nFirstOld==nData && pWriter->iType==DL_DOCIDS) );
796   nFirstNew = putVarint(c, iFirstDocid-pWriter->iPrevDocid);
797 
798   /* Verify that the incoming doclist is valid AND that it ends with
799   ** the expected docid.  This is essential because we'll trust this
800   ** docid in future delta-encoding.
801   */
802   ASSERT_VALID_DOCLIST(pWriter->iType, pData, nData, &iLastDocidDelta);
803   assert( iLastDocid==iFirstDocid-iDocid+iLastDocidDelta );
804 
805   /* Append recoded initial docid and everything else.  Rest of docids
806   ** should have been delta-encoded from previous initial docid.
807   */
808   if( nFirstOld<nData ){
809     dataBufferAppend2(pWriter->b, c, nFirstNew,
810                       pData+nFirstOld, nData-nFirstOld);
811   }else{
812     dataBufferAppend(pWriter->b, c, nFirstNew);
813   }
814   pWriter->iPrevDocid = iLastDocid;
815 }
dlwCopy(DLWriter * pWriter,DLReader * pReader)816 static void dlwCopy(DLWriter *pWriter, DLReader *pReader){
817   dlwAppend(pWriter, dlrDocData(pReader), dlrDocDataBytes(pReader),
818             dlrDocid(pReader), dlrDocid(pReader));
819 }
dlwAdd(DLWriter * pWriter,sqlite_int64 iDocid)820 static void dlwAdd(DLWriter *pWriter, sqlite_int64 iDocid){
821   char c[VARINT_MAX];
822   int n = putVarint(c, iDocid-pWriter->iPrevDocid);
823 
824   /* Docids must ascend. */
825   assert( !pWriter->has_iPrevDocid || iDocid>pWriter->iPrevDocid );
826   assert( pWriter->iType==DL_DOCIDS );
827 
828   dataBufferAppend(pWriter->b, c, n);
829   pWriter->iPrevDocid = iDocid;
830 #ifndef NDEBUG
831   pWriter->has_iPrevDocid = 1;
832 #endif
833 }
834 
835 /*******************************************************************/
836 /* PLReader is used to read data from a document's position list.  As
837 ** the caller steps through the list, data is cached so that varints
838 ** only need to be decoded once.
839 **
840 ** plrInit, plrDestroy - create/destroy a reader.
841 ** plrColumn, plrPosition, plrStartOffset, plrEndOffset - accessors
842 ** plrAtEnd - at end of stream, only call plrDestroy once true.
843 ** plrStep - step to the next element.
844 */
845 typedef struct PLReader {
846   /* These refer to the next position's data.  nData will reach 0 when
847   ** reading the last position, so plrStep() signals EOF by setting
848   ** pData to NULL.
849   */
850   const char *pData;
851   int nData;
852 
853   DocListType iType;
854   int iColumn;         /* the last column read */
855   int iPosition;       /* the last position read */
856   int iStartOffset;    /* the last start offset read */
857   int iEndOffset;      /* the last end offset read */
858 } PLReader;
859 
plrAtEnd(PLReader * pReader)860 static int plrAtEnd(PLReader *pReader){
861   return pReader->pData==NULL;
862 }
plrColumn(PLReader * pReader)863 static int plrColumn(PLReader *pReader){
864   assert( !plrAtEnd(pReader) );
865   return pReader->iColumn;
866 }
plrPosition(PLReader * pReader)867 static int plrPosition(PLReader *pReader){
868   assert( !plrAtEnd(pReader) );
869   return pReader->iPosition;
870 }
plrStartOffset(PLReader * pReader)871 static int plrStartOffset(PLReader *pReader){
872   assert( !plrAtEnd(pReader) );
873   return pReader->iStartOffset;
874 }
plrEndOffset(PLReader * pReader)875 static int plrEndOffset(PLReader *pReader){
876   assert( !plrAtEnd(pReader) );
877   return pReader->iEndOffset;
878 }
plrStep(PLReader * pReader)879 static void plrStep(PLReader *pReader){
880   int i, n;
881 
882   assert( !plrAtEnd(pReader) );
883 
884   if( pReader->nData==0 ){
885     pReader->pData = NULL;
886     return;
887   }
888 
889   n = getVarint32(pReader->pData, &i);
890   if( i==POS_COLUMN ){
891     n += getVarint32(pReader->pData+n, &pReader->iColumn);
892     pReader->iPosition = 0;
893     pReader->iStartOffset = 0;
894     n += getVarint32(pReader->pData+n, &i);
895   }
896   /* Should never see adjacent column changes. */
897   assert( i!=POS_COLUMN );
898 
899   if( i==POS_END ){
900     pReader->nData = 0;
901     pReader->pData = NULL;
902     return;
903   }
904 
905   pReader->iPosition += i-POS_BASE;
906   if( pReader->iType==DL_POSITIONS_OFFSETS ){
907     n += getVarint32(pReader->pData+n, &i);
908     pReader->iStartOffset += i;
909     n += getVarint32(pReader->pData+n, &i);
910     pReader->iEndOffset = pReader->iStartOffset+i;
911   }
912   assert( n<=pReader->nData );
913   pReader->pData += n;
914   pReader->nData -= n;
915 }
916 
plrInit(PLReader * pReader,DLReader * pDLReader)917 static void plrInit(PLReader *pReader, DLReader *pDLReader){
918   pReader->pData = dlrPosData(pDLReader);
919   pReader->nData = dlrPosDataLen(pDLReader);
920   pReader->iType = pDLReader->iType;
921   pReader->iColumn = 0;
922   pReader->iPosition = 0;
923   pReader->iStartOffset = 0;
924   pReader->iEndOffset = 0;
925   plrStep(pReader);
926 }
plrDestroy(PLReader * pReader)927 static void plrDestroy(PLReader *pReader){
928   SCRAMBLE(pReader);
929 }
930 
931 /*******************************************************************/
932 /* PLWriter is used in constructing a document's position list.  As a
933 ** convenience, if iType is DL_DOCIDS, PLWriter becomes a no-op.
934 ** PLWriter writes to the associated DLWriter's buffer.
935 **
936 ** plwInit - init for writing a document's poslist.
937 ** plwDestroy - clear a writer.
938 ** plwAdd - append position and offset information.
939 ** plwCopy - copy next position's data from reader to writer.
940 ** plwTerminate - add any necessary doclist terminator.
941 **
942 ** Calling plwAdd() after plwTerminate() may result in a corrupt
943 ** doclist.
944 */
945 /* TODO(shess) Until we've written the second item, we can cache the
946 ** first item's information.  Then we'd have three states:
947 **
948 ** - initialized with docid, no positions.
949 ** - docid and one position.
950 ** - docid and multiple positions.
951 **
952 ** Only the last state needs to actually write to dlw->b, which would
953 ** be an improvement in the DLCollector case.
954 */
955 typedef struct PLWriter {
956   DLWriter *dlw;
957 
958   int iColumn;    /* the last column written */
959   int iPos;       /* the last position written */
960   int iOffset;    /* the last start offset written */
961 } PLWriter;
962 
963 /* TODO(shess) In the case where the parent is reading these values
964 ** from a PLReader, we could optimize to a copy if that PLReader has
965 ** the same type as pWriter.
966 */
plwAdd(PLWriter * pWriter,int iColumn,int iPos,int iStartOffset,int iEndOffset)967 static void plwAdd(PLWriter *pWriter, int iColumn, int iPos,
968                    int iStartOffset, int iEndOffset){
969   /* Worst-case space for POS_COLUMN, iColumn, iPosDelta,
970   ** iStartOffsetDelta, and iEndOffsetDelta.
971   */
972   char c[5*VARINT_MAX];
973   int n = 0;
974 
975   /* Ban plwAdd() after plwTerminate(). */
976   assert( pWriter->iPos!=-1 );
977 
978   if( pWriter->dlw->iType==DL_DOCIDS ) return;
979 
980   if( iColumn!=pWriter->iColumn ){
981     n += putVarint(c+n, POS_COLUMN);
982     n += putVarint(c+n, iColumn);
983     pWriter->iColumn = iColumn;
984     pWriter->iPos = 0;
985     pWriter->iOffset = 0;
986   }
987   assert( iPos>=pWriter->iPos );
988   n += putVarint(c+n, POS_BASE+(iPos-pWriter->iPos));
989   pWriter->iPos = iPos;
990   if( pWriter->dlw->iType==DL_POSITIONS_OFFSETS ){
991     assert( iStartOffset>=pWriter->iOffset );
992     n += putVarint(c+n, iStartOffset-pWriter->iOffset);
993     pWriter->iOffset = iStartOffset;
994     assert( iEndOffset>=iStartOffset );
995     n += putVarint(c+n, iEndOffset-iStartOffset);
996   }
997   dataBufferAppend(pWriter->dlw->b, c, n);
998 }
plwCopy(PLWriter * pWriter,PLReader * pReader)999 static void plwCopy(PLWriter *pWriter, PLReader *pReader){
1000   plwAdd(pWriter, plrColumn(pReader), plrPosition(pReader),
1001          plrStartOffset(pReader), plrEndOffset(pReader));
1002 }
plwInit(PLWriter * pWriter,DLWriter * dlw,sqlite_int64 iDocid)1003 static void plwInit(PLWriter *pWriter, DLWriter *dlw, sqlite_int64 iDocid){
1004   char c[VARINT_MAX];
1005   int n;
1006 
1007   pWriter->dlw = dlw;
1008 
1009   /* Docids must ascend. */
1010   assert( !pWriter->dlw->has_iPrevDocid || iDocid>pWriter->dlw->iPrevDocid );
1011   n = putVarint(c, iDocid-pWriter->dlw->iPrevDocid);
1012   dataBufferAppend(pWriter->dlw->b, c, n);
1013   pWriter->dlw->iPrevDocid = iDocid;
1014 #ifndef NDEBUG
1015   pWriter->dlw->has_iPrevDocid = 1;
1016 #endif
1017 
1018   pWriter->iColumn = 0;
1019   pWriter->iPos = 0;
1020   pWriter->iOffset = 0;
1021 }
1022 /* TODO(shess) Should plwDestroy() also terminate the doclist?  But
1023 ** then plwDestroy() would no longer be just a destructor, it would
1024 ** also be doing work, which isn't consistent with the overall idiom.
1025 ** Another option would be for plwAdd() to always append any necessary
1026 ** terminator, so that the output is always correct.  But that would
1027 ** add incremental work to the common case with the only benefit being
1028 ** API elegance.  Punt for now.
1029 */
plwTerminate(PLWriter * pWriter)1030 static void plwTerminate(PLWriter *pWriter){
1031   if( pWriter->dlw->iType>DL_DOCIDS ){
1032     char c[VARINT_MAX];
1033     int n = putVarint(c, POS_END);
1034     dataBufferAppend(pWriter->dlw->b, c, n);
1035   }
1036 #ifndef NDEBUG
1037   /* Mark as terminated for assert in plwAdd(). */
1038   pWriter->iPos = -1;
1039 #endif
1040 }
plwDestroy(PLWriter * pWriter)1041 static void plwDestroy(PLWriter *pWriter){
1042   SCRAMBLE(pWriter);
1043 }
1044 
1045 /*******************************************************************/
1046 /* DLCollector wraps PLWriter and DLWriter to provide a
1047 ** dynamically-allocated doclist area to use during tokenization.
1048 **
1049 ** dlcNew - malloc up and initialize a collector.
1050 ** dlcDelete - destroy a collector and all contained items.
1051 ** dlcAddPos - append position and offset information.
1052 ** dlcAddDoclist - add the collected doclist to the given buffer.
1053 ** dlcNext - terminate the current document and open another.
1054 */
1055 typedef struct DLCollector {
1056   DataBuffer b;
1057   DLWriter dlw;
1058   PLWriter plw;
1059 } DLCollector;
1060 
1061 /* TODO(shess) This could also be done by calling plwTerminate() and
1062 ** dataBufferAppend().  I tried that, expecting nominal performance
1063 ** differences, but it seemed to pretty reliably be worth 1% to code
1064 ** it this way.  I suspect it is the incremental malloc overhead (some
1065 ** percentage of the plwTerminate() calls will cause a realloc), so
1066 ** this might be worth revisiting if the DataBuffer implementation
1067 ** changes.
1068 */
dlcAddDoclist(DLCollector * pCollector,DataBuffer * b)1069 static void dlcAddDoclist(DLCollector *pCollector, DataBuffer *b){
1070   if( pCollector->dlw.iType>DL_DOCIDS ){
1071     char c[VARINT_MAX];
1072     int n = putVarint(c, POS_END);
1073     dataBufferAppend2(b, pCollector->b.pData, pCollector->b.nData, c, n);
1074   }else{
1075     dataBufferAppend(b, pCollector->b.pData, pCollector->b.nData);
1076   }
1077 }
dlcNext(DLCollector * pCollector,sqlite_int64 iDocid)1078 static void dlcNext(DLCollector *pCollector, sqlite_int64 iDocid){
1079   plwTerminate(&pCollector->plw);
1080   plwDestroy(&pCollector->plw);
1081   plwInit(&pCollector->plw, &pCollector->dlw, iDocid);
1082 }
dlcAddPos(DLCollector * pCollector,int iColumn,int iPos,int iStartOffset,int iEndOffset)1083 static void dlcAddPos(DLCollector *pCollector, int iColumn, int iPos,
1084                       int iStartOffset, int iEndOffset){
1085   plwAdd(&pCollector->plw, iColumn, iPos, iStartOffset, iEndOffset);
1086 }
1087 
dlcNew(sqlite_int64 iDocid,DocListType iType)1088 static DLCollector *dlcNew(sqlite_int64 iDocid, DocListType iType){
1089   DLCollector *pCollector = sqlite3_malloc(sizeof(DLCollector));
1090   dataBufferInit(&pCollector->b, 0);
1091   dlwInit(&pCollector->dlw, iType, &pCollector->b);
1092   plwInit(&pCollector->plw, &pCollector->dlw, iDocid);
1093   return pCollector;
1094 }
dlcDelete(DLCollector * pCollector)1095 static void dlcDelete(DLCollector *pCollector){
1096   plwDestroy(&pCollector->plw);
1097   dlwDestroy(&pCollector->dlw);
1098   dataBufferDestroy(&pCollector->b);
1099   SCRAMBLE(pCollector);
1100   sqlite3_free(pCollector);
1101 }
1102 
1103 
1104 /* Copy the doclist data of iType in pData/nData into *out, trimming
1105 ** unnecessary data as we go.  Only columns matching iColumn are
1106 ** copied, all columns copied if iColumn is -1.  Elements with no
1107 ** matching columns are dropped.  The output is an iOutType doclist.
1108 */
1109 /* NOTE(shess) This code is only valid after all doclists are merged.
1110 ** If this is run before merges, then doclist items which represent
1111 ** deletion will be trimmed, and will thus not effect a deletion
1112 ** during the merge.
1113 */
docListTrim(DocListType iType,const char * pData,int nData,int iColumn,DocListType iOutType,DataBuffer * out)1114 static void docListTrim(DocListType iType, const char *pData, int nData,
1115                         int iColumn, DocListType iOutType, DataBuffer *out){
1116   DLReader dlReader;
1117   DLWriter dlWriter;
1118 
1119   assert( iOutType<=iType );
1120 
1121   dlrInit(&dlReader, iType, pData, nData);
1122   dlwInit(&dlWriter, iOutType, out);
1123 
1124   while( !dlrAtEnd(&dlReader) ){
1125     PLReader plReader;
1126     PLWriter plWriter;
1127     int match = 0;
1128 
1129     plrInit(&plReader, &dlReader);
1130 
1131     while( !plrAtEnd(&plReader) ){
1132       if( iColumn==-1 || plrColumn(&plReader)==iColumn ){
1133         if( !match ){
1134           plwInit(&plWriter, &dlWriter, dlrDocid(&dlReader));
1135           match = 1;
1136         }
1137         plwAdd(&plWriter, plrColumn(&plReader), plrPosition(&plReader),
1138                plrStartOffset(&plReader), plrEndOffset(&plReader));
1139       }
1140       plrStep(&plReader);
1141     }
1142     if( match ){
1143       plwTerminate(&plWriter);
1144       plwDestroy(&plWriter);
1145     }
1146 
1147     plrDestroy(&plReader);
1148     dlrStep(&dlReader);
1149   }
1150   dlwDestroy(&dlWriter);
1151   dlrDestroy(&dlReader);
1152 }
1153 
1154 /* Used by docListMerge() to keep doclists in the ascending order by
1155 ** docid, then ascending order by age (so the newest comes first).
1156 */
1157 typedef struct OrderedDLReader {
1158   DLReader *pReader;
1159 
1160   /* TODO(shess) If we assume that docListMerge pReaders is ordered by
1161   ** age (which we do), then we could use pReader comparisons to break
1162   ** ties.
1163   */
1164   int idx;
1165 } OrderedDLReader;
1166 
1167 /* Order eof to end, then by docid asc, idx desc. */
orderedDLReaderCmp(OrderedDLReader * r1,OrderedDLReader * r2)1168 static int orderedDLReaderCmp(OrderedDLReader *r1, OrderedDLReader *r2){
1169   if( dlrAtEnd(r1->pReader) ){
1170     if( dlrAtEnd(r2->pReader) ) return 0;  /* Both atEnd(). */
1171     return 1;                              /* Only r1 atEnd(). */
1172   }
1173   if( dlrAtEnd(r2->pReader) ) return -1;   /* Only r2 atEnd(). */
1174 
1175   if( dlrDocid(r1->pReader)<dlrDocid(r2->pReader) ) return -1;
1176   if( dlrDocid(r1->pReader)>dlrDocid(r2->pReader) ) return 1;
1177 
1178   /* Descending on idx. */
1179   return r2->idx-r1->idx;
1180 }
1181 
1182 /* Bubble p[0] to appropriate place in p[1..n-1].  Assumes that
1183 ** p[1..n-1] is already sorted.
1184 */
1185 /* TODO(shess) Is this frequent enough to warrant a binary search?
1186 ** Before implementing that, instrument the code to check.  In most
1187 ** current usage, I expect that p[0] will be less than p[1] a very
1188 ** high proportion of the time.
1189 */
orderedDLReaderReorder(OrderedDLReader * p,int n)1190 static void orderedDLReaderReorder(OrderedDLReader *p, int n){
1191   while( n>1 && orderedDLReaderCmp(p, p+1)>0 ){
1192     OrderedDLReader tmp = p[0];
1193     p[0] = p[1];
1194     p[1] = tmp;
1195     n--;
1196     p++;
1197   }
1198 }
1199 
1200 /* Given an array of doclist readers, merge their doclist elements
1201 ** into out in sorted order (by docid), dropping elements from older
1202 ** readers when there is a duplicate docid.  pReaders is assumed to be
1203 ** ordered by age, oldest first.
1204 */
1205 /* TODO(shess) nReaders must be <= MERGE_COUNT.  This should probably
1206 ** be fixed.
1207 */
docListMerge(DataBuffer * out,DLReader * pReaders,int nReaders)1208 static void docListMerge(DataBuffer *out,
1209                          DLReader *pReaders, int nReaders){
1210   OrderedDLReader readers[MERGE_COUNT];
1211   DLWriter writer;
1212   int i, n;
1213   const char *pStart = 0;
1214   int nStart = 0;
1215   sqlite_int64 iFirstDocid = 0, iLastDocid = 0;
1216 
1217   assert( nReaders>0 );
1218   if( nReaders==1 ){
1219     dataBufferAppend(out, dlrDocData(pReaders), dlrAllDataBytes(pReaders));
1220     return;
1221   }
1222 
1223   assert( nReaders<=MERGE_COUNT );
1224   n = 0;
1225   for(i=0; i<nReaders; i++){
1226     assert( pReaders[i].iType==pReaders[0].iType );
1227     readers[i].pReader = pReaders+i;
1228     readers[i].idx = i;
1229     n += dlrAllDataBytes(&pReaders[i]);
1230   }
1231   /* Conservatively size output to sum of inputs.  Output should end
1232   ** up strictly smaller than input.
1233   */
1234   dataBufferExpand(out, n);
1235 
1236   /* Get the readers into sorted order. */
1237   while( i-->0 ){
1238     orderedDLReaderReorder(readers+i, nReaders-i);
1239   }
1240 
1241   dlwInit(&writer, pReaders[0].iType, out);
1242   while( !dlrAtEnd(readers[0].pReader) ){
1243     sqlite_int64 iDocid = dlrDocid(readers[0].pReader);
1244 
1245     /* If this is a continuation of the current buffer to copy, extend
1246     ** that buffer.  memcpy() seems to be more efficient if it has a
1247     ** lots of data to copy.
1248     */
1249     if( dlrDocData(readers[0].pReader)==pStart+nStart ){
1250       nStart += dlrDocDataBytes(readers[0].pReader);
1251     }else{
1252       if( pStart!=0 ){
1253         dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid);
1254       }
1255       pStart = dlrDocData(readers[0].pReader);
1256       nStart = dlrDocDataBytes(readers[0].pReader);
1257       iFirstDocid = iDocid;
1258     }
1259     iLastDocid = iDocid;
1260     dlrStep(readers[0].pReader);
1261 
1262     /* Drop all of the older elements with the same docid. */
1263     for(i=1; i<nReaders &&
1264              !dlrAtEnd(readers[i].pReader) &&
1265              dlrDocid(readers[i].pReader)==iDocid; i++){
1266       dlrStep(readers[i].pReader);
1267     }
1268 
1269     /* Get the readers back into order. */
1270     while( i-->0 ){
1271       orderedDLReaderReorder(readers+i, nReaders-i);
1272     }
1273   }
1274 
1275   /* Copy over any remaining elements. */
1276   if( nStart>0 ) dlwAppend(&writer, pStart, nStart, iFirstDocid, iLastDocid);
1277   dlwDestroy(&writer);
1278 }
1279 
1280 /* Helper function for posListUnion().  Compares the current position
1281 ** between left and right, returning as standard C idiom of <0 if
1282 ** left<right, >0 if left>right, and 0 if left==right.  "End" always
1283 ** compares greater.
1284 */
posListCmp(PLReader * pLeft,PLReader * pRight)1285 static int posListCmp(PLReader *pLeft, PLReader *pRight){
1286   assert( pLeft->iType==pRight->iType );
1287   if( pLeft->iType==DL_DOCIDS ) return 0;
1288 
1289   if( plrAtEnd(pLeft) ) return plrAtEnd(pRight) ? 0 : 1;
1290   if( plrAtEnd(pRight) ) return -1;
1291 
1292   if( plrColumn(pLeft)<plrColumn(pRight) ) return -1;
1293   if( plrColumn(pLeft)>plrColumn(pRight) ) return 1;
1294 
1295   if( plrPosition(pLeft)<plrPosition(pRight) ) return -1;
1296   if( plrPosition(pLeft)>plrPosition(pRight) ) return 1;
1297   if( pLeft->iType==DL_POSITIONS ) return 0;
1298 
1299   if( plrStartOffset(pLeft)<plrStartOffset(pRight) ) return -1;
1300   if( plrStartOffset(pLeft)>plrStartOffset(pRight) ) return 1;
1301 
1302   if( plrEndOffset(pLeft)<plrEndOffset(pRight) ) return -1;
1303   if( plrEndOffset(pLeft)>plrEndOffset(pRight) ) return 1;
1304 
1305   return 0;
1306 }
1307 
1308 /* Write the union of position lists in pLeft and pRight to pOut.
1309 ** "Union" in this case meaning "All unique position tuples".  Should
1310 ** work with any doclist type, though both inputs and the output
1311 ** should be the same type.
1312 */
posListUnion(DLReader * pLeft,DLReader * pRight,DLWriter * pOut)1313 static void posListUnion(DLReader *pLeft, DLReader *pRight, DLWriter *pOut){
1314   PLReader left, right;
1315   PLWriter writer;
1316 
1317   assert( dlrDocid(pLeft)==dlrDocid(pRight) );
1318   assert( pLeft->iType==pRight->iType );
1319   assert( pLeft->iType==pOut->iType );
1320 
1321   plrInit(&left, pLeft);
1322   plrInit(&right, pRight);
1323   plwInit(&writer, pOut, dlrDocid(pLeft));
1324 
1325   while( !plrAtEnd(&left) || !plrAtEnd(&right) ){
1326     int c = posListCmp(&left, &right);
1327     if( c<0 ){
1328       plwCopy(&writer, &left);
1329       plrStep(&left);
1330     }else if( c>0 ){
1331       plwCopy(&writer, &right);
1332       plrStep(&right);
1333     }else{
1334       plwCopy(&writer, &left);
1335       plrStep(&left);
1336       plrStep(&right);
1337     }
1338   }
1339 
1340   plwTerminate(&writer);
1341   plwDestroy(&writer);
1342   plrDestroy(&left);
1343   plrDestroy(&right);
1344 }
1345 
1346 /* Write the union of doclists in pLeft and pRight to pOut.  For
1347 ** docids in common between the inputs, the union of the position
1348 ** lists is written.  Inputs and outputs are always type DL_DEFAULT.
1349 */
docListUnion(const char * pLeft,int nLeft,const char * pRight,int nRight,DataBuffer * pOut)1350 static void docListUnion(
1351   const char *pLeft, int nLeft,
1352   const char *pRight, int nRight,
1353   DataBuffer *pOut      /* Write the combined doclist here */
1354 ){
1355   DLReader left, right;
1356   DLWriter writer;
1357 
1358   if( nLeft==0 ){
1359     if( nRight!=0) dataBufferAppend(pOut, pRight, nRight);
1360     return;
1361   }
1362   if( nRight==0 ){
1363     dataBufferAppend(pOut, pLeft, nLeft);
1364     return;
1365   }
1366 
1367   dlrInit(&left, DL_DEFAULT, pLeft, nLeft);
1368   dlrInit(&right, DL_DEFAULT, pRight, nRight);
1369   dlwInit(&writer, DL_DEFAULT, pOut);
1370 
1371   while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){
1372     if( dlrAtEnd(&right) ){
1373       dlwCopy(&writer, &left);
1374       dlrStep(&left);
1375     }else if( dlrAtEnd(&left) ){
1376       dlwCopy(&writer, &right);
1377       dlrStep(&right);
1378     }else if( dlrDocid(&left)<dlrDocid(&right) ){
1379       dlwCopy(&writer, &left);
1380       dlrStep(&left);
1381     }else if( dlrDocid(&left)>dlrDocid(&right) ){
1382       dlwCopy(&writer, &right);
1383       dlrStep(&right);
1384     }else{
1385       posListUnion(&left, &right, &writer);
1386       dlrStep(&left);
1387       dlrStep(&right);
1388     }
1389   }
1390 
1391   dlrDestroy(&left);
1392   dlrDestroy(&right);
1393   dlwDestroy(&writer);
1394 }
1395 
1396 /* pLeft and pRight are DLReaders positioned to the same docid.
1397 **
1398 ** If there are no instances in pLeft or pRight where the position
1399 ** of pLeft is one less than the position of pRight, then this
1400 ** routine adds nothing to pOut.
1401 **
1402 ** If there are one or more instances where positions from pLeft
1403 ** are exactly one less than positions from pRight, then add a new
1404 ** document record to pOut.  If pOut wants to hold positions, then
1405 ** include the positions from pRight that are one more than a
1406 ** position in pLeft.  In other words:  pRight.iPos==pLeft.iPos+1.
1407 */
posListPhraseMerge(DLReader * pLeft,DLReader * pRight,DLWriter * pOut)1408 static void posListPhraseMerge(DLReader *pLeft, DLReader *pRight,
1409                                DLWriter *pOut){
1410   PLReader left, right;
1411   PLWriter writer;
1412   int match = 0;
1413 
1414   assert( dlrDocid(pLeft)==dlrDocid(pRight) );
1415   assert( pOut->iType!=DL_POSITIONS_OFFSETS );
1416 
1417   plrInit(&left, pLeft);
1418   plrInit(&right, pRight);
1419 
1420   while( !plrAtEnd(&left) && !plrAtEnd(&right) ){
1421     if( plrColumn(&left)<plrColumn(&right) ){
1422       plrStep(&left);
1423     }else if( plrColumn(&left)>plrColumn(&right) ){
1424       plrStep(&right);
1425     }else if( plrPosition(&left)+1<plrPosition(&right) ){
1426       plrStep(&left);
1427     }else if( plrPosition(&left)+1>plrPosition(&right) ){
1428       plrStep(&right);
1429     }else{
1430       if( !match ){
1431         plwInit(&writer, pOut, dlrDocid(pLeft));
1432         match = 1;
1433       }
1434       plwAdd(&writer, plrColumn(&right), plrPosition(&right), 0, 0);
1435       plrStep(&left);
1436       plrStep(&right);
1437     }
1438   }
1439 
1440   if( match ){
1441     plwTerminate(&writer);
1442     plwDestroy(&writer);
1443   }
1444 
1445   plrDestroy(&left);
1446   plrDestroy(&right);
1447 }
1448 
1449 /* We have two doclists with positions:  pLeft and pRight.
1450 ** Write the phrase intersection of these two doclists into pOut.
1451 **
1452 ** A phrase intersection means that two documents only match
1453 ** if pLeft.iPos+1==pRight.iPos.
1454 **
1455 ** iType controls the type of data written to pOut.  If iType is
1456 ** DL_POSITIONS, the positions are those from pRight.
1457 */
docListPhraseMerge(const char * pLeft,int nLeft,const char * pRight,int nRight,DocListType iType,DataBuffer * pOut)1458 static void docListPhraseMerge(
1459   const char *pLeft, int nLeft,
1460   const char *pRight, int nRight,
1461   DocListType iType,
1462   DataBuffer *pOut      /* Write the combined doclist here */
1463 ){
1464   DLReader left, right;
1465   DLWriter writer;
1466 
1467   if( nLeft==0 || nRight==0 ) return;
1468 
1469   assert( iType!=DL_POSITIONS_OFFSETS );
1470 
1471   dlrInit(&left, DL_POSITIONS, pLeft, nLeft);
1472   dlrInit(&right, DL_POSITIONS, pRight, nRight);
1473   dlwInit(&writer, iType, pOut);
1474 
1475   while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){
1476     if( dlrDocid(&left)<dlrDocid(&right) ){
1477       dlrStep(&left);
1478     }else if( dlrDocid(&right)<dlrDocid(&left) ){
1479       dlrStep(&right);
1480     }else{
1481       posListPhraseMerge(&left, &right, &writer);
1482       dlrStep(&left);
1483       dlrStep(&right);
1484     }
1485   }
1486 
1487   dlrDestroy(&left);
1488   dlrDestroy(&right);
1489   dlwDestroy(&writer);
1490 }
1491 
1492 /* We have two DL_DOCIDS doclists:  pLeft and pRight.
1493 ** Write the intersection of these two doclists into pOut as a
1494 ** DL_DOCIDS doclist.
1495 */
docListAndMerge(const char * pLeft,int nLeft,const char * pRight,int nRight,DataBuffer * pOut)1496 static void docListAndMerge(
1497   const char *pLeft, int nLeft,
1498   const char *pRight, int nRight,
1499   DataBuffer *pOut      /* Write the combined doclist here */
1500 ){
1501   DLReader left, right;
1502   DLWriter writer;
1503 
1504   if( nLeft==0 || nRight==0 ) return;
1505 
1506   dlrInit(&left, DL_DOCIDS, pLeft, nLeft);
1507   dlrInit(&right, DL_DOCIDS, pRight, nRight);
1508   dlwInit(&writer, DL_DOCIDS, pOut);
1509 
1510   while( !dlrAtEnd(&left) && !dlrAtEnd(&right) ){
1511     if( dlrDocid(&left)<dlrDocid(&right) ){
1512       dlrStep(&left);
1513     }else if( dlrDocid(&right)<dlrDocid(&left) ){
1514       dlrStep(&right);
1515     }else{
1516       dlwAdd(&writer, dlrDocid(&left));
1517       dlrStep(&left);
1518       dlrStep(&right);
1519     }
1520   }
1521 
1522   dlrDestroy(&left);
1523   dlrDestroy(&right);
1524   dlwDestroy(&writer);
1525 }
1526 
1527 /* We have two DL_DOCIDS doclists:  pLeft and pRight.
1528 ** Write the union of these two doclists into pOut as a
1529 ** DL_DOCIDS doclist.
1530 */
docListOrMerge(const char * pLeft,int nLeft,const char * pRight,int nRight,DataBuffer * pOut)1531 static void docListOrMerge(
1532   const char *pLeft, int nLeft,
1533   const char *pRight, int nRight,
1534   DataBuffer *pOut      /* Write the combined doclist here */
1535 ){
1536   DLReader left, right;
1537   DLWriter writer;
1538 
1539   if( nLeft==0 ){
1540     if( nRight!=0 ) dataBufferAppend(pOut, pRight, nRight);
1541     return;
1542   }
1543   if( nRight==0 ){
1544     dataBufferAppend(pOut, pLeft, nLeft);
1545     return;
1546   }
1547 
1548   dlrInit(&left, DL_DOCIDS, pLeft, nLeft);
1549   dlrInit(&right, DL_DOCIDS, pRight, nRight);
1550   dlwInit(&writer, DL_DOCIDS, pOut);
1551 
1552   while( !dlrAtEnd(&left) || !dlrAtEnd(&right) ){
1553     if( dlrAtEnd(&right) ){
1554       dlwAdd(&writer, dlrDocid(&left));
1555       dlrStep(&left);
1556     }else if( dlrAtEnd(&left) ){
1557       dlwAdd(&writer, dlrDocid(&right));
1558       dlrStep(&right);
1559     }else if( dlrDocid(&left)<dlrDocid(&right) ){
1560       dlwAdd(&writer, dlrDocid(&left));
1561       dlrStep(&left);
1562     }else if( dlrDocid(&right)<dlrDocid(&left) ){
1563       dlwAdd(&writer, dlrDocid(&right));
1564       dlrStep(&right);
1565     }else{
1566       dlwAdd(&writer, dlrDocid(&left));
1567       dlrStep(&left);
1568       dlrStep(&right);
1569     }
1570   }
1571 
1572   dlrDestroy(&left);
1573   dlrDestroy(&right);
1574   dlwDestroy(&writer);
1575 }
1576 
1577 /* We have two DL_DOCIDS doclists:  pLeft and pRight.
1578 ** Write into pOut as DL_DOCIDS doclist containing all documents that
1579 ** occur in pLeft but not in pRight.
1580 */
docListExceptMerge(const char * pLeft,int nLeft,const char * pRight,int nRight,DataBuffer * pOut)1581 static void docListExceptMerge(
1582   const char *pLeft, int nLeft,
1583   const char *pRight, int nRight,
1584   DataBuffer *pOut      /* Write the combined doclist here */
1585 ){
1586   DLReader left, right;
1587   DLWriter writer;
1588 
1589   if( nLeft==0 ) return;
1590   if( nRight==0 ){
1591     dataBufferAppend(pOut, pLeft, nLeft);
1592     return;
1593   }
1594 
1595   dlrInit(&left, DL_DOCIDS, pLeft, nLeft);
1596   dlrInit(&right, DL_DOCIDS, pRight, nRight);
1597   dlwInit(&writer, DL_DOCIDS, pOut);
1598 
1599   while( !dlrAtEnd(&left) ){
1600     while( !dlrAtEnd(&right) && dlrDocid(&right)<dlrDocid(&left) ){
1601       dlrStep(&right);
1602     }
1603     if( dlrAtEnd(&right) || dlrDocid(&left)<dlrDocid(&right) ){
1604       dlwAdd(&writer, dlrDocid(&left));
1605     }
1606     dlrStep(&left);
1607   }
1608 
1609   dlrDestroy(&left);
1610   dlrDestroy(&right);
1611   dlwDestroy(&writer);
1612 }
1613 
string_dup_n(const char * s,int n)1614 static char *string_dup_n(const char *s, int n){
1615   char *str = sqlite3_malloc(n + 1);
1616   memcpy(str, s, n);
1617   str[n] = '\0';
1618   return str;
1619 }
1620 
1621 /* Duplicate a string; the caller must free() the returned string.
1622  * (We don't use strdup() since it is not part of the standard C library and
1623  * may not be available everywhere.) */
string_dup(const char * s)1624 static char *string_dup(const char *s){
1625   return string_dup_n(s, strlen(s));
1626 }
1627 
1628 /* Format a string, replacing each occurrence of the % character with
1629  * zDb.zName.  This may be more convenient than sqlite_mprintf()
1630  * when one string is used repeatedly in a format string.
1631  * The caller must free() the returned string. */
string_format(const char * zFormat,const char * zDb,const char * zName)1632 static char *string_format(const char *zFormat,
1633                            const char *zDb, const char *zName){
1634   const char *p;
1635   size_t len = 0;
1636   size_t nDb = strlen(zDb);
1637   size_t nName = strlen(zName);
1638   size_t nFullTableName = nDb+1+nName;
1639   char *result;
1640   char *r;
1641 
1642   /* first compute length needed */
1643   for(p = zFormat ; *p ; ++p){
1644     len += (*p=='%' ? nFullTableName : 1);
1645   }
1646   len += 1;  /* for null terminator */
1647 
1648   r = result = sqlite3_malloc(len);
1649   for(p = zFormat; *p; ++p){
1650     if( *p=='%' ){
1651       memcpy(r, zDb, nDb);
1652       r += nDb;
1653       *r++ = '.';
1654       memcpy(r, zName, nName);
1655       r += nName;
1656     } else {
1657       *r++ = *p;
1658     }
1659   }
1660   *r++ = '\0';
1661   assert( r == result + len );
1662   return result;
1663 }
1664 
sql_exec(sqlite3 * db,const char * zDb,const char * zName,const char * zFormat)1665 static int sql_exec(sqlite3 *db, const char *zDb, const char *zName,
1666                     const char *zFormat){
1667   char *zCommand = string_format(zFormat, zDb, zName);
1668   int rc;
1669   TRACE(("FTS2 sql: %s\n", zCommand));
1670   rc = sqlite3_exec(db, zCommand, NULL, 0, NULL);
1671   sqlite3_free(zCommand);
1672   return rc;
1673 }
1674 
sql_prepare(sqlite3 * db,const char * zDb,const char * zName,sqlite3_stmt ** ppStmt,const char * zFormat)1675 static int sql_prepare(sqlite3 *db, const char *zDb, const char *zName,
1676                        sqlite3_stmt **ppStmt, const char *zFormat){
1677   char *zCommand = string_format(zFormat, zDb, zName);
1678   int rc;
1679   TRACE(("FTS2 prepare: %s\n", zCommand));
1680   rc = sqlite3_prepare_v2(db, zCommand, -1, ppStmt, NULL);
1681   sqlite3_free(zCommand);
1682   return rc;
1683 }
1684 
1685 /* end utility functions */
1686 
1687 /* Forward reference */
1688 typedef struct fulltext_vtab fulltext_vtab;
1689 
1690 /* A single term in a query is represented by an instances of
1691 ** the following structure.
1692 */
1693 typedef struct QueryTerm {
1694   short int nPhrase; /* How many following terms are part of the same phrase */
1695   short int iPhrase; /* This is the i-th term of a phrase. */
1696   short int iColumn; /* Column of the index that must match this term */
1697   signed char isOr;  /* this term is preceded by "OR" */
1698   signed char isNot; /* this term is preceded by "-" */
1699   signed char isPrefix; /* this term is followed by "*" */
1700   char *pTerm;       /* text of the term.  '\000' terminated.  malloced */
1701   int nTerm;         /* Number of bytes in pTerm[] */
1702 } QueryTerm;
1703 
1704 
1705 /* A query string is parsed into a Query structure.
1706  *
1707  * We could, in theory, allow query strings to be complicated
1708  * nested expressions with precedence determined by parentheses.
1709  * But none of the major search engines do this.  (Perhaps the
1710  * feeling is that an parenthesized expression is two complex of
1711  * an idea for the average user to grasp.)  Taking our lead from
1712  * the major search engines, we will allow queries to be a list
1713  * of terms (with an implied AND operator) or phrases in double-quotes,
1714  * with a single optional "-" before each non-phrase term to designate
1715  * negation and an optional OR connector.
1716  *
1717  * OR binds more tightly than the implied AND, which is what the
1718  * major search engines seem to do.  So, for example:
1719  *
1720  *    [one two OR three]     ==>    one AND (two OR three)
1721  *    [one OR two three]     ==>    (one OR two) AND three
1722  *
1723  * A "-" before a term matches all entries that lack that term.
1724  * The "-" must occur immediately before the term with in intervening
1725  * space.  This is how the search engines do it.
1726  *
1727  * A NOT term cannot be the right-hand operand of an OR.  If this
1728  * occurs in the query string, the NOT is ignored:
1729  *
1730  *    [one OR -two]          ==>    one OR two
1731  *
1732  */
1733 typedef struct Query {
1734   fulltext_vtab *pFts;  /* The full text index */
1735   int nTerms;           /* Number of terms in the query */
1736   QueryTerm *pTerms;    /* Array of terms.  Space obtained from malloc() */
1737   int nextIsOr;         /* Set the isOr flag on the next inserted term */
1738   int nextColumn;       /* Next word parsed must be in this column */
1739   int dfltColumn;       /* The default column */
1740 } Query;
1741 
1742 
1743 /*
1744 ** An instance of the following structure keeps track of generated
1745 ** matching-word offset information and snippets.
1746 */
1747 typedef struct Snippet {
1748   int nMatch;     /* Total number of matches */
1749   int nAlloc;     /* Space allocated for aMatch[] */
1750   struct snippetMatch { /* One entry for each matching term */
1751     char snStatus;       /* Status flag for use while constructing snippets */
1752     short int iCol;      /* The column that contains the match */
1753     short int iTerm;     /* The index in Query.pTerms[] of the matching term */
1754     short int nByte;     /* Number of bytes in the term */
1755     int iStart;          /* The offset to the first character of the term */
1756   } *aMatch;      /* Points to space obtained from malloc */
1757   char *zOffset;  /* Text rendering of aMatch[] */
1758   int nOffset;    /* strlen(zOffset) */
1759   char *zSnippet; /* Snippet text */
1760   int nSnippet;   /* strlen(zSnippet) */
1761 } Snippet;
1762 
1763 
1764 typedef enum QueryType {
1765   QUERY_GENERIC,   /* table scan */
1766   QUERY_ROWID,     /* lookup by rowid */
1767   QUERY_FULLTEXT   /* QUERY_FULLTEXT + [i] is a full-text search for column i*/
1768 } QueryType;
1769 
1770 typedef enum fulltext_statement {
1771   CONTENT_INSERT_STMT,
1772   CONTENT_SELECT_STMT,
1773   CONTENT_UPDATE_STMT,
1774   CONTENT_DELETE_STMT,
1775   CONTENT_EXISTS_STMT,
1776 
1777   BLOCK_INSERT_STMT,
1778   BLOCK_SELECT_STMT,
1779   BLOCK_DELETE_STMT,
1780   BLOCK_DELETE_ALL_STMT,
1781 
1782   SEGDIR_MAX_INDEX_STMT,
1783   SEGDIR_SET_STMT,
1784   SEGDIR_SELECT_LEVEL_STMT,
1785   SEGDIR_SPAN_STMT,
1786   SEGDIR_DELETE_STMT,
1787   SEGDIR_SELECT_SEGMENT_STMT,
1788   SEGDIR_SELECT_ALL_STMT,
1789   SEGDIR_DELETE_ALL_STMT,
1790   SEGDIR_COUNT_STMT,
1791 
1792   MAX_STMT                     /* Always at end! */
1793 } fulltext_statement;
1794 
1795 /* These must exactly match the enum above. */
1796 /* TODO(shess): Is there some risk that a statement will be used in two
1797 ** cursors at once, e.g.  if a query joins a virtual table to itself?
1798 ** If so perhaps we should move some of these to the cursor object.
1799 */
1800 static const char *const fulltext_zStatement[MAX_STMT] = {
1801   /* CONTENT_INSERT */ NULL,  /* generated in contentInsertStatement() */
1802   /* CONTENT_SELECT */ "select * from %_content where rowid = ?",
1803   /* CONTENT_UPDATE */ NULL,  /* generated in contentUpdateStatement() */
1804   /* CONTENT_DELETE */ "delete from %_content where rowid = ?",
1805   /* CONTENT_EXISTS */ "select rowid from %_content limit 1",
1806 
1807   /* BLOCK_INSERT */ "insert into %_segments values (?)",
1808   /* BLOCK_SELECT */ "select block from %_segments where rowid = ?",
1809   /* BLOCK_DELETE */ "delete from %_segments where rowid between ? and ?",
1810   /* BLOCK_DELETE_ALL */ "delete from %_segments",
1811 
1812   /* SEGDIR_MAX_INDEX */ "select max(idx) from %_segdir where level = ?",
1813   /* SEGDIR_SET */ "insert into %_segdir values (?, ?, ?, ?, ?, ?)",
1814   /* SEGDIR_SELECT_LEVEL */
1815   "select start_block, leaves_end_block, root from %_segdir "
1816   " where level = ? order by idx",
1817   /* SEGDIR_SPAN */
1818   "select min(start_block), max(end_block) from %_segdir "
1819   " where level = ? and start_block <> 0",
1820   /* SEGDIR_DELETE */ "delete from %_segdir where level = ?",
1821 
1822   /* NOTE(shess): The first three results of the following two
1823   ** statements must match.
1824   */
1825   /* SEGDIR_SELECT_SEGMENT */
1826   "select start_block, leaves_end_block, root from %_segdir "
1827   " where level = ? and idx = ?",
1828   /* SEGDIR_SELECT_ALL */
1829   "select start_block, leaves_end_block, root from %_segdir "
1830   " order by level desc, idx asc",
1831   /* SEGDIR_DELETE_ALL */ "delete from %_segdir",
1832   /* SEGDIR_COUNT */ "select count(*), ifnull(max(level),0) from %_segdir",
1833 };
1834 
1835 /*
1836 ** A connection to a fulltext index is an instance of the following
1837 ** structure.  The xCreate and xConnect methods create an instance
1838 ** of this structure and xDestroy and xDisconnect free that instance.
1839 ** All other methods receive a pointer to the structure as one of their
1840 ** arguments.
1841 */
1842 struct fulltext_vtab {
1843   sqlite3_vtab base;               /* Base class used by SQLite core */
1844   sqlite3 *db;                     /* The database connection */
1845   const char *zDb;                 /* logical database name */
1846   const char *zName;               /* virtual table name */
1847   int nColumn;                     /* number of columns in virtual table */
1848   char **azColumn;                 /* column names.  malloced */
1849   char **azContentColumn;          /* column names in content table; malloced */
1850   sqlite3_tokenizer *pTokenizer;   /* tokenizer for inserts and queries */
1851 
1852   /* Precompiled statements which we keep as long as the table is
1853   ** open.
1854   */
1855   sqlite3_stmt *pFulltextStatements[MAX_STMT];
1856 
1857   /* Precompiled statements used for segment merges.  We run a
1858   ** separate select across the leaf level of each tree being merged.
1859   */
1860   sqlite3_stmt *pLeafSelectStmts[MERGE_COUNT];
1861   /* The statement used to prepare pLeafSelectStmts. */
1862 #define LEAF_SELECT \
1863   "select block from %_segments where rowid between ? and ? order by rowid"
1864 
1865   /* These buffer pending index updates during transactions.
1866   ** nPendingData estimates the memory size of the pending data.  It
1867   ** doesn't include the hash-bucket overhead, nor any malloc
1868   ** overhead.  When nPendingData exceeds kPendingThreshold, the
1869   ** buffer is flushed even before the transaction closes.
1870   ** pendingTerms stores the data, and is only valid when nPendingData
1871   ** is >=0 (nPendingData<0 means pendingTerms has not been
1872   ** initialized).  iPrevDocid is the last docid written, used to make
1873   ** certain we're inserting in sorted order.
1874   */
1875   int nPendingData;
1876 #define kPendingThreshold (1*1024*1024)
1877   sqlite_int64 iPrevDocid;
1878   fts2Hash pendingTerms;
1879 };
1880 
1881 /*
1882 ** When the core wants to do a query, it create a cursor using a
1883 ** call to xOpen.  This structure is an instance of a cursor.  It
1884 ** is destroyed by xClose.
1885 */
1886 typedef struct fulltext_cursor {
1887   sqlite3_vtab_cursor base;        /* Base class used by SQLite core */
1888   QueryType iCursorType;           /* Copy of sqlite3_index_info.idxNum */
1889   sqlite3_stmt *pStmt;             /* Prepared statement in use by the cursor */
1890   int eof;                         /* True if at End Of Results */
1891   Query q;                         /* Parsed query string */
1892   Snippet snippet;                 /* Cached snippet for the current row */
1893   int iColumn;                     /* Column being searched */
1894   DataBuffer result;               /* Doclist results from fulltextQuery */
1895   DLReader reader;                 /* Result reader if result not empty */
1896 } fulltext_cursor;
1897 
cursor_vtab(fulltext_cursor * c)1898 static struct fulltext_vtab *cursor_vtab(fulltext_cursor *c){
1899   return (fulltext_vtab *) c->base.pVtab;
1900 }
1901 
1902 static const sqlite3_module fts2Module;   /* forward declaration */
1903 
1904 /* Return a dynamically generated statement of the form
1905  *   insert into %_content (rowid, ...) values (?, ...)
1906  */
contentInsertStatement(fulltext_vtab * v)1907 static const char *contentInsertStatement(fulltext_vtab *v){
1908   StringBuffer sb;
1909   int i;
1910 
1911   initStringBuffer(&sb);
1912   append(&sb, "insert into %_content (rowid, ");
1913   appendList(&sb, v->nColumn, v->azContentColumn);
1914   append(&sb, ") values (?");
1915   for(i=0; i<v->nColumn; ++i)
1916     append(&sb, ", ?");
1917   append(&sb, ")");
1918   return stringBufferData(&sb);
1919 }
1920 
1921 /* Return a dynamically generated statement of the form
1922  *   update %_content set [col_0] = ?, [col_1] = ?, ...
1923  *                    where rowid = ?
1924  */
contentUpdateStatement(fulltext_vtab * v)1925 static const char *contentUpdateStatement(fulltext_vtab *v){
1926   StringBuffer sb;
1927   int i;
1928 
1929   initStringBuffer(&sb);
1930   append(&sb, "update %_content set ");
1931   for(i=0; i<v->nColumn; ++i) {
1932     if( i>0 ){
1933       append(&sb, ", ");
1934     }
1935     append(&sb, v->azContentColumn[i]);
1936     append(&sb, " = ?");
1937   }
1938   append(&sb, " where rowid = ?");
1939   return stringBufferData(&sb);
1940 }
1941 
1942 /* Puts a freshly-prepared statement determined by iStmt in *ppStmt.
1943 ** If the indicated statement has never been prepared, it is prepared
1944 ** and cached, otherwise the cached version is reset.
1945 */
sql_get_statement(fulltext_vtab * v,fulltext_statement iStmt,sqlite3_stmt ** ppStmt)1946 static int sql_get_statement(fulltext_vtab *v, fulltext_statement iStmt,
1947                              sqlite3_stmt **ppStmt){
1948   assert( iStmt<MAX_STMT );
1949   if( v->pFulltextStatements[iStmt]==NULL ){
1950     const char *zStmt;
1951     int rc;
1952     switch( iStmt ){
1953       case CONTENT_INSERT_STMT:
1954         zStmt = contentInsertStatement(v); break;
1955       case CONTENT_UPDATE_STMT:
1956         zStmt = contentUpdateStatement(v); break;
1957       default:
1958         zStmt = fulltext_zStatement[iStmt];
1959     }
1960     rc = sql_prepare(v->db, v->zDb, v->zName, &v->pFulltextStatements[iStmt],
1961                          zStmt);
1962     if( zStmt != fulltext_zStatement[iStmt]) sqlite3_free((void *) zStmt);
1963     if( rc!=SQLITE_OK ) return rc;
1964   } else {
1965     int rc = sqlite3_reset(v->pFulltextStatements[iStmt]);
1966     if( rc!=SQLITE_OK ) return rc;
1967   }
1968 
1969   *ppStmt = v->pFulltextStatements[iStmt];
1970   return SQLITE_OK;
1971 }
1972 
1973 /* Like sqlite3_step(), but convert SQLITE_DONE to SQLITE_OK and
1974 ** SQLITE_ROW to SQLITE_ERROR.  Useful for statements like UPDATE,
1975 ** where we expect no results.
1976 */
sql_single_step(sqlite3_stmt * s)1977 static int sql_single_step(sqlite3_stmt *s){
1978   int rc = sqlite3_step(s);
1979   return (rc==SQLITE_DONE) ? SQLITE_OK : rc;
1980 }
1981 
1982 /* Like sql_get_statement(), but for special replicated LEAF_SELECT
1983 ** statements.  idx -1 is a special case for an uncached version of
1984 ** the statement (used in the optimize implementation).
1985 */
1986 /* TODO(shess) Write version for generic statements and then share
1987 ** that between the cached-statement functions.
1988 */
sql_get_leaf_statement(fulltext_vtab * v,int idx,sqlite3_stmt ** ppStmt)1989 static int sql_get_leaf_statement(fulltext_vtab *v, int idx,
1990                                   sqlite3_stmt **ppStmt){
1991   assert( idx>=-1 && idx<MERGE_COUNT );
1992   if( idx==-1 ){
1993     return sql_prepare(v->db, v->zDb, v->zName, ppStmt, LEAF_SELECT);
1994   }else if( v->pLeafSelectStmts[idx]==NULL ){
1995     int rc = sql_prepare(v->db, v->zDb, v->zName, &v->pLeafSelectStmts[idx],
1996                          LEAF_SELECT);
1997     if( rc!=SQLITE_OK ) return rc;
1998   }else{
1999     int rc = sqlite3_reset(v->pLeafSelectStmts[idx]);
2000     if( rc!=SQLITE_OK ) return rc;
2001   }
2002 
2003   *ppStmt = v->pLeafSelectStmts[idx];
2004   return SQLITE_OK;
2005 }
2006 
2007 /* insert into %_content (rowid, ...) values ([rowid], [pValues]) */
content_insert(fulltext_vtab * v,sqlite3_value * rowid,sqlite3_value ** pValues)2008 static int content_insert(fulltext_vtab *v, sqlite3_value *rowid,
2009                           sqlite3_value **pValues){
2010   sqlite3_stmt *s;
2011   int i;
2012   int rc = sql_get_statement(v, CONTENT_INSERT_STMT, &s);
2013   if( rc!=SQLITE_OK ) return rc;
2014 
2015   rc = sqlite3_bind_value(s, 1, rowid);
2016   if( rc!=SQLITE_OK ) return rc;
2017 
2018   for(i=0; i<v->nColumn; ++i){
2019     rc = sqlite3_bind_value(s, 2+i, pValues[i]);
2020     if( rc!=SQLITE_OK ) return rc;
2021   }
2022 
2023   return sql_single_step(s);
2024 }
2025 
2026 /* update %_content set col0 = pValues[0], col1 = pValues[1], ...
2027  *                  where rowid = [iRowid] */
content_update(fulltext_vtab * v,sqlite3_value ** pValues,sqlite_int64 iRowid)2028 static int content_update(fulltext_vtab *v, sqlite3_value **pValues,
2029                           sqlite_int64 iRowid){
2030   sqlite3_stmt *s;
2031   int i;
2032   int rc = sql_get_statement(v, CONTENT_UPDATE_STMT, &s);
2033   if( rc!=SQLITE_OK ) return rc;
2034 
2035   for(i=0; i<v->nColumn; ++i){
2036     rc = sqlite3_bind_value(s, 1+i, pValues[i]);
2037     if( rc!=SQLITE_OK ) return rc;
2038   }
2039 
2040   rc = sqlite3_bind_int64(s, 1+v->nColumn, iRowid);
2041   if( rc!=SQLITE_OK ) return rc;
2042 
2043   return sql_single_step(s);
2044 }
2045 
freeStringArray(int nString,const char ** pString)2046 static void freeStringArray(int nString, const char **pString){
2047   int i;
2048 
2049   for (i=0 ; i < nString ; ++i) {
2050     if( pString[i]!=NULL ) sqlite3_free((void *) pString[i]);
2051   }
2052   sqlite3_free((void *) pString);
2053 }
2054 
2055 /* select * from %_content where rowid = [iRow]
2056  * The caller must delete the returned array and all strings in it.
2057  * null fields will be NULL in the returned array.
2058  *
2059  * TODO: Perhaps we should return pointer/length strings here for consistency
2060  * with other code which uses pointer/length. */
content_select(fulltext_vtab * v,sqlite_int64 iRow,const char *** pValues)2061 static int content_select(fulltext_vtab *v, sqlite_int64 iRow,
2062                           const char ***pValues){
2063   sqlite3_stmt *s;
2064   const char **values;
2065   int i;
2066   int rc;
2067 
2068   *pValues = NULL;
2069 
2070   rc = sql_get_statement(v, CONTENT_SELECT_STMT, &s);
2071   if( rc!=SQLITE_OK ) return rc;
2072 
2073   rc = sqlite3_bind_int64(s, 1, iRow);
2074   if( rc!=SQLITE_OK ) return rc;
2075 
2076   rc = sqlite3_step(s);
2077   if( rc!=SQLITE_ROW ) return rc;
2078 
2079   values = (const char **) sqlite3_malloc(v->nColumn * sizeof(const char *));
2080   for(i=0; i<v->nColumn; ++i){
2081     if( sqlite3_column_type(s, i)==SQLITE_NULL ){
2082       values[i] = NULL;
2083     }else{
2084       values[i] = string_dup((char*)sqlite3_column_text(s, i));
2085     }
2086   }
2087 
2088   /* We expect only one row.  We must execute another sqlite3_step()
2089    * to complete the iteration; otherwise the table will remain locked. */
2090   rc = sqlite3_step(s);
2091   if( rc==SQLITE_DONE ){
2092     *pValues = values;
2093     return SQLITE_OK;
2094   }
2095 
2096   freeStringArray(v->nColumn, values);
2097   return rc;
2098 }
2099 
2100 /* delete from %_content where rowid = [iRow ] */
content_delete(fulltext_vtab * v,sqlite_int64 iRow)2101 static int content_delete(fulltext_vtab *v, sqlite_int64 iRow){
2102   sqlite3_stmt *s;
2103   int rc = sql_get_statement(v, CONTENT_DELETE_STMT, &s);
2104   if( rc!=SQLITE_OK ) return rc;
2105 
2106   rc = sqlite3_bind_int64(s, 1, iRow);
2107   if( rc!=SQLITE_OK ) return rc;
2108 
2109   return sql_single_step(s);
2110 }
2111 
2112 /* Returns SQLITE_ROW if any rows exist in %_content, SQLITE_DONE if
2113 ** no rows exist, and any error in case of failure.
2114 */
content_exists(fulltext_vtab * v)2115 static int content_exists(fulltext_vtab *v){
2116   sqlite3_stmt *s;
2117   int rc = sql_get_statement(v, CONTENT_EXISTS_STMT, &s);
2118   if( rc!=SQLITE_OK ) return rc;
2119 
2120   rc = sqlite3_step(s);
2121   if( rc!=SQLITE_ROW ) return rc;
2122 
2123   /* We expect only one row.  We must execute another sqlite3_step()
2124    * to complete the iteration; otherwise the table will remain locked. */
2125   rc = sqlite3_step(s);
2126   if( rc==SQLITE_DONE ) return SQLITE_ROW;
2127   if( rc==SQLITE_ROW ) return SQLITE_ERROR;
2128   return rc;
2129 }
2130 
2131 /* insert into %_segments values ([pData])
2132 **   returns assigned rowid in *piBlockid
2133 */
block_insert(fulltext_vtab * v,const char * pData,int nData,sqlite_int64 * piBlockid)2134 static int block_insert(fulltext_vtab *v, const char *pData, int nData,
2135                         sqlite_int64 *piBlockid){
2136   sqlite3_stmt *s;
2137   int rc = sql_get_statement(v, BLOCK_INSERT_STMT, &s);
2138   if( rc!=SQLITE_OK ) return rc;
2139 
2140   rc = sqlite3_bind_blob(s, 1, pData, nData, SQLITE_STATIC);
2141   if( rc!=SQLITE_OK ) return rc;
2142 
2143   rc = sqlite3_step(s);
2144   if( rc==SQLITE_ROW ) return SQLITE_ERROR;
2145   if( rc!=SQLITE_DONE ) return rc;
2146 
2147   *piBlockid = sqlite3_last_insert_rowid(v->db);
2148   return SQLITE_OK;
2149 }
2150 
2151 /* delete from %_segments
2152 **   where rowid between [iStartBlockid] and [iEndBlockid]
2153 **
2154 ** Deletes the range of blocks, inclusive, used to delete the blocks
2155 ** which form a segment.
2156 */
block_delete(fulltext_vtab * v,sqlite_int64 iStartBlockid,sqlite_int64 iEndBlockid)2157 static int block_delete(fulltext_vtab *v,
2158                         sqlite_int64 iStartBlockid, sqlite_int64 iEndBlockid){
2159   sqlite3_stmt *s;
2160   int rc = sql_get_statement(v, BLOCK_DELETE_STMT, &s);
2161   if( rc!=SQLITE_OK ) return rc;
2162 
2163   rc = sqlite3_bind_int64(s, 1, iStartBlockid);
2164   if( rc!=SQLITE_OK ) return rc;
2165 
2166   rc = sqlite3_bind_int64(s, 2, iEndBlockid);
2167   if( rc!=SQLITE_OK ) return rc;
2168 
2169   return sql_single_step(s);
2170 }
2171 
2172 /* Returns SQLITE_ROW with *pidx set to the maximum segment idx found
2173 ** at iLevel.  Returns SQLITE_DONE if there are no segments at
2174 ** iLevel.  Otherwise returns an error.
2175 */
segdir_max_index(fulltext_vtab * v,int iLevel,int * pidx)2176 static int segdir_max_index(fulltext_vtab *v, int iLevel, int *pidx){
2177   sqlite3_stmt *s;
2178   int rc = sql_get_statement(v, SEGDIR_MAX_INDEX_STMT, &s);
2179   if( rc!=SQLITE_OK ) return rc;
2180 
2181   rc = sqlite3_bind_int(s, 1, iLevel);
2182   if( rc!=SQLITE_OK ) return rc;
2183 
2184   rc = sqlite3_step(s);
2185   /* Should always get at least one row due to how max() works. */
2186   if( rc==SQLITE_DONE ) return SQLITE_DONE;
2187   if( rc!=SQLITE_ROW ) return rc;
2188 
2189   /* NULL means that there were no inputs to max(). */
2190   if( SQLITE_NULL==sqlite3_column_type(s, 0) ){
2191     rc = sqlite3_step(s);
2192     if( rc==SQLITE_ROW ) return SQLITE_ERROR;
2193     return rc;
2194   }
2195 
2196   *pidx = sqlite3_column_int(s, 0);
2197 
2198   /* We expect only one row.  We must execute another sqlite3_step()
2199    * to complete the iteration; otherwise the table will remain locked. */
2200   rc = sqlite3_step(s);
2201   if( rc==SQLITE_ROW ) return SQLITE_ERROR;
2202   if( rc!=SQLITE_DONE ) return rc;
2203   return SQLITE_ROW;
2204 }
2205 
2206 /* insert into %_segdir values (
2207 **   [iLevel], [idx],
2208 **   [iStartBlockid], [iLeavesEndBlockid], [iEndBlockid],
2209 **   [pRootData]
2210 ** )
2211 */
segdir_set(fulltext_vtab * v,int iLevel,int idx,sqlite_int64 iStartBlockid,sqlite_int64 iLeavesEndBlockid,sqlite_int64 iEndBlockid,const char * pRootData,int nRootData)2212 static int segdir_set(fulltext_vtab *v, int iLevel, int idx,
2213                       sqlite_int64 iStartBlockid,
2214                       sqlite_int64 iLeavesEndBlockid,
2215                       sqlite_int64 iEndBlockid,
2216                       const char *pRootData, int nRootData){
2217   sqlite3_stmt *s;
2218   int rc = sql_get_statement(v, SEGDIR_SET_STMT, &s);
2219   if( rc!=SQLITE_OK ) return rc;
2220 
2221   rc = sqlite3_bind_int(s, 1, iLevel);
2222   if( rc!=SQLITE_OK ) return rc;
2223 
2224   rc = sqlite3_bind_int(s, 2, idx);
2225   if( rc!=SQLITE_OK ) return rc;
2226 
2227   rc = sqlite3_bind_int64(s, 3, iStartBlockid);
2228   if( rc!=SQLITE_OK ) return rc;
2229 
2230   rc = sqlite3_bind_int64(s, 4, iLeavesEndBlockid);
2231   if( rc!=SQLITE_OK ) return rc;
2232 
2233   rc = sqlite3_bind_int64(s, 5, iEndBlockid);
2234   if( rc!=SQLITE_OK ) return rc;
2235 
2236   rc = sqlite3_bind_blob(s, 6, pRootData, nRootData, SQLITE_STATIC);
2237   if( rc!=SQLITE_OK ) return rc;
2238 
2239   return sql_single_step(s);
2240 }
2241 
2242 /* Queries %_segdir for the block span of the segments in level
2243 ** iLevel.  Returns SQLITE_DONE if there are no blocks for iLevel,
2244 ** SQLITE_ROW if there are blocks, else an error.
2245 */
segdir_span(fulltext_vtab * v,int iLevel,sqlite_int64 * piStartBlockid,sqlite_int64 * piEndBlockid)2246 static int segdir_span(fulltext_vtab *v, int iLevel,
2247                        sqlite_int64 *piStartBlockid,
2248                        sqlite_int64 *piEndBlockid){
2249   sqlite3_stmt *s;
2250   int rc = sql_get_statement(v, SEGDIR_SPAN_STMT, &s);
2251   if( rc!=SQLITE_OK ) return rc;
2252 
2253   rc = sqlite3_bind_int(s, 1, iLevel);
2254   if( rc!=SQLITE_OK ) return rc;
2255 
2256   rc = sqlite3_step(s);
2257   if( rc==SQLITE_DONE ) return SQLITE_DONE;  /* Should never happen */
2258   if( rc!=SQLITE_ROW ) return rc;
2259 
2260   /* This happens if all segments at this level are entirely inline. */
2261   if( SQLITE_NULL==sqlite3_column_type(s, 0) ){
2262     /* We expect only one row.  We must execute another sqlite3_step()
2263      * to complete the iteration; otherwise the table will remain locked. */
2264     int rc2 = sqlite3_step(s);
2265     if( rc2==SQLITE_ROW ) return SQLITE_ERROR;
2266     return rc2;
2267   }
2268 
2269   *piStartBlockid = sqlite3_column_int64(s, 0);
2270   *piEndBlockid = sqlite3_column_int64(s, 1);
2271 
2272   /* We expect only one row.  We must execute another sqlite3_step()
2273    * to complete the iteration; otherwise the table will remain locked. */
2274   rc = sqlite3_step(s);
2275   if( rc==SQLITE_ROW ) return SQLITE_ERROR;
2276   if( rc!=SQLITE_DONE ) return rc;
2277   return SQLITE_ROW;
2278 }
2279 
2280 /* Delete the segment blocks and segment directory records for all
2281 ** segments at iLevel.
2282 */
segdir_delete(fulltext_vtab * v,int iLevel)2283 static int segdir_delete(fulltext_vtab *v, int iLevel){
2284   sqlite3_stmt *s;
2285   sqlite_int64 iStartBlockid, iEndBlockid;
2286   int rc = segdir_span(v, iLevel, &iStartBlockid, &iEndBlockid);
2287   if( rc!=SQLITE_ROW && rc!=SQLITE_DONE ) return rc;
2288 
2289   if( rc==SQLITE_ROW ){
2290     rc = block_delete(v, iStartBlockid, iEndBlockid);
2291     if( rc!=SQLITE_OK ) return rc;
2292   }
2293 
2294   /* Delete the segment directory itself. */
2295   rc = sql_get_statement(v, SEGDIR_DELETE_STMT, &s);
2296   if( rc!=SQLITE_OK ) return rc;
2297 
2298   rc = sqlite3_bind_int64(s, 1, iLevel);
2299   if( rc!=SQLITE_OK ) return rc;
2300 
2301   return sql_single_step(s);
2302 }
2303 
2304 /* Delete entire fts index, SQLITE_OK on success, relevant error on
2305 ** failure.
2306 */
segdir_delete_all(fulltext_vtab * v)2307 static int segdir_delete_all(fulltext_vtab *v){
2308   sqlite3_stmt *s;
2309   int rc = sql_get_statement(v, SEGDIR_DELETE_ALL_STMT, &s);
2310   if( rc!=SQLITE_OK ) return rc;
2311 
2312   rc = sql_single_step(s);
2313   if( rc!=SQLITE_OK ) return rc;
2314 
2315   rc = sql_get_statement(v, BLOCK_DELETE_ALL_STMT, &s);
2316   if( rc!=SQLITE_OK ) return rc;
2317 
2318   return sql_single_step(s);
2319 }
2320 
2321 /* Returns SQLITE_OK with *pnSegments set to the number of entries in
2322 ** %_segdir and *piMaxLevel set to the highest level which has a
2323 ** segment.  Otherwise returns the SQLite error which caused failure.
2324 */
segdir_count(fulltext_vtab * v,int * pnSegments,int * piMaxLevel)2325 static int segdir_count(fulltext_vtab *v, int *pnSegments, int *piMaxLevel){
2326   sqlite3_stmt *s;
2327   int rc = sql_get_statement(v, SEGDIR_COUNT_STMT, &s);
2328   if( rc!=SQLITE_OK ) return rc;
2329 
2330   rc = sqlite3_step(s);
2331   /* TODO(shess): This case should not be possible?  Should stronger
2332   ** measures be taken if it happens?
2333   */
2334   if( rc==SQLITE_DONE ){
2335     *pnSegments = 0;
2336     *piMaxLevel = 0;
2337     return SQLITE_OK;
2338   }
2339   if( rc!=SQLITE_ROW ) return rc;
2340 
2341   *pnSegments = sqlite3_column_int(s, 0);
2342   *piMaxLevel = sqlite3_column_int(s, 1);
2343 
2344   /* We expect only one row.  We must execute another sqlite3_step()
2345    * to complete the iteration; otherwise the table will remain locked. */
2346   rc = sqlite3_step(s);
2347   if( rc==SQLITE_DONE ) return SQLITE_OK;
2348   if( rc==SQLITE_ROW ) return SQLITE_ERROR;
2349   return rc;
2350 }
2351 
2352 /* TODO(shess) clearPendingTerms() is far down the file because
2353 ** writeZeroSegment() is far down the file because LeafWriter is far
2354 ** down the file.  Consider refactoring the code to move the non-vtab
2355 ** code above the vtab code so that we don't need this forward
2356 ** reference.
2357 */
2358 static int clearPendingTerms(fulltext_vtab *v);
2359 
2360 /*
2361 ** Free the memory used to contain a fulltext_vtab structure.
2362 */
fulltext_vtab_destroy(fulltext_vtab * v)2363 static void fulltext_vtab_destroy(fulltext_vtab *v){
2364   int iStmt, i;
2365 
2366   TRACE(("FTS2 Destroy %p\n", v));
2367   for( iStmt=0; iStmt<MAX_STMT; iStmt++ ){
2368     if( v->pFulltextStatements[iStmt]!=NULL ){
2369       sqlite3_finalize(v->pFulltextStatements[iStmt]);
2370       v->pFulltextStatements[iStmt] = NULL;
2371     }
2372   }
2373 
2374   for( i=0; i<MERGE_COUNT; i++ ){
2375     if( v->pLeafSelectStmts[i]!=NULL ){
2376       sqlite3_finalize(v->pLeafSelectStmts[i]);
2377       v->pLeafSelectStmts[i] = NULL;
2378     }
2379   }
2380 
2381   if( v->pTokenizer!=NULL ){
2382     v->pTokenizer->pModule->xDestroy(v->pTokenizer);
2383     v->pTokenizer = NULL;
2384   }
2385 
2386   clearPendingTerms(v);
2387 
2388   sqlite3_free(v->azColumn);
2389   for(i = 0; i < v->nColumn; ++i) {
2390     sqlite3_free(v->azContentColumn[i]);
2391   }
2392   sqlite3_free(v->azContentColumn);
2393   sqlite3_free(v);
2394 }
2395 
2396 /*
2397 ** Token types for parsing the arguments to xConnect or xCreate.
2398 */
2399 #define TOKEN_EOF         0    /* End of file */
2400 #define TOKEN_SPACE       1    /* Any kind of whitespace */
2401 #define TOKEN_ID          2    /* An identifier */
2402 #define TOKEN_STRING      3    /* A string literal */
2403 #define TOKEN_PUNCT       4    /* A single punctuation character */
2404 
2405 /*
2406 ** If X is a character that can be used in an identifier then
2407 ** IdChar(X) will be true.  Otherwise it is false.
2408 **
2409 ** For ASCII, any character with the high-order bit set is
2410 ** allowed in an identifier.  For 7-bit characters,
2411 ** sqlite3IsIdChar[X] must be 1.
2412 **
2413 ** Ticket #1066.  the SQL standard does not allow '$' in the
2414 ** middle of identfiers.  But many SQL implementations do.
2415 ** SQLite will allow '$' in identifiers for compatibility.
2416 ** But the feature is undocumented.
2417 */
2418 static const char isIdChar[] = {
2419 /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
2420     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
2421     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
2422     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
2423     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
2424     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
2425     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
2426 };
2427 #define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && isIdChar[c-0x20]))
2428 
2429 
2430 /*
2431 ** Return the length of the token that begins at z[0].
2432 ** Store the token type in *tokenType before returning.
2433 */
getToken(const char * z,int * tokenType)2434 static int getToken(const char *z, int *tokenType){
2435   int i, c;
2436   switch( *z ){
2437     case 0: {
2438       *tokenType = TOKEN_EOF;
2439       return 0;
2440     }
2441     case ' ': case '\t': case '\n': case '\f': case '\r': {
2442       for(i=1; safe_isspace(z[i]); i++){}
2443       *tokenType = TOKEN_SPACE;
2444       return i;
2445     }
2446     case '`':
2447     case '\'':
2448     case '"': {
2449       int delim = z[0];
2450       for(i=1; (c=z[i])!=0; i++){
2451         if( c==delim ){
2452           if( z[i+1]==delim ){
2453             i++;
2454           }else{
2455             break;
2456           }
2457         }
2458       }
2459       *tokenType = TOKEN_STRING;
2460       return i + (c!=0);
2461     }
2462     case '[': {
2463       for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
2464       *tokenType = TOKEN_ID;
2465       return i;
2466     }
2467     default: {
2468       if( !IdChar(*z) ){
2469         break;
2470       }
2471       for(i=1; IdChar(z[i]); i++){}
2472       *tokenType = TOKEN_ID;
2473       return i;
2474     }
2475   }
2476   *tokenType = TOKEN_PUNCT;
2477   return 1;
2478 }
2479 
2480 /*
2481 ** A token extracted from a string is an instance of the following
2482 ** structure.
2483 */
2484 typedef struct Token {
2485   const char *z;       /* Pointer to token text.  Not '\000' terminated */
2486   short int n;         /* Length of the token text in bytes. */
2487 } Token;
2488 
2489 /*
2490 ** Given a input string (which is really one of the argv[] parameters
2491 ** passed into xConnect or xCreate) split the string up into tokens.
2492 ** Return an array of pointers to '\000' terminated strings, one string
2493 ** for each non-whitespace token.
2494 **
2495 ** The returned array is terminated by a single NULL pointer.
2496 **
2497 ** Space to hold the returned array is obtained from a single
2498 ** malloc and should be freed by passing the return value to free().
2499 ** The individual strings within the token list are all a part of
2500 ** the single memory allocation and will all be freed at once.
2501 */
tokenizeString(const char * z,int * pnToken)2502 static char **tokenizeString(const char *z, int *pnToken){
2503   int nToken = 0;
2504   Token *aToken = sqlite3_malloc( strlen(z) * sizeof(aToken[0]) );
2505   int n = 1;
2506   int e, i;
2507   int totalSize = 0;
2508   char **azToken;
2509   char *zCopy;
2510   while( n>0 ){
2511     n = getToken(z, &e);
2512     if( e!=TOKEN_SPACE ){
2513       aToken[nToken].z = z;
2514       aToken[nToken].n = n;
2515       nToken++;
2516       totalSize += n+1;
2517     }
2518     z += n;
2519   }
2520   azToken = (char**)sqlite3_malloc( nToken*sizeof(char*) + totalSize );
2521   zCopy = (char*)&azToken[nToken];
2522   nToken--;
2523   for(i=0; i<nToken; i++){
2524     azToken[i] = zCopy;
2525     n = aToken[i].n;
2526     memcpy(zCopy, aToken[i].z, n);
2527     zCopy[n] = 0;
2528     zCopy += n+1;
2529   }
2530   azToken[nToken] = 0;
2531   sqlite3_free(aToken);
2532   *pnToken = nToken;
2533   return azToken;
2534 }
2535 
2536 /*
2537 ** Convert an SQL-style quoted string into a normal string by removing
2538 ** the quote characters.  The conversion is done in-place.  If the
2539 ** input does not begin with a quote character, then this routine
2540 ** is a no-op.
2541 **
2542 ** Examples:
2543 **
2544 **     "abc"   becomes   abc
2545 **     'xyz'   becomes   xyz
2546 **     [pqr]   becomes   pqr
2547 **     `mno`   becomes   mno
2548 */
dequoteString(char * z)2549 static void dequoteString(char *z){
2550   int quote;
2551   int i, j;
2552   if( z==0 ) return;
2553   quote = z[0];
2554   switch( quote ){
2555     case '\'':  break;
2556     case '"':   break;
2557     case '`':   break;                /* For MySQL compatibility */
2558     case '[':   quote = ']';  break;  /* For MS SqlServer compatibility */
2559     default:    return;
2560   }
2561   for(i=1, j=0; z[i]; i++){
2562     if( z[i]==quote ){
2563       if( z[i+1]==quote ){
2564         z[j++] = quote;
2565         i++;
2566       }else{
2567         z[j++] = 0;
2568         break;
2569       }
2570     }else{
2571       z[j++] = z[i];
2572     }
2573   }
2574 }
2575 
2576 /*
2577 ** The input azIn is a NULL-terminated list of tokens.  Remove the first
2578 ** token and all punctuation tokens.  Remove the quotes from
2579 ** around string literal tokens.
2580 **
2581 ** Example:
2582 **
2583 **     input:      tokenize chinese ( 'simplifed' , 'mixed' )
2584 **     output:     chinese simplifed mixed
2585 **
2586 ** Another example:
2587 **
2588 **     input:      delimiters ( '[' , ']' , '...' )
2589 **     output:     [ ] ...
2590 */
tokenListToIdList(char ** azIn)2591 static void tokenListToIdList(char **azIn){
2592   int i, j;
2593   if( azIn ){
2594     for(i=0, j=-1; azIn[i]; i++){
2595       if( safe_isalnum(azIn[i][0]) || azIn[i][1] ){
2596         dequoteString(azIn[i]);
2597         if( j>=0 ){
2598           azIn[j] = azIn[i];
2599         }
2600         j++;
2601       }
2602     }
2603     azIn[j] = 0;
2604   }
2605 }
2606 
2607 
2608 /*
2609 ** Find the first alphanumeric token in the string zIn.  Null-terminate
2610 ** this token.  Remove any quotation marks.  And return a pointer to
2611 ** the result.
2612 */
firstToken(char * zIn,char ** pzTail)2613 static char *firstToken(char *zIn, char **pzTail){
2614   int n, ttype;
2615   while(1){
2616     n = getToken(zIn, &ttype);
2617     if( ttype==TOKEN_SPACE ){
2618       zIn += n;
2619     }else if( ttype==TOKEN_EOF ){
2620       *pzTail = zIn;
2621       return 0;
2622     }else{
2623       zIn[n] = 0;
2624       *pzTail = &zIn[1];
2625       dequoteString(zIn);
2626       return zIn;
2627     }
2628   }
2629   /*NOTREACHED*/
2630 }
2631 
2632 /* Return true if...
2633 **
2634 **   *  s begins with the string t, ignoring case
2635 **   *  s is longer than t
2636 **   *  The first character of s beyond t is not a alphanumeric
2637 **
2638 ** Ignore leading space in *s.
2639 **
2640 ** To put it another way, return true if the first token of
2641 ** s[] is t[].
2642 */
startsWith(const char * s,const char * t)2643 static int startsWith(const char *s, const char *t){
2644   while( safe_isspace(*s) ){ s++; }
2645   while( *t ){
2646     if( safe_tolower(*s++)!=safe_tolower(*t++) ) return 0;
2647   }
2648   return *s!='_' && !safe_isalnum(*s);
2649 }
2650 
2651 /*
2652 ** An instance of this structure defines the "spec" of a
2653 ** full text index.  This structure is populated by parseSpec
2654 ** and use by fulltextConnect and fulltextCreate.
2655 */
2656 typedef struct TableSpec {
2657   const char *zDb;         /* Logical database name */
2658   const char *zName;       /* Name of the full-text index */
2659   int nColumn;             /* Number of columns to be indexed */
2660   char **azColumn;         /* Original names of columns to be indexed */
2661   char **azContentColumn;  /* Column names for %_content */
2662   char **azTokenizer;      /* Name of tokenizer and its arguments */
2663 } TableSpec;
2664 
2665 /*
2666 ** Reclaim all of the memory used by a TableSpec
2667 */
clearTableSpec(TableSpec * p)2668 static void clearTableSpec(TableSpec *p) {
2669   sqlite3_free(p->azColumn);
2670   sqlite3_free(p->azContentColumn);
2671   sqlite3_free(p->azTokenizer);
2672 }
2673 
2674 /* Parse a CREATE VIRTUAL TABLE statement, which looks like this:
2675  *
2676  * CREATE VIRTUAL TABLE email
2677  *        USING fts2(subject, body, tokenize mytokenizer(myarg))
2678  *
2679  * We return parsed information in a TableSpec structure.
2680  *
2681  */
parseSpec(TableSpec * pSpec,int argc,const char * const * argv,char ** pzErr)2682 static int parseSpec(TableSpec *pSpec, int argc, const char *const*argv,
2683                      char**pzErr){
2684   int i, n;
2685   char *z, *zDummy;
2686   char **azArg;
2687   const char *zTokenizer = 0;    /* argv[] entry describing the tokenizer */
2688 
2689   assert( argc>=3 );
2690   /* Current interface:
2691   ** argv[0] - module name
2692   ** argv[1] - database name
2693   ** argv[2] - table name
2694   ** argv[3..] - columns, optionally followed by tokenizer specification
2695   **             and snippet delimiters specification.
2696   */
2697 
2698   /* Make a copy of the complete argv[][] array in a single allocation.
2699   ** The argv[][] array is read-only and transient.  We can write to the
2700   ** copy in order to modify things and the copy is persistent.
2701   */
2702   CLEAR(pSpec);
2703   for(i=n=0; i<argc; i++){
2704     n += strlen(argv[i]) + 1;
2705   }
2706   azArg = sqlite3_malloc( sizeof(char*)*argc + n );
2707   if( azArg==0 ){
2708     return SQLITE_NOMEM;
2709   }
2710   z = (char*)&azArg[argc];
2711   for(i=0; i<argc; i++){
2712     azArg[i] = z;
2713     strcpy(z, argv[i]);
2714     z += strlen(z)+1;
2715   }
2716 
2717   /* Identify the column names and the tokenizer and delimiter arguments
2718   ** in the argv[][] array.
2719   */
2720   pSpec->zDb = azArg[1];
2721   pSpec->zName = azArg[2];
2722   pSpec->nColumn = 0;
2723   pSpec->azColumn = azArg;
2724   zTokenizer = "tokenize simple";
2725   for(i=3; i<argc; ++i){
2726     if( startsWith(azArg[i],"tokenize") ){
2727       zTokenizer = azArg[i];
2728     }else{
2729       z = azArg[pSpec->nColumn] = firstToken(azArg[i], &zDummy);
2730       pSpec->nColumn++;
2731     }
2732   }
2733   if( pSpec->nColumn==0 ){
2734     azArg[0] = "content";
2735     pSpec->nColumn = 1;
2736   }
2737 
2738   /*
2739   ** Construct the list of content column names.
2740   **
2741   ** Each content column name will be of the form cNNAAAA
2742   ** where NN is the column number and AAAA is the sanitized
2743   ** column name.  "sanitized" means that special characters are
2744   ** converted to "_".  The cNN prefix guarantees that all column
2745   ** names are unique.
2746   **
2747   ** The AAAA suffix is not strictly necessary.  It is included
2748   ** for the convenience of people who might examine the generated
2749   ** %_content table and wonder what the columns are used for.
2750   */
2751   pSpec->azContentColumn = sqlite3_malloc( pSpec->nColumn * sizeof(char *) );
2752   if( pSpec->azContentColumn==0 ){
2753     clearTableSpec(pSpec);
2754     return SQLITE_NOMEM;
2755   }
2756   for(i=0; i<pSpec->nColumn; i++){
2757     char *p;
2758     pSpec->azContentColumn[i] = sqlite3_mprintf("c%d%s", i, azArg[i]);
2759     for (p = pSpec->azContentColumn[i]; *p ; ++p) {
2760       if( !safe_isalnum(*p) ) *p = '_';
2761     }
2762   }
2763 
2764   /*
2765   ** Parse the tokenizer specification string.
2766   */
2767   pSpec->azTokenizer = tokenizeString(zTokenizer, &n);
2768   tokenListToIdList(pSpec->azTokenizer);
2769 
2770   return SQLITE_OK;
2771 }
2772 
2773 /*
2774 ** Generate a CREATE TABLE statement that describes the schema of
2775 ** the virtual table.  Return a pointer to this schema string.
2776 **
2777 ** Space is obtained from sqlite3_mprintf() and should be freed
2778 ** using sqlite3_free().
2779 */
fulltextSchema(int nColumn,const char * const * azColumn,const char * zTableName)2780 static char *fulltextSchema(
2781   int nColumn,                  /* Number of columns */
2782   const char *const* azColumn,  /* List of columns */
2783   const char *zTableName        /* Name of the table */
2784 ){
2785   int i;
2786   char *zSchema, *zNext;
2787   const char *zSep = "(";
2788   zSchema = sqlite3_mprintf("CREATE TABLE x");
2789   for(i=0; i<nColumn; i++){
2790     zNext = sqlite3_mprintf("%s%s%Q", zSchema, zSep, azColumn[i]);
2791     sqlite3_free(zSchema);
2792     zSchema = zNext;
2793     zSep = ",";
2794   }
2795   zNext = sqlite3_mprintf("%s,%Q)", zSchema, zTableName);
2796   sqlite3_free(zSchema);
2797   return zNext;
2798 }
2799 
2800 /*
2801 ** Build a new sqlite3_vtab structure that will describe the
2802 ** fulltext index defined by spec.
2803 */
constructVtab(sqlite3 * db,fts2Hash * pHash,TableSpec * spec,sqlite3_vtab ** ppVTab,char ** pzErr)2804 static int constructVtab(
2805   sqlite3 *db,              /* The SQLite database connection */
2806   fts2Hash *pHash,          /* Hash table containing tokenizers */
2807   TableSpec *spec,          /* Parsed spec information from parseSpec() */
2808   sqlite3_vtab **ppVTab,    /* Write the resulting vtab structure here */
2809   char **pzErr              /* Write any error message here */
2810 ){
2811   int rc;
2812   int n;
2813   fulltext_vtab *v = 0;
2814   const sqlite3_tokenizer_module *m = NULL;
2815   char *schema;
2816 
2817   char const *zTok;         /* Name of tokenizer to use for this fts table */
2818   int nTok;                 /* Length of zTok, including nul terminator */
2819 
2820   v = (fulltext_vtab *) sqlite3_malloc(sizeof(fulltext_vtab));
2821   if( v==0 ) return SQLITE_NOMEM;
2822   CLEAR(v);
2823   /* sqlite will initialize v->base */
2824   v->db = db;
2825   v->zDb = spec->zDb;       /* Freed when azColumn is freed */
2826   v->zName = spec->zName;   /* Freed when azColumn is freed */
2827   v->nColumn = spec->nColumn;
2828   v->azContentColumn = spec->azContentColumn;
2829   spec->azContentColumn = 0;
2830   v->azColumn = spec->azColumn;
2831   spec->azColumn = 0;
2832 
2833   if( spec->azTokenizer==0 ){
2834     return SQLITE_NOMEM;
2835   }
2836 
2837   zTok = spec->azTokenizer[0];
2838   if( !zTok ){
2839     zTok = "simple";
2840   }
2841   nTok = strlen(zTok)+1;
2842 
2843   m = (sqlite3_tokenizer_module *)sqlite3Fts2HashFind(pHash, zTok, nTok);
2844   if( !m ){
2845     *pzErr = sqlite3_mprintf("unknown tokenizer: %s", spec->azTokenizer[0]);
2846     rc = SQLITE_ERROR;
2847     goto err;
2848   }
2849 
2850   for(n=0; spec->azTokenizer[n]; n++){}
2851   if( n ){
2852     rc = m->xCreate(n-1, (const char*const*)&spec->azTokenizer[1],
2853                     &v->pTokenizer);
2854   }else{
2855     rc = m->xCreate(0, 0, &v->pTokenizer);
2856   }
2857   if( rc!=SQLITE_OK ) goto err;
2858   v->pTokenizer->pModule = m;
2859 
2860   /* TODO: verify the existence of backing tables foo_content, foo_term */
2861 
2862   schema = fulltextSchema(v->nColumn, (const char*const*)v->azColumn,
2863                           spec->zName);
2864   rc = sqlite3_declare_vtab(db, schema);
2865   sqlite3_free(schema);
2866   if( rc!=SQLITE_OK ) goto err;
2867 
2868   memset(v->pFulltextStatements, 0, sizeof(v->pFulltextStatements));
2869 
2870   /* Indicate that the buffer is not live. */
2871   v->nPendingData = -1;
2872 
2873   *ppVTab = &v->base;
2874   TRACE(("FTS2 Connect %p\n", v));
2875 
2876   return rc;
2877 
2878 err:
2879   fulltext_vtab_destroy(v);
2880   return rc;
2881 }
2882 
fulltextConnect(sqlite3 * db,void * pAux,int argc,const char * const * argv,sqlite3_vtab ** ppVTab,char ** pzErr)2883 static int fulltextConnect(
2884   sqlite3 *db,
2885   void *pAux,
2886   int argc, const char *const*argv,
2887   sqlite3_vtab **ppVTab,
2888   char **pzErr
2889 ){
2890   TableSpec spec;
2891   int rc = parseSpec(&spec, argc, argv, pzErr);
2892   if( rc!=SQLITE_OK ) return rc;
2893 
2894   rc = constructVtab(db, (fts2Hash *)pAux, &spec, ppVTab, pzErr);
2895   clearTableSpec(&spec);
2896   return rc;
2897 }
2898 
2899 /* The %_content table holds the text of each document, with
2900 ** the rowid used as the docid.
2901 */
2902 /* TODO(shess) This comment needs elaboration to match the updated
2903 ** code.  Work it into the top-of-file comment at that time.
2904 */
fulltextCreate(sqlite3 * db,void * pAux,int argc,const char * const * argv,sqlite3_vtab ** ppVTab,char ** pzErr)2905 static int fulltextCreate(sqlite3 *db, void *pAux,
2906                           int argc, const char * const *argv,
2907                           sqlite3_vtab **ppVTab, char **pzErr){
2908   int rc;
2909   TableSpec spec;
2910   StringBuffer schema;
2911   TRACE(("FTS2 Create\n"));
2912 
2913   rc = parseSpec(&spec, argc, argv, pzErr);
2914   if( rc!=SQLITE_OK ) return rc;
2915 
2916   initStringBuffer(&schema);
2917   append(&schema, "CREATE TABLE %_content(");
2918   appendList(&schema, spec.nColumn, spec.azContentColumn);
2919   append(&schema, ")");
2920   rc = sql_exec(db, spec.zDb, spec.zName, stringBufferData(&schema));
2921   stringBufferDestroy(&schema);
2922   if( rc!=SQLITE_OK ) goto out;
2923 
2924   rc = sql_exec(db, spec.zDb, spec.zName,
2925                 "create table %_segments(block blob);");
2926   if( rc!=SQLITE_OK ) goto out;
2927 
2928   rc = sql_exec(db, spec.zDb, spec.zName,
2929                 "create table %_segdir("
2930                 "  level integer,"
2931                 "  idx integer,"
2932                 "  start_block integer,"
2933                 "  leaves_end_block integer,"
2934                 "  end_block integer,"
2935                 "  root blob,"
2936                 "  primary key(level, idx)"
2937                 ");");
2938   if( rc!=SQLITE_OK ) goto out;
2939 
2940   rc = constructVtab(db, (fts2Hash *)pAux, &spec, ppVTab, pzErr);
2941 
2942 out:
2943   clearTableSpec(&spec);
2944   return rc;
2945 }
2946 
2947 /* Decide how to handle an SQL query. */
fulltextBestIndex(sqlite3_vtab * pVTab,sqlite3_index_info * pInfo)2948 static int fulltextBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
2949   int i;
2950   TRACE(("FTS2 BestIndex\n"));
2951 
2952   for(i=0; i<pInfo->nConstraint; ++i){
2953     const struct sqlite3_index_constraint *pConstraint;
2954     pConstraint = &pInfo->aConstraint[i];
2955     if( pConstraint->usable ) {
2956       if( pConstraint->iColumn==-1 &&
2957           pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
2958         pInfo->idxNum = QUERY_ROWID;      /* lookup by rowid */
2959         TRACE(("FTS2 QUERY_ROWID\n"));
2960       } else if( pConstraint->iColumn>=0 &&
2961                  pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
2962         /* full-text search */
2963         pInfo->idxNum = QUERY_FULLTEXT + pConstraint->iColumn;
2964         TRACE(("FTS2 QUERY_FULLTEXT %d\n", pConstraint->iColumn));
2965       } else continue;
2966 
2967       pInfo->aConstraintUsage[i].argvIndex = 1;
2968       pInfo->aConstraintUsage[i].omit = 1;
2969 
2970       /* An arbitrary value for now.
2971        * TODO: Perhaps rowid matches should be considered cheaper than
2972        * full-text searches. */
2973       pInfo->estimatedCost = 1.0;
2974 
2975       return SQLITE_OK;
2976     }
2977   }
2978   pInfo->idxNum = QUERY_GENERIC;
2979   return SQLITE_OK;
2980 }
2981 
fulltextDisconnect(sqlite3_vtab * pVTab)2982 static int fulltextDisconnect(sqlite3_vtab *pVTab){
2983   TRACE(("FTS2 Disconnect %p\n", pVTab));
2984   fulltext_vtab_destroy((fulltext_vtab *)pVTab);
2985   return SQLITE_OK;
2986 }
2987 
fulltextDestroy(sqlite3_vtab * pVTab)2988 static int fulltextDestroy(sqlite3_vtab *pVTab){
2989   fulltext_vtab *v = (fulltext_vtab *)pVTab;
2990   int rc;
2991 
2992   TRACE(("FTS2 Destroy %p\n", pVTab));
2993   rc = sql_exec(v->db, v->zDb, v->zName,
2994                 "drop table if exists %_content;"
2995                 "drop table if exists %_segments;"
2996                 "drop table if exists %_segdir;"
2997                 );
2998   if( rc!=SQLITE_OK ) return rc;
2999 
3000   fulltext_vtab_destroy((fulltext_vtab *)pVTab);
3001   return SQLITE_OK;
3002 }
3003 
fulltextOpen(sqlite3_vtab * pVTab,sqlite3_vtab_cursor ** ppCursor)3004 static int fulltextOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
3005   fulltext_cursor *c;
3006 
3007   c = (fulltext_cursor *) sqlite3_malloc(sizeof(fulltext_cursor));
3008   if( c ){
3009     memset(c, 0, sizeof(fulltext_cursor));
3010     /* sqlite will initialize c->base */
3011     *ppCursor = &c->base;
3012     TRACE(("FTS2 Open %p: %p\n", pVTab, c));
3013     return SQLITE_OK;
3014   }else{
3015     return SQLITE_NOMEM;
3016   }
3017 }
3018 
3019 
3020 /* Free all of the dynamically allocated memory held by *q
3021 */
queryClear(Query * q)3022 static void queryClear(Query *q){
3023   int i;
3024   for(i = 0; i < q->nTerms; ++i){
3025     sqlite3_free(q->pTerms[i].pTerm);
3026   }
3027   sqlite3_free(q->pTerms);
3028   CLEAR(q);
3029 }
3030 
3031 /* Free all of the dynamically allocated memory held by the
3032 ** Snippet
3033 */
snippetClear(Snippet * p)3034 static void snippetClear(Snippet *p){
3035   sqlite3_free(p->aMatch);
3036   sqlite3_free(p->zOffset);
3037   sqlite3_free(p->zSnippet);
3038   CLEAR(p);
3039 }
3040 /*
3041 ** Append a single entry to the p->aMatch[] log.
3042 */
snippetAppendMatch(Snippet * p,int iCol,int iTerm,int iStart,int nByte)3043 static void snippetAppendMatch(
3044   Snippet *p,               /* Append the entry to this snippet */
3045   int iCol, int iTerm,      /* The column and query term */
3046   int iStart, int nByte     /* Offset and size of the match */
3047 ){
3048   int i;
3049   struct snippetMatch *pMatch;
3050   if( p->nMatch+1>=p->nAlloc ){
3051     p->nAlloc = p->nAlloc*2 + 10;
3052     p->aMatch = sqlite3_realloc(p->aMatch, p->nAlloc*sizeof(p->aMatch[0]) );
3053     if( p->aMatch==0 ){
3054       p->nMatch = 0;
3055       p->nAlloc = 0;
3056       return;
3057     }
3058   }
3059   i = p->nMatch++;
3060   pMatch = &p->aMatch[i];
3061   pMatch->iCol = iCol;
3062   pMatch->iTerm = iTerm;
3063   pMatch->iStart = iStart;
3064   pMatch->nByte = nByte;
3065 }
3066 
3067 /*
3068 ** Sizing information for the circular buffer used in snippetOffsetsOfColumn()
3069 */
3070 #define FTS2_ROTOR_SZ   (32)
3071 #define FTS2_ROTOR_MASK (FTS2_ROTOR_SZ-1)
3072 
3073 /*
3074 ** Add entries to pSnippet->aMatch[] for every match that occurs against
3075 ** document zDoc[0..nDoc-1] which is stored in column iColumn.
3076 */
snippetOffsetsOfColumn(Query * pQuery,Snippet * pSnippet,int iColumn,const char * zDoc,int nDoc)3077 static void snippetOffsetsOfColumn(
3078   Query *pQuery,
3079   Snippet *pSnippet,
3080   int iColumn,
3081   const char *zDoc,
3082   int nDoc
3083 ){
3084   const sqlite3_tokenizer_module *pTModule;  /* The tokenizer module */
3085   sqlite3_tokenizer *pTokenizer;             /* The specific tokenizer */
3086   sqlite3_tokenizer_cursor *pTCursor;        /* Tokenizer cursor */
3087   fulltext_vtab *pVtab;                /* The full text index */
3088   int nColumn;                         /* Number of columns in the index */
3089   const QueryTerm *aTerm;              /* Query string terms */
3090   int nTerm;                           /* Number of query string terms */
3091   int i, j;                            /* Loop counters */
3092   int rc;                              /* Return code */
3093   unsigned int match, prevMatch;       /* Phrase search bitmasks */
3094   const char *zToken;                  /* Next token from the tokenizer */
3095   int nToken;                          /* Size of zToken */
3096   int iBegin, iEnd, iPos;              /* Offsets of beginning and end */
3097 
3098   /* The following variables keep a circular buffer of the last
3099   ** few tokens */
3100   unsigned int iRotor = 0;             /* Index of current token */
3101   int iRotorBegin[FTS2_ROTOR_SZ];      /* Beginning offset of token */
3102   int iRotorLen[FTS2_ROTOR_SZ];        /* Length of token */
3103 
3104   pVtab = pQuery->pFts;
3105   nColumn = pVtab->nColumn;
3106   pTokenizer = pVtab->pTokenizer;
3107   pTModule = pTokenizer->pModule;
3108   rc = pTModule->xOpen(pTokenizer, zDoc, nDoc, &pTCursor);
3109   if( rc ) return;
3110   pTCursor->pTokenizer = pTokenizer;
3111   aTerm = pQuery->pTerms;
3112   nTerm = pQuery->nTerms;
3113   if( nTerm>=FTS2_ROTOR_SZ ){
3114     nTerm = FTS2_ROTOR_SZ - 1;
3115   }
3116   prevMatch = 0;
3117   while(1){
3118     rc = pTModule->xNext(pTCursor, &zToken, &nToken, &iBegin, &iEnd, &iPos);
3119     if( rc ) break;
3120     iRotorBegin[iRotor&FTS2_ROTOR_MASK] = iBegin;
3121     iRotorLen[iRotor&FTS2_ROTOR_MASK] = iEnd-iBegin;
3122     match = 0;
3123     for(i=0; i<nTerm; i++){
3124       int iCol;
3125       iCol = aTerm[i].iColumn;
3126       if( iCol>=0 && iCol<nColumn && iCol!=iColumn ) continue;
3127       if( aTerm[i].nTerm>nToken ) continue;
3128       if( !aTerm[i].isPrefix && aTerm[i].nTerm<nToken ) continue;
3129       assert( aTerm[i].nTerm<=nToken );
3130       if( memcmp(aTerm[i].pTerm, zToken, aTerm[i].nTerm) ) continue;
3131       if( aTerm[i].iPhrase>1 && (prevMatch & (1<<i))==0 ) continue;
3132       match |= 1<<i;
3133       if( i==nTerm-1 || aTerm[i+1].iPhrase==1 ){
3134         for(j=aTerm[i].iPhrase-1; j>=0; j--){
3135           int k = (iRotor-j) & FTS2_ROTOR_MASK;
3136           snippetAppendMatch(pSnippet, iColumn, i-j,
3137                 iRotorBegin[k], iRotorLen[k]);
3138         }
3139       }
3140     }
3141     prevMatch = match<<1;
3142     iRotor++;
3143   }
3144   pTModule->xClose(pTCursor);
3145 }
3146 
3147 
3148 /*
3149 ** Compute all offsets for the current row of the query.
3150 ** If the offsets have already been computed, this routine is a no-op.
3151 */
snippetAllOffsets(fulltext_cursor * p)3152 static void snippetAllOffsets(fulltext_cursor *p){
3153   int nColumn;
3154   int iColumn, i;
3155   int iFirst, iLast;
3156   fulltext_vtab *pFts;
3157 
3158   if( p->snippet.nMatch ) return;
3159   if( p->q.nTerms==0 ) return;
3160   pFts = p->q.pFts;
3161   nColumn = pFts->nColumn;
3162   iColumn = (p->iCursorType - QUERY_FULLTEXT);
3163   if( iColumn<0 || iColumn>=nColumn ){
3164     iFirst = 0;
3165     iLast = nColumn-1;
3166   }else{
3167     iFirst = iColumn;
3168     iLast = iColumn;
3169   }
3170   for(i=iFirst; i<=iLast; i++){
3171     const char *zDoc;
3172     int nDoc;
3173     zDoc = (const char*)sqlite3_column_text(p->pStmt, i+1);
3174     nDoc = sqlite3_column_bytes(p->pStmt, i+1);
3175     snippetOffsetsOfColumn(&p->q, &p->snippet, i, zDoc, nDoc);
3176   }
3177 }
3178 
3179 /*
3180 ** Convert the information in the aMatch[] array of the snippet
3181 ** into the string zOffset[0..nOffset-1].
3182 */
snippetOffsetText(Snippet * p)3183 static void snippetOffsetText(Snippet *p){
3184   int i;
3185   int cnt = 0;
3186   StringBuffer sb;
3187   char zBuf[200];
3188   if( p->zOffset ) return;
3189   initStringBuffer(&sb);
3190   for(i=0; i<p->nMatch; i++){
3191     struct snippetMatch *pMatch = &p->aMatch[i];
3192     zBuf[0] = ' ';
3193     sqlite3_snprintf(sizeof(zBuf)-1, &zBuf[cnt>0], "%d %d %d %d",
3194         pMatch->iCol, pMatch->iTerm, pMatch->iStart, pMatch->nByte);
3195     append(&sb, zBuf);
3196     cnt++;
3197   }
3198   p->zOffset = stringBufferData(&sb);
3199   p->nOffset = stringBufferLength(&sb);
3200 }
3201 
3202 /*
3203 ** zDoc[0..nDoc-1] is phrase of text.  aMatch[0..nMatch-1] are a set
3204 ** of matching words some of which might be in zDoc.  zDoc is column
3205 ** number iCol.
3206 **
3207 ** iBreak is suggested spot in zDoc where we could begin or end an
3208 ** excerpt.  Return a value similar to iBreak but possibly adjusted
3209 ** to be a little left or right so that the break point is better.
3210 */
wordBoundary(int iBreak,const char * zDoc,int nDoc,struct snippetMatch * aMatch,int nMatch,int iCol)3211 static int wordBoundary(
3212   int iBreak,                   /* The suggested break point */
3213   const char *zDoc,             /* Document text */
3214   int nDoc,                     /* Number of bytes in zDoc[] */
3215   struct snippetMatch *aMatch,  /* Matching words */
3216   int nMatch,                   /* Number of entries in aMatch[] */
3217   int iCol                      /* The column number for zDoc[] */
3218 ){
3219   int i;
3220   if( iBreak<=10 ){
3221     return 0;
3222   }
3223   if( iBreak>=nDoc-10 ){
3224     return nDoc;
3225   }
3226   for(i=0; i<nMatch && aMatch[i].iCol<iCol; i++){}
3227   while( i<nMatch && aMatch[i].iStart+aMatch[i].nByte<iBreak ){ i++; }
3228   if( i<nMatch ){
3229     if( aMatch[i].iStart<iBreak+10 ){
3230       return aMatch[i].iStart;
3231     }
3232     if( i>0 && aMatch[i-1].iStart+aMatch[i-1].nByte>=iBreak ){
3233       return aMatch[i-1].iStart;
3234     }
3235   }
3236   for(i=1; i<=10; i++){
3237     if( safe_isspace(zDoc[iBreak-i]) ){
3238       return iBreak - i + 1;
3239     }
3240     if( safe_isspace(zDoc[iBreak+i]) ){
3241       return iBreak + i + 1;
3242     }
3243   }
3244   return iBreak;
3245 }
3246 
3247 
3248 
3249 /*
3250 ** Allowed values for Snippet.aMatch[].snStatus
3251 */
3252 #define SNIPPET_IGNORE  0   /* It is ok to omit this match from the snippet */
3253 #define SNIPPET_DESIRED 1   /* We want to include this match in the snippet */
3254 
3255 /*
3256 ** Generate the text of a snippet.
3257 */
snippetText(fulltext_cursor * pCursor,const char * zStartMark,const char * zEndMark,const char * zEllipsis)3258 static void snippetText(
3259   fulltext_cursor *pCursor,   /* The cursor we need the snippet for */
3260   const char *zStartMark,     /* Markup to appear before each match */
3261   const char *zEndMark,       /* Markup to appear after each match */
3262   const char *zEllipsis       /* Ellipsis mark */
3263 ){
3264   int i, j;
3265   struct snippetMatch *aMatch;
3266   int nMatch;
3267   int nDesired;
3268   StringBuffer sb;
3269   int tailCol;
3270   int tailOffset;
3271   int iCol;
3272   int nDoc;
3273   const char *zDoc;
3274   int iStart, iEnd;
3275   int tailEllipsis = 0;
3276   int iMatch;
3277 
3278 
3279   sqlite3_free(pCursor->snippet.zSnippet);
3280   pCursor->snippet.zSnippet = 0;
3281   aMatch = pCursor->snippet.aMatch;
3282   nMatch = pCursor->snippet.nMatch;
3283   initStringBuffer(&sb);
3284 
3285   for(i=0; i<nMatch; i++){
3286     aMatch[i].snStatus = SNIPPET_IGNORE;
3287   }
3288   nDesired = 0;
3289   for(i=0; i<pCursor->q.nTerms; i++){
3290     for(j=0; j<nMatch; j++){
3291       if( aMatch[j].iTerm==i ){
3292         aMatch[j].snStatus = SNIPPET_DESIRED;
3293         nDesired++;
3294         break;
3295       }
3296     }
3297   }
3298 
3299   iMatch = 0;
3300   tailCol = -1;
3301   tailOffset = 0;
3302   for(i=0; i<nMatch && nDesired>0; i++){
3303     if( aMatch[i].snStatus!=SNIPPET_DESIRED ) continue;
3304     nDesired--;
3305     iCol = aMatch[i].iCol;
3306     zDoc = (const char*)sqlite3_column_text(pCursor->pStmt, iCol+1);
3307     nDoc = sqlite3_column_bytes(pCursor->pStmt, iCol+1);
3308     iStart = aMatch[i].iStart - 40;
3309     iStart = wordBoundary(iStart, zDoc, nDoc, aMatch, nMatch, iCol);
3310     if( iStart<=10 ){
3311       iStart = 0;
3312     }
3313     if( iCol==tailCol && iStart<=tailOffset+20 ){
3314       iStart = tailOffset;
3315     }
3316     if( (iCol!=tailCol && tailCol>=0) || iStart!=tailOffset ){
3317       trimWhiteSpace(&sb);
3318       appendWhiteSpace(&sb);
3319       append(&sb, zEllipsis);
3320       appendWhiteSpace(&sb);
3321     }
3322     iEnd = aMatch[i].iStart + aMatch[i].nByte + 40;
3323     iEnd = wordBoundary(iEnd, zDoc, nDoc, aMatch, nMatch, iCol);
3324     if( iEnd>=nDoc-10 ){
3325       iEnd = nDoc;
3326       tailEllipsis = 0;
3327     }else{
3328       tailEllipsis = 1;
3329     }
3330     while( iMatch<nMatch && aMatch[iMatch].iCol<iCol ){ iMatch++; }
3331     while( iStart<iEnd ){
3332       while( iMatch<nMatch && aMatch[iMatch].iStart<iStart
3333              && aMatch[iMatch].iCol<=iCol ){
3334         iMatch++;
3335       }
3336       if( iMatch<nMatch && aMatch[iMatch].iStart<iEnd
3337              && aMatch[iMatch].iCol==iCol ){
3338         nappend(&sb, &zDoc[iStart], aMatch[iMatch].iStart - iStart);
3339         iStart = aMatch[iMatch].iStart;
3340         append(&sb, zStartMark);
3341         nappend(&sb, &zDoc[iStart], aMatch[iMatch].nByte);
3342         append(&sb, zEndMark);
3343         iStart += aMatch[iMatch].nByte;
3344         for(j=iMatch+1; j<nMatch; j++){
3345           if( aMatch[j].iTerm==aMatch[iMatch].iTerm
3346               && aMatch[j].snStatus==SNIPPET_DESIRED ){
3347             nDesired--;
3348             aMatch[j].snStatus = SNIPPET_IGNORE;
3349           }
3350         }
3351       }else{
3352         nappend(&sb, &zDoc[iStart], iEnd - iStart);
3353         iStart = iEnd;
3354       }
3355     }
3356     tailCol = iCol;
3357     tailOffset = iEnd;
3358   }
3359   trimWhiteSpace(&sb);
3360   if( tailEllipsis ){
3361     appendWhiteSpace(&sb);
3362     append(&sb, zEllipsis);
3363   }
3364   pCursor->snippet.zSnippet = stringBufferData(&sb);
3365   pCursor->snippet.nSnippet = stringBufferLength(&sb);
3366 }
3367 
3368 
3369 /*
3370 ** Close the cursor.  For additional information see the documentation
3371 ** on the xClose method of the virtual table interface.
3372 */
fulltextClose(sqlite3_vtab_cursor * pCursor)3373 static int fulltextClose(sqlite3_vtab_cursor *pCursor){
3374   fulltext_cursor *c = (fulltext_cursor *) pCursor;
3375   TRACE(("FTS2 Close %p\n", c));
3376   sqlite3_finalize(c->pStmt);
3377   queryClear(&c->q);
3378   snippetClear(&c->snippet);
3379   if( c->result.nData!=0 ) dlrDestroy(&c->reader);
3380   dataBufferDestroy(&c->result);
3381   sqlite3_free(c);
3382   return SQLITE_OK;
3383 }
3384 
fulltextNext(sqlite3_vtab_cursor * pCursor)3385 static int fulltextNext(sqlite3_vtab_cursor *pCursor){
3386   fulltext_cursor *c = (fulltext_cursor *) pCursor;
3387   int rc;
3388 
3389   TRACE(("FTS2 Next %p\n", pCursor));
3390   snippetClear(&c->snippet);
3391   if( c->iCursorType < QUERY_FULLTEXT ){
3392     /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */
3393     rc = sqlite3_step(c->pStmt);
3394     switch( rc ){
3395       case SQLITE_ROW:
3396         c->eof = 0;
3397         return SQLITE_OK;
3398       case SQLITE_DONE:
3399         c->eof = 1;
3400         return SQLITE_OK;
3401       default:
3402         c->eof = 1;
3403         return rc;
3404     }
3405   } else {  /* full-text query */
3406     rc = sqlite3_reset(c->pStmt);
3407     if( rc!=SQLITE_OK ) return rc;
3408 
3409     if( c->result.nData==0 || dlrAtEnd(&c->reader) ){
3410       c->eof = 1;
3411       return SQLITE_OK;
3412     }
3413     rc = sqlite3_bind_int64(c->pStmt, 1, dlrDocid(&c->reader));
3414     dlrStep(&c->reader);
3415     if( rc!=SQLITE_OK ) return rc;
3416     /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */
3417     rc = sqlite3_step(c->pStmt);
3418     if( rc==SQLITE_ROW ){   /* the case we expect */
3419       c->eof = 0;
3420       return SQLITE_OK;
3421     }
3422     /* an error occurred; abort */
3423     return rc==SQLITE_DONE ? SQLITE_ERROR : rc;
3424   }
3425 }
3426 
3427 
3428 /* TODO(shess) If we pushed LeafReader to the top of the file, or to
3429 ** another file, term_select() could be pushed above
3430 ** docListOfTerm().
3431 */
3432 static int termSelect(fulltext_vtab *v, int iColumn,
3433                       const char *pTerm, int nTerm, int isPrefix,
3434                       DocListType iType, DataBuffer *out);
3435 
3436 /* Return a DocList corresponding to the query term *pTerm.  If *pTerm
3437 ** is the first term of a phrase query, go ahead and evaluate the phrase
3438 ** query and return the doclist for the entire phrase query.
3439 **
3440 ** The resulting DL_DOCIDS doclist is stored in pResult, which is
3441 ** overwritten.
3442 */
docListOfTerm(fulltext_vtab * v,int iColumn,QueryTerm * pQTerm,DataBuffer * pResult)3443 static int docListOfTerm(
3444   fulltext_vtab *v,   /* The full text index */
3445   int iColumn,        /* column to restrict to.  No restriction if >=nColumn */
3446   QueryTerm *pQTerm,  /* Term we are looking for, or 1st term of a phrase */
3447   DataBuffer *pResult /* Write the result here */
3448 ){
3449   DataBuffer left, right, new;
3450   int i, rc;
3451 
3452   /* No phrase search if no position info. */
3453   assert( pQTerm->nPhrase==0 || DL_DEFAULT!=DL_DOCIDS );
3454 
3455   /* This code should never be called with buffered updates. */
3456   assert( v->nPendingData<0 );
3457 
3458   dataBufferInit(&left, 0);
3459   rc = termSelect(v, iColumn, pQTerm->pTerm, pQTerm->nTerm, pQTerm->isPrefix,
3460                   0<pQTerm->nPhrase ? DL_POSITIONS : DL_DOCIDS, &left);
3461   if( rc ) return rc;
3462   for(i=1; i<=pQTerm->nPhrase && left.nData>0; i++){
3463     dataBufferInit(&right, 0);
3464     rc = termSelect(v, iColumn, pQTerm[i].pTerm, pQTerm[i].nTerm,
3465                     pQTerm[i].isPrefix, DL_POSITIONS, &right);
3466     if( rc ){
3467       dataBufferDestroy(&left);
3468       return rc;
3469     }
3470     dataBufferInit(&new, 0);
3471     docListPhraseMerge(left.pData, left.nData, right.pData, right.nData,
3472                        i<pQTerm->nPhrase ? DL_POSITIONS : DL_DOCIDS, &new);
3473     dataBufferDestroy(&left);
3474     dataBufferDestroy(&right);
3475     left = new;
3476   }
3477   *pResult = left;
3478   return SQLITE_OK;
3479 }
3480 
3481 /* Add a new term pTerm[0..nTerm-1] to the query *q.
3482 */
queryAdd(Query * q,const char * pTerm,int nTerm)3483 static void queryAdd(Query *q, const char *pTerm, int nTerm){
3484   QueryTerm *t;
3485   ++q->nTerms;
3486   q->pTerms = sqlite3_realloc(q->pTerms, q->nTerms * sizeof(q->pTerms[0]));
3487   if( q->pTerms==0 ){
3488     q->nTerms = 0;
3489     return;
3490   }
3491   t = &q->pTerms[q->nTerms - 1];
3492   CLEAR(t);
3493   t->pTerm = sqlite3_malloc(nTerm+1);
3494   memcpy(t->pTerm, pTerm, nTerm);
3495   t->pTerm[nTerm] = 0;
3496   t->nTerm = nTerm;
3497   t->isOr = q->nextIsOr;
3498   t->isPrefix = 0;
3499   q->nextIsOr = 0;
3500   t->iColumn = q->nextColumn;
3501   q->nextColumn = q->dfltColumn;
3502 }
3503 
3504 /*
3505 ** Check to see if the string zToken[0...nToken-1] matches any
3506 ** column name in the virtual table.   If it does,
3507 ** return the zero-indexed column number.  If not, return -1.
3508 */
checkColumnSpecifier(fulltext_vtab * pVtab,const char * zToken,int nToken)3509 static int checkColumnSpecifier(
3510   fulltext_vtab *pVtab,    /* The virtual table */
3511   const char *zToken,      /* Text of the token */
3512   int nToken               /* Number of characters in the token */
3513 ){
3514   int i;
3515   for(i=0; i<pVtab->nColumn; i++){
3516     if( memcmp(pVtab->azColumn[i], zToken, nToken)==0
3517         && pVtab->azColumn[i][nToken]==0 ){
3518       return i;
3519     }
3520   }
3521   return -1;
3522 }
3523 
3524 /*
3525 ** Parse the text at pSegment[0..nSegment-1].  Add additional terms
3526 ** to the query being assemblied in pQuery.
3527 **
3528 ** inPhrase is true if pSegment[0..nSegement-1] is contained within
3529 ** double-quotes.  If inPhrase is true, then the first term
3530 ** is marked with the number of terms in the phrase less one and
3531 ** OR and "-" syntax is ignored.  If inPhrase is false, then every
3532 ** term found is marked with nPhrase=0 and OR and "-" syntax is significant.
3533 */
tokenizeSegment(sqlite3_tokenizer * pTokenizer,const char * pSegment,int nSegment,int inPhrase,Query * pQuery)3534 static int tokenizeSegment(
3535   sqlite3_tokenizer *pTokenizer,          /* The tokenizer to use */
3536   const char *pSegment, int nSegment,     /* Query expression being parsed */
3537   int inPhrase,                           /* True if within "..." */
3538   Query *pQuery                           /* Append results here */
3539 ){
3540   const sqlite3_tokenizer_module *pModule = pTokenizer->pModule;
3541   sqlite3_tokenizer_cursor *pCursor;
3542   int firstIndex = pQuery->nTerms;
3543   int iCol;
3544   int nTerm = 1;
3545 
3546   int rc = pModule->xOpen(pTokenizer, pSegment, nSegment, &pCursor);
3547   if( rc!=SQLITE_OK ) return rc;
3548   pCursor->pTokenizer = pTokenizer;
3549 
3550   while( 1 ){
3551     const char *pToken;
3552     int nToken, iBegin, iEnd, iPos;
3553 
3554     rc = pModule->xNext(pCursor,
3555                         &pToken, &nToken,
3556                         &iBegin, &iEnd, &iPos);
3557     if( rc!=SQLITE_OK ) break;
3558     if( !inPhrase &&
3559         pSegment[iEnd]==':' &&
3560          (iCol = checkColumnSpecifier(pQuery->pFts, pToken, nToken))>=0 ){
3561       pQuery->nextColumn = iCol;
3562       continue;
3563     }
3564     if( !inPhrase && pQuery->nTerms>0 && nToken==2
3565          && pSegment[iBegin]=='O' && pSegment[iBegin+1]=='R' ){
3566       pQuery->nextIsOr = 1;
3567       continue;
3568     }
3569     queryAdd(pQuery, pToken, nToken);
3570     if( !inPhrase && iBegin>0 && pSegment[iBegin-1]=='-' ){
3571       pQuery->pTerms[pQuery->nTerms-1].isNot = 1;
3572     }
3573     if( iEnd<nSegment && pSegment[iEnd]=='*' ){
3574       pQuery->pTerms[pQuery->nTerms-1].isPrefix = 1;
3575     }
3576     pQuery->pTerms[pQuery->nTerms-1].iPhrase = nTerm;
3577     if( inPhrase ){
3578       nTerm++;
3579     }
3580   }
3581 
3582   if( inPhrase && pQuery->nTerms>firstIndex ){
3583     pQuery->pTerms[firstIndex].nPhrase = pQuery->nTerms - firstIndex - 1;
3584   }
3585 
3586   return pModule->xClose(pCursor);
3587 }
3588 
3589 /* Parse a query string, yielding a Query object pQuery.
3590 **
3591 ** The calling function will need to queryClear() to clean up
3592 ** the dynamically allocated memory held by pQuery.
3593 */
parseQuery(fulltext_vtab * v,const char * zInput,int nInput,int dfltColumn,Query * pQuery)3594 static int parseQuery(
3595   fulltext_vtab *v,        /* The fulltext index */
3596   const char *zInput,      /* Input text of the query string */
3597   int nInput,              /* Size of the input text */
3598   int dfltColumn,          /* Default column of the index to match against */
3599   Query *pQuery            /* Write the parse results here. */
3600 ){
3601   int iInput, inPhrase = 0;
3602 
3603   if( zInput==0 ) nInput = 0;
3604   if( nInput<0 ) nInput = strlen(zInput);
3605   pQuery->nTerms = 0;
3606   pQuery->pTerms = NULL;
3607   pQuery->nextIsOr = 0;
3608   pQuery->nextColumn = dfltColumn;
3609   pQuery->dfltColumn = dfltColumn;
3610   pQuery->pFts = v;
3611 
3612   for(iInput=0; iInput<nInput; ++iInput){
3613     int i;
3614     for(i=iInput; i<nInput && zInput[i]!='"'; ++i){}
3615     if( i>iInput ){
3616       tokenizeSegment(v->pTokenizer, zInput+iInput, i-iInput, inPhrase,
3617                        pQuery);
3618     }
3619     iInput = i;
3620     if( i<nInput ){
3621       assert( zInput[i]=='"' );
3622       inPhrase = !inPhrase;
3623     }
3624   }
3625 
3626   if( inPhrase ){
3627     /* unmatched quote */
3628     queryClear(pQuery);
3629     return SQLITE_ERROR;
3630   }
3631   return SQLITE_OK;
3632 }
3633 
3634 /* TODO(shess) Refactor the code to remove this forward decl. */
3635 static int flushPendingTerms(fulltext_vtab *v);
3636 
3637 /* Perform a full-text query using the search expression in
3638 ** zInput[0..nInput-1].  Return a list of matching documents
3639 ** in pResult.
3640 **
3641 ** Queries must match column iColumn.  Or if iColumn>=nColumn
3642 ** they are allowed to match against any column.
3643 */
fulltextQuery(fulltext_vtab * v,int iColumn,const char * zInput,int nInput,DataBuffer * pResult,Query * pQuery)3644 static int fulltextQuery(
3645   fulltext_vtab *v,      /* The full text index */
3646   int iColumn,           /* Match against this column by default */
3647   const char *zInput,    /* The query string */
3648   int nInput,            /* Number of bytes in zInput[] */
3649   DataBuffer *pResult,   /* Write the result doclist here */
3650   Query *pQuery          /* Put parsed query string here */
3651 ){
3652   int i, iNext, rc;
3653   DataBuffer left, right, or, new;
3654   int nNot = 0;
3655   QueryTerm *aTerm;
3656 
3657   /* TODO(shess) Instead of flushing pendingTerms, we could query for
3658   ** the relevant term and merge the doclist into what we receive from
3659   ** the database.  Wait and see if this is a common issue, first.
3660   **
3661   ** A good reason not to flush is to not generate update-related
3662   ** error codes from here.
3663   */
3664 
3665   /* Flush any buffered updates before executing the query. */
3666   rc = flushPendingTerms(v);
3667   if( rc!=SQLITE_OK ) return rc;
3668 
3669   /* TODO(shess) I think that the queryClear() calls below are not
3670   ** necessary, because fulltextClose() already clears the query.
3671   */
3672   rc = parseQuery(v, zInput, nInput, iColumn, pQuery);
3673   if( rc!=SQLITE_OK ) return rc;
3674 
3675   /* Empty or NULL queries return no results. */
3676   if( pQuery->nTerms==0 ){
3677     dataBufferInit(pResult, 0);
3678     return SQLITE_OK;
3679   }
3680 
3681   /* Merge AND terms. */
3682   /* TODO(shess) I think we can early-exit if( i>nNot && left.nData==0 ). */
3683   aTerm = pQuery->pTerms;
3684   for(i = 0; i<pQuery->nTerms; i=iNext){
3685     if( aTerm[i].isNot ){
3686       /* Handle all NOT terms in a separate pass */
3687       nNot++;
3688       iNext = i + aTerm[i].nPhrase+1;
3689       continue;
3690     }
3691     iNext = i + aTerm[i].nPhrase + 1;
3692     rc = docListOfTerm(v, aTerm[i].iColumn, &aTerm[i], &right);
3693     if( rc ){
3694       if( i!=nNot ) dataBufferDestroy(&left);
3695       queryClear(pQuery);
3696       return rc;
3697     }
3698     while( iNext<pQuery->nTerms && aTerm[iNext].isOr ){
3699       rc = docListOfTerm(v, aTerm[iNext].iColumn, &aTerm[iNext], &or);
3700       iNext += aTerm[iNext].nPhrase + 1;
3701       if( rc ){
3702         if( i!=nNot ) dataBufferDestroy(&left);
3703         dataBufferDestroy(&right);
3704         queryClear(pQuery);
3705         return rc;
3706       }
3707       dataBufferInit(&new, 0);
3708       docListOrMerge(right.pData, right.nData, or.pData, or.nData, &new);
3709       dataBufferDestroy(&right);
3710       dataBufferDestroy(&or);
3711       right = new;
3712     }
3713     if( i==nNot ){           /* first term processed. */
3714       left = right;
3715     }else{
3716       dataBufferInit(&new, 0);
3717       docListAndMerge(left.pData, left.nData, right.pData, right.nData, &new);
3718       dataBufferDestroy(&right);
3719       dataBufferDestroy(&left);
3720       left = new;
3721     }
3722   }
3723 
3724   if( nNot==pQuery->nTerms ){
3725     /* We do not yet know how to handle a query of only NOT terms */
3726     return SQLITE_ERROR;
3727   }
3728 
3729   /* Do the EXCEPT terms */
3730   for(i=0; i<pQuery->nTerms;  i += aTerm[i].nPhrase + 1){
3731     if( !aTerm[i].isNot ) continue;
3732     rc = docListOfTerm(v, aTerm[i].iColumn, &aTerm[i], &right);
3733     if( rc ){
3734       queryClear(pQuery);
3735       dataBufferDestroy(&left);
3736       return rc;
3737     }
3738     dataBufferInit(&new, 0);
3739     docListExceptMerge(left.pData, left.nData, right.pData, right.nData, &new);
3740     dataBufferDestroy(&right);
3741     dataBufferDestroy(&left);
3742     left = new;
3743   }
3744 
3745   *pResult = left;
3746   return rc;
3747 }
3748 
3749 /*
3750 ** This is the xFilter interface for the virtual table.  See
3751 ** the virtual table xFilter method documentation for additional
3752 ** information.
3753 **
3754 ** If idxNum==QUERY_GENERIC then do a full table scan against
3755 ** the %_content table.
3756 **
3757 ** If idxNum==QUERY_ROWID then do a rowid lookup for a single entry
3758 ** in the %_content table.
3759 **
3760 ** If idxNum>=QUERY_FULLTEXT then use the full text index.  The
3761 ** column on the left-hand side of the MATCH operator is column
3762 ** number idxNum-QUERY_FULLTEXT, 0 indexed.  argv[0] is the right-hand
3763 ** side of the MATCH operator.
3764 */
3765 /* TODO(shess) Upgrade the cursor initialization and destruction to
3766 ** account for fulltextFilter() being called multiple times on the
3767 ** same cursor.  The current solution is very fragile.  Apply fix to
3768 ** fts2 as appropriate.
3769 */
fulltextFilter(sqlite3_vtab_cursor * pCursor,int idxNum,const char * idxStr,int argc,sqlite3_value ** argv)3770 static int fulltextFilter(
3771   sqlite3_vtab_cursor *pCursor,     /* The cursor used for this query */
3772   int idxNum, const char *idxStr,   /* Which indexing scheme to use */
3773   int argc, sqlite3_value **argv    /* Arguments for the indexing scheme */
3774 ){
3775   fulltext_cursor *c = (fulltext_cursor *) pCursor;
3776   fulltext_vtab *v = cursor_vtab(c);
3777   int rc;
3778 
3779   TRACE(("FTS2 Filter %p\n",pCursor));
3780 
3781   /* If the cursor has a statement that was not prepared according to
3782   ** idxNum, clear it.  I believe all calls to fulltextFilter with a
3783   ** given cursor will have the same idxNum , but in this case it's
3784   ** easy to be safe.
3785   */
3786   if( c->pStmt && c->iCursorType!=idxNum ){
3787     sqlite3_finalize(c->pStmt);
3788     c->pStmt = NULL;
3789   }
3790 
3791   /* Get a fresh statement appropriate to idxNum. */
3792   /* TODO(shess): Add a prepared-statement cache in the vt structure.
3793   ** The cache must handle multiple open cursors.  Easier to cache the
3794   ** statement variants at the vt to reduce malloc/realloc/free here.
3795   ** Or we could have a StringBuffer variant which allowed stack
3796   ** construction for small values.
3797   */
3798   if( !c->pStmt ){
3799     char *zSql = sqlite3_mprintf("select rowid, * from %%_content %s",
3800                                  idxNum==QUERY_GENERIC ? "" : "where rowid=?");
3801     rc = sql_prepare(v->db, v->zDb, v->zName, &c->pStmt, zSql);
3802     sqlite3_free(zSql);
3803     if( rc!=SQLITE_OK ) return rc;
3804     c->iCursorType = idxNum;
3805   }else{
3806     sqlite3_reset(c->pStmt);
3807     assert( c->iCursorType==idxNum );
3808   }
3809 
3810   switch( idxNum ){
3811     case QUERY_GENERIC:
3812       break;
3813 
3814     case QUERY_ROWID:
3815       rc = sqlite3_bind_int64(c->pStmt, 1, sqlite3_value_int64(argv[0]));
3816       if( rc!=SQLITE_OK ) return rc;
3817       break;
3818 
3819     default:   /* full-text search */
3820     {
3821       const char *zQuery = (const char *)sqlite3_value_text(argv[0]);
3822       assert( idxNum<=QUERY_FULLTEXT+v->nColumn);
3823       assert( argc==1 );
3824       queryClear(&c->q);
3825       if( c->result.nData!=0 ){
3826         /* This case happens if the same cursor is used repeatedly. */
3827         dlrDestroy(&c->reader);
3828         dataBufferReset(&c->result);
3829       }else{
3830         dataBufferInit(&c->result, 0);
3831       }
3832       rc = fulltextQuery(v, idxNum-QUERY_FULLTEXT, zQuery, -1, &c->result, &c->q);
3833       if( rc!=SQLITE_OK ) return rc;
3834       if( c->result.nData!=0 ){
3835         dlrInit(&c->reader, DL_DOCIDS, c->result.pData, c->result.nData);
3836       }
3837       break;
3838     }
3839   }
3840 
3841   return fulltextNext(pCursor);
3842 }
3843 
3844 /* This is the xEof method of the virtual table.  The SQLite core
3845 ** calls this routine to find out if it has reached the end of
3846 ** a query's results set.
3847 */
fulltextEof(sqlite3_vtab_cursor * pCursor)3848 static int fulltextEof(sqlite3_vtab_cursor *pCursor){
3849   fulltext_cursor *c = (fulltext_cursor *) pCursor;
3850   return c->eof;
3851 }
3852 
3853 /* This is the xColumn method of the virtual table.  The SQLite
3854 ** core calls this method during a query when it needs the value
3855 ** of a column from the virtual table.  This method needs to use
3856 ** one of the sqlite3_result_*() routines to store the requested
3857 ** value back in the pContext.
3858 */
fulltextColumn(sqlite3_vtab_cursor * pCursor,sqlite3_context * pContext,int idxCol)3859 static int fulltextColumn(sqlite3_vtab_cursor *pCursor,
3860                           sqlite3_context *pContext, int idxCol){
3861   fulltext_cursor *c = (fulltext_cursor *) pCursor;
3862   fulltext_vtab *v = cursor_vtab(c);
3863 
3864   if( idxCol<v->nColumn ){
3865     sqlite3_value *pVal = sqlite3_column_value(c->pStmt, idxCol+1);
3866     sqlite3_result_value(pContext, pVal);
3867   }else if( idxCol==v->nColumn ){
3868     /* The extra column whose name is the same as the table.
3869     ** Return a blob which is a pointer to the cursor
3870     */
3871     sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT);
3872   }
3873   return SQLITE_OK;
3874 }
3875 
3876 /* This is the xRowid method.  The SQLite core calls this routine to
3877 ** retrive the rowid for the current row of the result set.  The
3878 ** rowid should be written to *pRowid.
3879 */
fulltextRowid(sqlite3_vtab_cursor * pCursor,sqlite_int64 * pRowid)3880 static int fulltextRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
3881   fulltext_cursor *c = (fulltext_cursor *) pCursor;
3882 
3883   *pRowid = sqlite3_column_int64(c->pStmt, 0);
3884   return SQLITE_OK;
3885 }
3886 
3887 /* Add all terms in [zText] to pendingTerms table.  If [iColumn] > 0,
3888 ** we also store positions and offsets in the hash table using that
3889 ** column number.
3890 */
buildTerms(fulltext_vtab * v,sqlite_int64 iDocid,const char * zText,int iColumn)3891 static int buildTerms(fulltext_vtab *v, sqlite_int64 iDocid,
3892                       const char *zText, int iColumn){
3893   sqlite3_tokenizer *pTokenizer = v->pTokenizer;
3894   sqlite3_tokenizer_cursor *pCursor;
3895   const char *pToken;
3896   int nTokenBytes;
3897   int iStartOffset, iEndOffset, iPosition;
3898   int rc;
3899 
3900   rc = pTokenizer->pModule->xOpen(pTokenizer, zText, -1, &pCursor);
3901   if( rc!=SQLITE_OK ) return rc;
3902 
3903   pCursor->pTokenizer = pTokenizer;
3904   while( SQLITE_OK==(rc=pTokenizer->pModule->xNext(pCursor,
3905                                                    &pToken, &nTokenBytes,
3906                                                    &iStartOffset, &iEndOffset,
3907                                                    &iPosition)) ){
3908     DLCollector *p;
3909     int nData;                   /* Size of doclist before our update. */
3910 
3911     /* Positions can't be negative; we use -1 as a terminator
3912      * internally.  Token can't be NULL or empty. */
3913     if( iPosition<0 || pToken == NULL || nTokenBytes == 0 ){
3914       rc = SQLITE_ERROR;
3915       break;
3916     }
3917 
3918     p = fts2HashFind(&v->pendingTerms, pToken, nTokenBytes);
3919     if( p==NULL ){
3920       nData = 0;
3921       p = dlcNew(iDocid, DL_DEFAULT);
3922       fts2HashInsert(&v->pendingTerms, pToken, nTokenBytes, p);
3923 
3924       /* Overhead for our hash table entry, the key, and the value. */
3925       v->nPendingData += sizeof(struct fts2HashElem)+sizeof(*p)+nTokenBytes;
3926     }else{
3927       nData = p->b.nData;
3928       if( p->dlw.iPrevDocid!=iDocid ) dlcNext(p, iDocid);
3929     }
3930     if( iColumn>=0 ){
3931       dlcAddPos(p, iColumn, iPosition, iStartOffset, iEndOffset);
3932     }
3933 
3934     /* Accumulate data added by dlcNew or dlcNext, and dlcAddPos. */
3935     v->nPendingData += p->b.nData-nData;
3936   }
3937 
3938   /* TODO(shess) Check return?  Should this be able to cause errors at
3939   ** this point?  Actually, same question about sqlite3_finalize(),
3940   ** though one could argue that failure there means that the data is
3941   ** not durable.  *ponder*
3942   */
3943   pTokenizer->pModule->xClose(pCursor);
3944   if( SQLITE_DONE == rc ) return SQLITE_OK;
3945   return rc;
3946 }
3947 
3948 /* Add doclists for all terms in [pValues] to pendingTerms table. */
insertTerms(fulltext_vtab * v,sqlite_int64 iRowid,sqlite3_value ** pValues)3949 static int insertTerms(fulltext_vtab *v, sqlite_int64 iRowid,
3950                        sqlite3_value **pValues){
3951   int i;
3952   for(i = 0; i < v->nColumn ; ++i){
3953     char *zText = (char*)sqlite3_value_text(pValues[i]);
3954     int rc = buildTerms(v, iRowid, zText, i);
3955     if( rc!=SQLITE_OK ) return rc;
3956   }
3957   return SQLITE_OK;
3958 }
3959 
3960 /* Add empty doclists for all terms in the given row's content to
3961 ** pendingTerms.
3962 */
deleteTerms(fulltext_vtab * v,sqlite_int64 iRowid)3963 static int deleteTerms(fulltext_vtab *v, sqlite_int64 iRowid){
3964   const char **pValues;
3965   int i, rc;
3966 
3967   /* TODO(shess) Should we allow such tables at all? */
3968   if( DL_DEFAULT==DL_DOCIDS ) return SQLITE_ERROR;
3969 
3970   rc = content_select(v, iRowid, &pValues);
3971   if( rc!=SQLITE_OK ) return rc;
3972 
3973   for(i = 0 ; i < v->nColumn; ++i) {
3974     rc = buildTerms(v, iRowid, pValues[i], -1);
3975     if( rc!=SQLITE_OK ) break;
3976   }
3977 
3978   freeStringArray(v->nColumn, pValues);
3979   return SQLITE_OK;
3980 }
3981 
3982 /* TODO(shess) Refactor the code to remove this forward decl. */
3983 static int initPendingTerms(fulltext_vtab *v, sqlite_int64 iDocid);
3984 
3985 /* Insert a row into the %_content table; set *piRowid to be the ID of the
3986 ** new row.  Add doclists for terms to pendingTerms.
3987 */
index_insert(fulltext_vtab * v,sqlite3_value * pRequestRowid,sqlite3_value ** pValues,sqlite_int64 * piRowid)3988 static int index_insert(fulltext_vtab *v, sqlite3_value *pRequestRowid,
3989                         sqlite3_value **pValues, sqlite_int64 *piRowid){
3990   int rc;
3991 
3992   rc = content_insert(v, pRequestRowid, pValues);  /* execute an SQL INSERT */
3993   if( rc!=SQLITE_OK ) return rc;
3994 
3995   *piRowid = sqlite3_last_insert_rowid(v->db);
3996   rc = initPendingTerms(v, *piRowid);
3997   if( rc!=SQLITE_OK ) return rc;
3998 
3999   return insertTerms(v, *piRowid, pValues);
4000 }
4001 
4002 /* Delete a row from the %_content table; add empty doclists for terms
4003 ** to pendingTerms.
4004 */
index_delete(fulltext_vtab * v,sqlite_int64 iRow)4005 static int index_delete(fulltext_vtab *v, sqlite_int64 iRow){
4006   int rc = initPendingTerms(v, iRow);
4007   if( rc!=SQLITE_OK ) return rc;
4008 
4009   rc = deleteTerms(v, iRow);
4010   if( rc!=SQLITE_OK ) return rc;
4011 
4012   return content_delete(v, iRow);  /* execute an SQL DELETE */
4013 }
4014 
4015 /* Update a row in the %_content table; add delete doclists to
4016 ** pendingTerms for old terms not in the new data, add insert doclists
4017 ** to pendingTerms for terms in the new data.
4018 */
index_update(fulltext_vtab * v,sqlite_int64 iRow,sqlite3_value ** pValues)4019 static int index_update(fulltext_vtab *v, sqlite_int64 iRow,
4020                         sqlite3_value **pValues){
4021   int rc = initPendingTerms(v, iRow);
4022   if( rc!=SQLITE_OK ) return rc;
4023 
4024   /* Generate an empty doclist for each term that previously appeared in this
4025    * row. */
4026   rc = deleteTerms(v, iRow);
4027   if( rc!=SQLITE_OK ) return rc;
4028 
4029   rc = content_update(v, pValues, iRow);  /* execute an SQL UPDATE */
4030   if( rc!=SQLITE_OK ) return rc;
4031 
4032   /* Now add positions for terms which appear in the updated row. */
4033   return insertTerms(v, iRow, pValues);
4034 }
4035 
4036 /*******************************************************************/
4037 /* InteriorWriter is used to collect terms and block references into
4038 ** interior nodes in %_segments.  See commentary at top of file for
4039 ** format.
4040 */
4041 
4042 /* How large interior nodes can grow. */
4043 #define INTERIOR_MAX 2048
4044 
4045 /* Minimum number of terms per interior node (except the root). This
4046 ** prevents large terms from making the tree too skinny - must be >0
4047 ** so that the tree always makes progress.  Note that the min tree
4048 ** fanout will be INTERIOR_MIN_TERMS+1.
4049 */
4050 #define INTERIOR_MIN_TERMS 7
4051 #if INTERIOR_MIN_TERMS<1
4052 # error INTERIOR_MIN_TERMS must be greater than 0.
4053 #endif
4054 
4055 /* ROOT_MAX controls how much data is stored inline in the segment
4056 ** directory.
4057 */
4058 /* TODO(shess) Push ROOT_MAX down to whoever is writing things.  It's
4059 ** only here so that interiorWriterRootInfo() and leafWriterRootInfo()
4060 ** can both see it, but if the caller passed it in, we wouldn't even
4061 ** need a define.
4062 */
4063 #define ROOT_MAX 1024
4064 #if ROOT_MAX<VARINT_MAX*2
4065 # error ROOT_MAX must have enough space for a header.
4066 #endif
4067 
4068 /* InteriorBlock stores a linked-list of interior blocks while a lower
4069 ** layer is being constructed.
4070 */
4071 typedef struct InteriorBlock {
4072   DataBuffer term;           /* Leftmost term in block's subtree. */
4073   DataBuffer data;           /* Accumulated data for the block. */
4074   struct InteriorBlock *next;
4075 } InteriorBlock;
4076 
interiorBlockNew(int iHeight,sqlite_int64 iChildBlock,const char * pTerm,int nTerm)4077 static InteriorBlock *interiorBlockNew(int iHeight, sqlite_int64 iChildBlock,
4078                                        const char *pTerm, int nTerm){
4079   InteriorBlock *block = sqlite3_malloc(sizeof(InteriorBlock));
4080   char c[VARINT_MAX+VARINT_MAX];
4081   int n;
4082 
4083   if( block ){
4084     memset(block, 0, sizeof(*block));
4085     dataBufferInit(&block->term, 0);
4086     dataBufferReplace(&block->term, pTerm, nTerm);
4087 
4088     n = putVarint(c, iHeight);
4089     n += putVarint(c+n, iChildBlock);
4090     dataBufferInit(&block->data, INTERIOR_MAX);
4091     dataBufferReplace(&block->data, c, n);
4092   }
4093   return block;
4094 }
4095 
4096 #ifndef NDEBUG
4097 /* Verify that the data is readable as an interior node. */
interiorBlockValidate(InteriorBlock * pBlock)4098 static void interiorBlockValidate(InteriorBlock *pBlock){
4099   const char *pData = pBlock->data.pData;
4100   int nData = pBlock->data.nData;
4101   int n, iDummy;
4102   sqlite_int64 iBlockid;
4103 
4104   assert( nData>0 );
4105   assert( pData!=0 );
4106   assert( pData+nData>pData );
4107 
4108   /* Must lead with height of node as a varint(n), n>0 */
4109   n = getVarint32(pData, &iDummy);
4110   assert( n>0 );
4111   assert( iDummy>0 );
4112   assert( n<nData );
4113   pData += n;
4114   nData -= n;
4115 
4116   /* Must contain iBlockid. */
4117   n = getVarint(pData, &iBlockid);
4118   assert( n>0 );
4119   assert( n<=nData );
4120   pData += n;
4121   nData -= n;
4122 
4123   /* Zero or more terms of positive length */
4124   if( nData!=0 ){
4125     /* First term is not delta-encoded. */
4126     n = getVarint32(pData, &iDummy);
4127     assert( n>0 );
4128     assert( iDummy>0 );
4129     assert( n+iDummy>0);
4130     assert( n+iDummy<=nData );
4131     pData += n+iDummy;
4132     nData -= n+iDummy;
4133 
4134     /* Following terms delta-encoded. */
4135     while( nData!=0 ){
4136       /* Length of shared prefix. */
4137       n = getVarint32(pData, &iDummy);
4138       assert( n>0 );
4139       assert( iDummy>=0 );
4140       assert( n<nData );
4141       pData += n;
4142       nData -= n;
4143 
4144       /* Length and data of distinct suffix. */
4145       n = getVarint32(pData, &iDummy);
4146       assert( n>0 );
4147       assert( iDummy>0 );
4148       assert( n+iDummy>0);
4149       assert( n+iDummy<=nData );
4150       pData += n+iDummy;
4151       nData -= n+iDummy;
4152     }
4153   }
4154 }
4155 #define ASSERT_VALID_INTERIOR_BLOCK(x) interiorBlockValidate(x)
4156 #else
4157 #define ASSERT_VALID_INTERIOR_BLOCK(x) assert( 1 )
4158 #endif
4159 
4160 typedef struct InteriorWriter {
4161   int iHeight;                   /* from 0 at leaves. */
4162   InteriorBlock *first, *last;
4163   struct InteriorWriter *parentWriter;
4164 
4165   DataBuffer term;               /* Last term written to block "last". */
4166   sqlite_int64 iOpeningChildBlock; /* First child block in block "last". */
4167 #ifndef NDEBUG
4168   sqlite_int64 iLastChildBlock;  /* for consistency checks. */
4169 #endif
4170 } InteriorWriter;
4171 
4172 /* Initialize an interior node where pTerm[nTerm] marks the leftmost
4173 ** term in the tree.  iChildBlock is the leftmost child block at the
4174 ** next level down the tree.
4175 */
interiorWriterInit(int iHeight,const char * pTerm,int nTerm,sqlite_int64 iChildBlock,InteriorWriter * pWriter)4176 static void interiorWriterInit(int iHeight, const char *pTerm, int nTerm,
4177                                sqlite_int64 iChildBlock,
4178                                InteriorWriter *pWriter){
4179   InteriorBlock *block;
4180   assert( iHeight>0 );
4181   CLEAR(pWriter);
4182 
4183   pWriter->iHeight = iHeight;
4184   pWriter->iOpeningChildBlock = iChildBlock;
4185 #ifndef NDEBUG
4186   pWriter->iLastChildBlock = iChildBlock;
4187 #endif
4188   block = interiorBlockNew(iHeight, iChildBlock, pTerm, nTerm);
4189   pWriter->last = pWriter->first = block;
4190   ASSERT_VALID_INTERIOR_BLOCK(pWriter->last);
4191   dataBufferInit(&pWriter->term, 0);
4192 }
4193 
4194 /* Append the child node rooted at iChildBlock to the interior node,
4195 ** with pTerm[nTerm] as the leftmost term in iChildBlock's subtree.
4196 */
interiorWriterAppend(InteriorWriter * pWriter,const char * pTerm,int nTerm,sqlite_int64 iChildBlock)4197 static void interiorWriterAppend(InteriorWriter *pWriter,
4198                                  const char *pTerm, int nTerm,
4199                                  sqlite_int64 iChildBlock){
4200   char c[VARINT_MAX+VARINT_MAX];
4201   int n, nPrefix = 0;
4202 
4203   ASSERT_VALID_INTERIOR_BLOCK(pWriter->last);
4204 
4205   /* The first term written into an interior node is actually
4206   ** associated with the second child added (the first child was added
4207   ** in interiorWriterInit, or in the if clause at the bottom of this
4208   ** function).  That term gets encoded straight up, with nPrefix left
4209   ** at 0.
4210   */
4211   if( pWriter->term.nData==0 ){
4212     n = putVarint(c, nTerm);
4213   }else{
4214     while( nPrefix<pWriter->term.nData &&
4215            pTerm[nPrefix]==pWriter->term.pData[nPrefix] ){
4216       nPrefix++;
4217     }
4218 
4219     n = putVarint(c, nPrefix);
4220     n += putVarint(c+n, nTerm-nPrefix);
4221   }
4222 
4223 #ifndef NDEBUG
4224   pWriter->iLastChildBlock++;
4225 #endif
4226   assert( pWriter->iLastChildBlock==iChildBlock );
4227 
4228   /* Overflow to a new block if the new term makes the current block
4229   ** too big, and the current block already has enough terms.
4230   */
4231   if( pWriter->last->data.nData+n+nTerm-nPrefix>INTERIOR_MAX &&
4232       iChildBlock-pWriter->iOpeningChildBlock>INTERIOR_MIN_TERMS ){
4233     pWriter->last->next = interiorBlockNew(pWriter->iHeight, iChildBlock,
4234                                            pTerm, nTerm);
4235     pWriter->last = pWriter->last->next;
4236     pWriter->iOpeningChildBlock = iChildBlock;
4237     dataBufferReset(&pWriter->term);
4238   }else{
4239     dataBufferAppend2(&pWriter->last->data, c, n,
4240                       pTerm+nPrefix, nTerm-nPrefix);
4241     dataBufferReplace(&pWriter->term, pTerm, nTerm);
4242   }
4243   ASSERT_VALID_INTERIOR_BLOCK(pWriter->last);
4244 }
4245 
4246 /* Free the space used by pWriter, including the linked-list of
4247 ** InteriorBlocks, and parentWriter, if present.
4248 */
interiorWriterDestroy(InteriorWriter * pWriter)4249 static int interiorWriterDestroy(InteriorWriter *pWriter){
4250   InteriorBlock *block = pWriter->first;
4251 
4252   while( block!=NULL ){
4253     InteriorBlock *b = block;
4254     block = block->next;
4255     dataBufferDestroy(&b->term);
4256     dataBufferDestroy(&b->data);
4257     sqlite3_free(b);
4258   }
4259   if( pWriter->parentWriter!=NULL ){
4260     interiorWriterDestroy(pWriter->parentWriter);
4261     sqlite3_free(pWriter->parentWriter);
4262   }
4263   dataBufferDestroy(&pWriter->term);
4264   SCRAMBLE(pWriter);
4265   return SQLITE_OK;
4266 }
4267 
4268 /* If pWriter can fit entirely in ROOT_MAX, return it as the root info
4269 ** directly, leaving *piEndBlockid unchanged.  Otherwise, flush
4270 ** pWriter to %_segments, building a new layer of interior nodes, and
4271 ** recursively ask for their root into.
4272 */
interiorWriterRootInfo(fulltext_vtab * v,InteriorWriter * pWriter,char ** ppRootInfo,int * pnRootInfo,sqlite_int64 * piEndBlockid)4273 static int interiorWriterRootInfo(fulltext_vtab *v, InteriorWriter *pWriter,
4274                                   char **ppRootInfo, int *pnRootInfo,
4275                                   sqlite_int64 *piEndBlockid){
4276   InteriorBlock *block = pWriter->first;
4277   sqlite_int64 iBlockid = 0;
4278   int rc;
4279 
4280   /* If we can fit the segment inline */
4281   if( block==pWriter->last && block->data.nData<ROOT_MAX ){
4282     *ppRootInfo = block->data.pData;
4283     *pnRootInfo = block->data.nData;
4284     return SQLITE_OK;
4285   }
4286 
4287   /* Flush the first block to %_segments, and create a new level of
4288   ** interior node.
4289   */
4290   ASSERT_VALID_INTERIOR_BLOCK(block);
4291   rc = block_insert(v, block->data.pData, block->data.nData, &iBlockid);
4292   if( rc!=SQLITE_OK ) return rc;
4293   *piEndBlockid = iBlockid;
4294 
4295   pWriter->parentWriter = sqlite3_malloc(sizeof(*pWriter->parentWriter));
4296   interiorWriterInit(pWriter->iHeight+1,
4297                      block->term.pData, block->term.nData,
4298                      iBlockid, pWriter->parentWriter);
4299 
4300   /* Flush additional blocks and append to the higher interior
4301   ** node.
4302   */
4303   for(block=block->next; block!=NULL; block=block->next){
4304     ASSERT_VALID_INTERIOR_BLOCK(block);
4305     rc = block_insert(v, block->data.pData, block->data.nData, &iBlockid);
4306     if( rc!=SQLITE_OK ) return rc;
4307     *piEndBlockid = iBlockid;
4308 
4309     interiorWriterAppend(pWriter->parentWriter,
4310                          block->term.pData, block->term.nData, iBlockid);
4311   }
4312 
4313   /* Parent node gets the chance to be the root. */
4314   return interiorWriterRootInfo(v, pWriter->parentWriter,
4315                                 ppRootInfo, pnRootInfo, piEndBlockid);
4316 }
4317 
4318 /****************************************************************/
4319 /* InteriorReader is used to read off the data from an interior node
4320 ** (see comment at top of file for the format).
4321 */
4322 typedef struct InteriorReader {
4323   const char *pData;
4324   int nData;
4325 
4326   DataBuffer term;          /* previous term, for decoding term delta. */
4327 
4328   sqlite_int64 iBlockid;
4329 } InteriorReader;
4330 
interiorReaderDestroy(InteriorReader * pReader)4331 static void interiorReaderDestroy(InteriorReader *pReader){
4332   dataBufferDestroy(&pReader->term);
4333   SCRAMBLE(pReader);
4334 }
4335 
4336 /* TODO(shess) The assertions are great, but what if we're in NDEBUG
4337 ** and the blob is empty or otherwise contains suspect data?
4338 */
interiorReaderInit(const char * pData,int nData,InteriorReader * pReader)4339 static void interiorReaderInit(const char *pData, int nData,
4340                                InteriorReader *pReader){
4341   int n, nTerm;
4342 
4343   /* Require at least the leading flag byte */
4344   assert( nData>0 );
4345   assert( pData[0]!='\0' );
4346 
4347   CLEAR(pReader);
4348 
4349   /* Decode the base blockid, and set the cursor to the first term. */
4350   n = getVarint(pData+1, &pReader->iBlockid);
4351   assert( 1+n<=nData );
4352   pReader->pData = pData+1+n;
4353   pReader->nData = nData-(1+n);
4354 
4355   /* A single-child interior node (such as when a leaf node was too
4356   ** large for the segment directory) won't have any terms.
4357   ** Otherwise, decode the first term.
4358   */
4359   if( pReader->nData==0 ){
4360     dataBufferInit(&pReader->term, 0);
4361   }else{
4362     n = getVarint32(pReader->pData, &nTerm);
4363     dataBufferInit(&pReader->term, nTerm);
4364     dataBufferReplace(&pReader->term, pReader->pData+n, nTerm);
4365     assert( n+nTerm<=pReader->nData );
4366     pReader->pData += n+nTerm;
4367     pReader->nData -= n+nTerm;
4368   }
4369 }
4370 
interiorReaderAtEnd(InteriorReader * pReader)4371 static int interiorReaderAtEnd(InteriorReader *pReader){
4372   return pReader->term.nData==0;
4373 }
4374 
interiorReaderCurrentBlockid(InteriorReader * pReader)4375 static sqlite_int64 interiorReaderCurrentBlockid(InteriorReader *pReader){
4376   return pReader->iBlockid;
4377 }
4378 
interiorReaderTermBytes(InteriorReader * pReader)4379 static int interiorReaderTermBytes(InteriorReader *pReader){
4380   assert( !interiorReaderAtEnd(pReader) );
4381   return pReader->term.nData;
4382 }
interiorReaderTerm(InteriorReader * pReader)4383 static const char *interiorReaderTerm(InteriorReader *pReader){
4384   assert( !interiorReaderAtEnd(pReader) );
4385   return pReader->term.pData;
4386 }
4387 
4388 /* Step forward to the next term in the node. */
interiorReaderStep(InteriorReader * pReader)4389 static void interiorReaderStep(InteriorReader *pReader){
4390   assert( !interiorReaderAtEnd(pReader) );
4391 
4392   /* If the last term has been read, signal eof, else construct the
4393   ** next term.
4394   */
4395   if( pReader->nData==0 ){
4396     dataBufferReset(&pReader->term);
4397   }else{
4398     int n, nPrefix, nSuffix;
4399 
4400     n = getVarint32(pReader->pData, &nPrefix);
4401     n += getVarint32(pReader->pData+n, &nSuffix);
4402 
4403     /* Truncate the current term and append suffix data. */
4404     pReader->term.nData = nPrefix;
4405     dataBufferAppend(&pReader->term, pReader->pData+n, nSuffix);
4406 
4407     assert( n+nSuffix<=pReader->nData );
4408     pReader->pData += n+nSuffix;
4409     pReader->nData -= n+nSuffix;
4410   }
4411   pReader->iBlockid++;
4412 }
4413 
4414 /* Compare the current term to pTerm[nTerm], returning strcmp-style
4415 ** results.  If isPrefix, equality means equal through nTerm bytes.
4416 */
interiorReaderTermCmp(InteriorReader * pReader,const char * pTerm,int nTerm,int isPrefix)4417 static int interiorReaderTermCmp(InteriorReader *pReader,
4418                                  const char *pTerm, int nTerm, int isPrefix){
4419   const char *pReaderTerm = interiorReaderTerm(pReader);
4420   int nReaderTerm = interiorReaderTermBytes(pReader);
4421   int c, n = nReaderTerm<nTerm ? nReaderTerm : nTerm;
4422 
4423   if( n==0 ){
4424     if( nReaderTerm>0 ) return -1;
4425     if( nTerm>0 ) return 1;
4426     return 0;
4427   }
4428 
4429   c = memcmp(pReaderTerm, pTerm, n);
4430   if( c!=0 ) return c;
4431   if( isPrefix && n==nTerm ) return 0;
4432   return nReaderTerm - nTerm;
4433 }
4434 
4435 /****************************************************************/
4436 /* LeafWriter is used to collect terms and associated doclist data
4437 ** into leaf blocks in %_segments (see top of file for format info).
4438 ** Expected usage is:
4439 **
4440 ** LeafWriter writer;
4441 ** leafWriterInit(0, 0, &writer);
4442 ** while( sorted_terms_left_to_process ){
4443 **   // data is doclist data for that term.
4444 **   rc = leafWriterStep(v, &writer, pTerm, nTerm, pData, nData);
4445 **   if( rc!=SQLITE_OK ) goto err;
4446 ** }
4447 ** rc = leafWriterFinalize(v, &writer);
4448 **err:
4449 ** leafWriterDestroy(&writer);
4450 ** return rc;
4451 **
4452 ** leafWriterStep() may write a collected leaf out to %_segments.
4453 ** leafWriterFinalize() finishes writing any buffered data and stores
4454 ** a root node in %_segdir.  leafWriterDestroy() frees all buffers and
4455 ** InteriorWriters allocated as part of writing this segment.
4456 **
4457 ** TODO(shess) Document leafWriterStepMerge().
4458 */
4459 
4460 /* Put terms with data this big in their own block. */
4461 #define STANDALONE_MIN 1024
4462 
4463 /* Keep leaf blocks below this size. */
4464 #define LEAF_MAX 2048
4465 
4466 typedef struct LeafWriter {
4467   int iLevel;
4468   int idx;
4469   sqlite_int64 iStartBlockid;     /* needed to create the root info */
4470   sqlite_int64 iEndBlockid;       /* when we're done writing. */
4471 
4472   DataBuffer term;                /* previous encoded term */
4473   DataBuffer data;                /* encoding buffer */
4474 
4475   /* bytes of first term in the current node which distinguishes that
4476   ** term from the last term of the previous node.
4477   */
4478   int nTermDistinct;
4479 
4480   InteriorWriter parentWriter;    /* if we overflow */
4481   int has_parent;
4482 } LeafWriter;
4483 
leafWriterInit(int iLevel,int idx,LeafWriter * pWriter)4484 static void leafWriterInit(int iLevel, int idx, LeafWriter *pWriter){
4485   CLEAR(pWriter);
4486   pWriter->iLevel = iLevel;
4487   pWriter->idx = idx;
4488 
4489   dataBufferInit(&pWriter->term, 32);
4490 
4491   /* Start out with a reasonably sized block, though it can grow. */
4492   dataBufferInit(&pWriter->data, LEAF_MAX);
4493 }
4494 
4495 #ifndef NDEBUG
4496 /* Verify that the data is readable as a leaf node. */
leafNodeValidate(const char * pData,int nData)4497 static void leafNodeValidate(const char *pData, int nData){
4498   int n, iDummy;
4499 
4500   if( nData==0 ) return;
4501   assert( nData>0 );
4502   assert( pData!=0 );
4503   assert( pData+nData>pData );
4504 
4505   /* Must lead with a varint(0) */
4506   n = getVarint32(pData, &iDummy);
4507   assert( iDummy==0 );
4508   assert( n>0 );
4509   assert( n<nData );
4510   pData += n;
4511   nData -= n;
4512 
4513   /* Leading term length and data must fit in buffer. */
4514   n = getVarint32(pData, &iDummy);
4515   assert( n>0 );
4516   assert( iDummy>0 );
4517   assert( n+iDummy>0 );
4518   assert( n+iDummy<nData );
4519   pData += n+iDummy;
4520   nData -= n+iDummy;
4521 
4522   /* Leading term's doclist length and data must fit. */
4523   n = getVarint32(pData, &iDummy);
4524   assert( n>0 );
4525   assert( iDummy>0 );
4526   assert( n+iDummy>0 );
4527   assert( n+iDummy<=nData );
4528   ASSERT_VALID_DOCLIST(DL_DEFAULT, pData+n, iDummy, NULL);
4529   pData += n+iDummy;
4530   nData -= n+iDummy;
4531 
4532   /* Verify that trailing terms and doclists also are readable. */
4533   while( nData!=0 ){
4534     n = getVarint32(pData, &iDummy);
4535     assert( n>0 );
4536     assert( iDummy>=0 );
4537     assert( n<nData );
4538     pData += n;
4539     nData -= n;
4540     n = getVarint32(pData, &iDummy);
4541     assert( n>0 );
4542     assert( iDummy>0 );
4543     assert( n+iDummy>0 );
4544     assert( n+iDummy<nData );
4545     pData += n+iDummy;
4546     nData -= n+iDummy;
4547 
4548     n = getVarint32(pData, &iDummy);
4549     assert( n>0 );
4550     assert( iDummy>0 );
4551     assert( n+iDummy>0 );
4552     assert( n+iDummy<=nData );
4553     ASSERT_VALID_DOCLIST(DL_DEFAULT, pData+n, iDummy, NULL);
4554     pData += n+iDummy;
4555     nData -= n+iDummy;
4556   }
4557 }
4558 #define ASSERT_VALID_LEAF_NODE(p, n) leafNodeValidate(p, n)
4559 #else
4560 #define ASSERT_VALID_LEAF_NODE(p, n) assert( 1 )
4561 #endif
4562 
4563 /* Flush the current leaf node to %_segments, and adding the resulting
4564 ** blockid and the starting term to the interior node which will
4565 ** contain it.
4566 */
leafWriterInternalFlush(fulltext_vtab * v,LeafWriter * pWriter,int iData,int nData)4567 static int leafWriterInternalFlush(fulltext_vtab *v, LeafWriter *pWriter,
4568                                    int iData, int nData){
4569   sqlite_int64 iBlockid = 0;
4570   const char *pStartingTerm;
4571   int nStartingTerm, rc, n;
4572 
4573   /* Must have the leading varint(0) flag, plus at least some
4574   ** valid-looking data.
4575   */
4576   assert( nData>2 );
4577   assert( iData>=0 );
4578   assert( iData+nData<=pWriter->data.nData );
4579   ASSERT_VALID_LEAF_NODE(pWriter->data.pData+iData, nData);
4580 
4581   rc = block_insert(v, pWriter->data.pData+iData, nData, &iBlockid);
4582   if( rc!=SQLITE_OK ) return rc;
4583   assert( iBlockid!=0 );
4584 
4585   /* Reconstruct the first term in the leaf for purposes of building
4586   ** the interior node.
4587   */
4588   n = getVarint32(pWriter->data.pData+iData+1, &nStartingTerm);
4589   pStartingTerm = pWriter->data.pData+iData+1+n;
4590   assert( pWriter->data.nData>iData+1+n+nStartingTerm );
4591   assert( pWriter->nTermDistinct>0 );
4592   assert( pWriter->nTermDistinct<=nStartingTerm );
4593   nStartingTerm = pWriter->nTermDistinct;
4594 
4595   if( pWriter->has_parent ){
4596     interiorWriterAppend(&pWriter->parentWriter,
4597                          pStartingTerm, nStartingTerm, iBlockid);
4598   }else{
4599     interiorWriterInit(1, pStartingTerm, nStartingTerm, iBlockid,
4600                        &pWriter->parentWriter);
4601     pWriter->has_parent = 1;
4602   }
4603 
4604   /* Track the span of this segment's leaf nodes. */
4605   if( pWriter->iEndBlockid==0 ){
4606     pWriter->iEndBlockid = pWriter->iStartBlockid = iBlockid;
4607   }else{
4608     pWriter->iEndBlockid++;
4609     assert( iBlockid==pWriter->iEndBlockid );
4610   }
4611 
4612   return SQLITE_OK;
4613 }
leafWriterFlush(fulltext_vtab * v,LeafWriter * pWriter)4614 static int leafWriterFlush(fulltext_vtab *v, LeafWriter *pWriter){
4615   int rc = leafWriterInternalFlush(v, pWriter, 0, pWriter->data.nData);
4616   if( rc!=SQLITE_OK ) return rc;
4617 
4618   /* Re-initialize the output buffer. */
4619   dataBufferReset(&pWriter->data);
4620 
4621   return SQLITE_OK;
4622 }
4623 
4624 /* Fetch the root info for the segment.  If the entire leaf fits
4625 ** within ROOT_MAX, then it will be returned directly, otherwise it
4626 ** will be flushed and the root info will be returned from the
4627 ** interior node.  *piEndBlockid is set to the blockid of the last
4628 ** interior or leaf node written to disk (0 if none are written at
4629 ** all).
4630 */
leafWriterRootInfo(fulltext_vtab * v,LeafWriter * pWriter,char ** ppRootInfo,int * pnRootInfo,sqlite_int64 * piEndBlockid)4631 static int leafWriterRootInfo(fulltext_vtab *v, LeafWriter *pWriter,
4632                               char **ppRootInfo, int *pnRootInfo,
4633                               sqlite_int64 *piEndBlockid){
4634   /* we can fit the segment entirely inline */
4635   if( !pWriter->has_parent && pWriter->data.nData<ROOT_MAX ){
4636     *ppRootInfo = pWriter->data.pData;
4637     *pnRootInfo = pWriter->data.nData;
4638     *piEndBlockid = 0;
4639     return SQLITE_OK;
4640   }
4641 
4642   /* Flush remaining leaf data. */
4643   if( pWriter->data.nData>0 ){
4644     int rc = leafWriterFlush(v, pWriter);
4645     if( rc!=SQLITE_OK ) return rc;
4646   }
4647 
4648   /* We must have flushed a leaf at some point. */
4649   assert( pWriter->has_parent );
4650 
4651   /* Tenatively set the end leaf blockid as the end blockid.  If the
4652   ** interior node can be returned inline, this will be the final
4653   ** blockid, otherwise it will be overwritten by
4654   ** interiorWriterRootInfo().
4655   */
4656   *piEndBlockid = pWriter->iEndBlockid;
4657 
4658   return interiorWriterRootInfo(v, &pWriter->parentWriter,
4659                                 ppRootInfo, pnRootInfo, piEndBlockid);
4660 }
4661 
4662 /* Collect the rootInfo data and store it into the segment directory.
4663 ** This has the effect of flushing the segment's leaf data to
4664 ** %_segments, and also flushing any interior nodes to %_segments.
4665 */
leafWriterFinalize(fulltext_vtab * v,LeafWriter * pWriter)4666 static int leafWriterFinalize(fulltext_vtab *v, LeafWriter *pWriter){
4667   sqlite_int64 iEndBlockid;
4668   char *pRootInfo;
4669   int rc, nRootInfo;
4670 
4671   rc = leafWriterRootInfo(v, pWriter, &pRootInfo, &nRootInfo, &iEndBlockid);
4672   if( rc!=SQLITE_OK ) return rc;
4673 
4674   /* Don't bother storing an entirely empty segment. */
4675   if( iEndBlockid==0 && nRootInfo==0 ) return SQLITE_OK;
4676 
4677   return segdir_set(v, pWriter->iLevel, pWriter->idx,
4678                     pWriter->iStartBlockid, pWriter->iEndBlockid,
4679                     iEndBlockid, pRootInfo, nRootInfo);
4680 }
4681 
leafWriterDestroy(LeafWriter * pWriter)4682 static void leafWriterDestroy(LeafWriter *pWriter){
4683   if( pWriter->has_parent ) interiorWriterDestroy(&pWriter->parentWriter);
4684   dataBufferDestroy(&pWriter->term);
4685   dataBufferDestroy(&pWriter->data);
4686 }
4687 
4688 /* Encode a term into the leafWriter, delta-encoding as appropriate.
4689 ** Returns the length of the new term which distinguishes it from the
4690 ** previous term, which can be used to set nTermDistinct when a node
4691 ** boundary is crossed.
4692 */
leafWriterEncodeTerm(LeafWriter * pWriter,const char * pTerm,int nTerm)4693 static int leafWriterEncodeTerm(LeafWriter *pWriter,
4694                                 const char *pTerm, int nTerm){
4695   char c[VARINT_MAX+VARINT_MAX];
4696   int n, nPrefix = 0;
4697 
4698   assert( nTerm>0 );
4699   while( nPrefix<pWriter->term.nData &&
4700          pTerm[nPrefix]==pWriter->term.pData[nPrefix] ){
4701     nPrefix++;
4702     /* Failing this implies that the terms weren't in order. */
4703     assert( nPrefix<nTerm );
4704   }
4705 
4706   if( pWriter->data.nData==0 ){
4707     /* Encode the node header and leading term as:
4708     **  varint(0)
4709     **  varint(nTerm)
4710     **  char pTerm[nTerm]
4711     */
4712     n = putVarint(c, '\0');
4713     n += putVarint(c+n, nTerm);
4714     dataBufferAppend2(&pWriter->data, c, n, pTerm, nTerm);
4715   }else{
4716     /* Delta-encode the term as:
4717     **  varint(nPrefix)
4718     **  varint(nSuffix)
4719     **  char pTermSuffix[nSuffix]
4720     */
4721     n = putVarint(c, nPrefix);
4722     n += putVarint(c+n, nTerm-nPrefix);
4723     dataBufferAppend2(&pWriter->data, c, n, pTerm+nPrefix, nTerm-nPrefix);
4724   }
4725   dataBufferReplace(&pWriter->term, pTerm, nTerm);
4726 
4727   return nPrefix+1;
4728 }
4729 
4730 /* Used to avoid a memmove when a large amount of doclist data is in
4731 ** the buffer.  This constructs a node and term header before
4732 ** iDoclistData and flushes the resulting complete node using
4733 ** leafWriterInternalFlush().
4734 */
leafWriterInlineFlush(fulltext_vtab * v,LeafWriter * pWriter,const char * pTerm,int nTerm,int iDoclistData)4735 static int leafWriterInlineFlush(fulltext_vtab *v, LeafWriter *pWriter,
4736                                  const char *pTerm, int nTerm,
4737                                  int iDoclistData){
4738   char c[VARINT_MAX+VARINT_MAX];
4739   int iData, n = putVarint(c, 0);
4740   n += putVarint(c+n, nTerm);
4741 
4742   /* There should always be room for the header.  Even if pTerm shared
4743   ** a substantial prefix with the previous term, the entire prefix
4744   ** could be constructed from earlier data in the doclist, so there
4745   ** should be room.
4746   */
4747   assert( iDoclistData>=n+nTerm );
4748 
4749   iData = iDoclistData-(n+nTerm);
4750   memcpy(pWriter->data.pData+iData, c, n);
4751   memcpy(pWriter->data.pData+iData+n, pTerm, nTerm);
4752 
4753   return leafWriterInternalFlush(v, pWriter, iData, pWriter->data.nData-iData);
4754 }
4755 
4756 /* Push pTerm[nTerm] along with the doclist data to the leaf layer of
4757 ** %_segments.
4758 */
leafWriterStepMerge(fulltext_vtab * v,LeafWriter * pWriter,const char * pTerm,int nTerm,DLReader * pReaders,int nReaders)4759 static int leafWriterStepMerge(fulltext_vtab *v, LeafWriter *pWriter,
4760                                const char *pTerm, int nTerm,
4761                                DLReader *pReaders, int nReaders){
4762   char c[VARINT_MAX+VARINT_MAX];
4763   int iTermData = pWriter->data.nData, iDoclistData;
4764   int i, nData, n, nActualData, nActual, rc, nTermDistinct;
4765 
4766   ASSERT_VALID_LEAF_NODE(pWriter->data.pData, pWriter->data.nData);
4767   nTermDistinct = leafWriterEncodeTerm(pWriter, pTerm, nTerm);
4768 
4769   /* Remember nTermDistinct if opening a new node. */
4770   if( iTermData==0 ) pWriter->nTermDistinct = nTermDistinct;
4771 
4772   iDoclistData = pWriter->data.nData;
4773 
4774   /* Estimate the length of the merged doclist so we can leave space
4775   ** to encode it.
4776   */
4777   for(i=0, nData=0; i<nReaders; i++){
4778     nData += dlrAllDataBytes(&pReaders[i]);
4779   }
4780   n = putVarint(c, nData);
4781   dataBufferAppend(&pWriter->data, c, n);
4782 
4783   docListMerge(&pWriter->data, pReaders, nReaders);
4784   ASSERT_VALID_DOCLIST(DL_DEFAULT,
4785                        pWriter->data.pData+iDoclistData+n,
4786                        pWriter->data.nData-iDoclistData-n, NULL);
4787 
4788   /* The actual amount of doclist data at this point could be smaller
4789   ** than the length we encoded.  Additionally, the space required to
4790   ** encode this length could be smaller.  For small doclists, this is
4791   ** not a big deal, we can just use memmove() to adjust things.
4792   */
4793   nActualData = pWriter->data.nData-(iDoclistData+n);
4794   nActual = putVarint(c, nActualData);
4795   assert( nActualData<=nData );
4796   assert( nActual<=n );
4797 
4798   /* If the new doclist is big enough for force a standalone leaf
4799   ** node, we can immediately flush it inline without doing the
4800   ** memmove().
4801   */
4802   /* TODO(shess) This test matches leafWriterStep(), which does this
4803   ** test before it knows the cost to varint-encode the term and
4804   ** doclist lengths.  At some point, change to
4805   ** pWriter->data.nData-iTermData>STANDALONE_MIN.
4806   */
4807   if( nTerm+nActualData>STANDALONE_MIN ){
4808     /* Push leaf node from before this term. */
4809     if( iTermData>0 ){
4810       rc = leafWriterInternalFlush(v, pWriter, 0, iTermData);
4811       if( rc!=SQLITE_OK ) return rc;
4812 
4813       pWriter->nTermDistinct = nTermDistinct;
4814     }
4815 
4816     /* Fix the encoded doclist length. */
4817     iDoclistData += n - nActual;
4818     memcpy(pWriter->data.pData+iDoclistData, c, nActual);
4819 
4820     /* Push the standalone leaf node. */
4821     rc = leafWriterInlineFlush(v, pWriter, pTerm, nTerm, iDoclistData);
4822     if( rc!=SQLITE_OK ) return rc;
4823 
4824     /* Leave the node empty. */
4825     dataBufferReset(&pWriter->data);
4826 
4827     return rc;
4828   }
4829 
4830   /* At this point, we know that the doclist was small, so do the
4831   ** memmove if indicated.
4832   */
4833   if( nActual<n ){
4834     memmove(pWriter->data.pData+iDoclistData+nActual,
4835             pWriter->data.pData+iDoclistData+n,
4836             pWriter->data.nData-(iDoclistData+n));
4837     pWriter->data.nData -= n-nActual;
4838   }
4839 
4840   /* Replace written length with actual length. */
4841   memcpy(pWriter->data.pData+iDoclistData, c, nActual);
4842 
4843   /* If the node is too large, break things up. */
4844   /* TODO(shess) This test matches leafWriterStep(), which does this
4845   ** test before it knows the cost to varint-encode the term and
4846   ** doclist lengths.  At some point, change to
4847   ** pWriter->data.nData>LEAF_MAX.
4848   */
4849   if( iTermData+nTerm+nActualData>LEAF_MAX ){
4850     /* Flush out the leading data as a node */
4851     rc = leafWriterInternalFlush(v, pWriter, 0, iTermData);
4852     if( rc!=SQLITE_OK ) return rc;
4853 
4854     pWriter->nTermDistinct = nTermDistinct;
4855 
4856     /* Rebuild header using the current term */
4857     n = putVarint(pWriter->data.pData, 0);
4858     n += putVarint(pWriter->data.pData+n, nTerm);
4859     memcpy(pWriter->data.pData+n, pTerm, nTerm);
4860     n += nTerm;
4861 
4862     /* There should always be room, because the previous encoding
4863     ** included all data necessary to construct the term.
4864     */
4865     assert( n<iDoclistData );
4866     /* So long as STANDALONE_MIN is half or less of LEAF_MAX, the
4867     ** following memcpy() is safe (as opposed to needing a memmove).
4868     */
4869     assert( 2*STANDALONE_MIN<=LEAF_MAX );
4870     assert( n+pWriter->data.nData-iDoclistData<iDoclistData );
4871     memcpy(pWriter->data.pData+n,
4872            pWriter->data.pData+iDoclistData,
4873            pWriter->data.nData-iDoclistData);
4874     pWriter->data.nData -= iDoclistData-n;
4875   }
4876   ASSERT_VALID_LEAF_NODE(pWriter->data.pData, pWriter->data.nData);
4877 
4878   return SQLITE_OK;
4879 }
4880 
4881 /* Push pTerm[nTerm] along with the doclist data to the leaf layer of
4882 ** %_segments.
4883 */
4884 /* TODO(shess) Revise writeZeroSegment() so that doclists are
4885 ** constructed directly in pWriter->data.
4886 */
leafWriterStep(fulltext_vtab * v,LeafWriter * pWriter,const char * pTerm,int nTerm,const char * pData,int nData)4887 static int leafWriterStep(fulltext_vtab *v, LeafWriter *pWriter,
4888                           const char *pTerm, int nTerm,
4889                           const char *pData, int nData){
4890   int rc;
4891   DLReader reader;
4892 
4893   dlrInit(&reader, DL_DEFAULT, pData, nData);
4894   rc = leafWriterStepMerge(v, pWriter, pTerm, nTerm, &reader, 1);
4895   dlrDestroy(&reader);
4896 
4897   return rc;
4898 }
4899 
4900 
4901 /****************************************************************/
4902 /* LeafReader is used to iterate over an individual leaf node. */
4903 typedef struct LeafReader {
4904   DataBuffer term;          /* copy of current term. */
4905 
4906   const char *pData;        /* data for current term. */
4907   int nData;
4908 } LeafReader;
4909 
leafReaderDestroy(LeafReader * pReader)4910 static void leafReaderDestroy(LeafReader *pReader){
4911   dataBufferDestroy(&pReader->term);
4912   SCRAMBLE(pReader);
4913 }
4914 
leafReaderAtEnd(LeafReader * pReader)4915 static int leafReaderAtEnd(LeafReader *pReader){
4916   return pReader->nData<=0;
4917 }
4918 
4919 /* Access the current term. */
leafReaderTermBytes(LeafReader * pReader)4920 static int leafReaderTermBytes(LeafReader *pReader){
4921   return pReader->term.nData;
4922 }
leafReaderTerm(LeafReader * pReader)4923 static const char *leafReaderTerm(LeafReader *pReader){
4924   assert( pReader->term.nData>0 );
4925   return pReader->term.pData;
4926 }
4927 
4928 /* Access the doclist data for the current term. */
leafReaderDataBytes(LeafReader * pReader)4929 static int leafReaderDataBytes(LeafReader *pReader){
4930   int nData;
4931   assert( pReader->term.nData>0 );
4932   getVarint32(pReader->pData, &nData);
4933   return nData;
4934 }
leafReaderData(LeafReader * pReader)4935 static const char *leafReaderData(LeafReader *pReader){
4936   int n, nData;
4937   assert( pReader->term.nData>0 );
4938   n = getVarint32(pReader->pData, &nData);
4939   return pReader->pData+n;
4940 }
4941 
leafReaderInit(const char * pData,int nData,LeafReader * pReader)4942 static void leafReaderInit(const char *pData, int nData,
4943                            LeafReader *pReader){
4944   int nTerm, n;
4945 
4946   assert( nData>0 );
4947   assert( pData[0]=='\0' );
4948 
4949   CLEAR(pReader);
4950 
4951   /* Read the first term, skipping the header byte. */
4952   n = getVarint32(pData+1, &nTerm);
4953   dataBufferInit(&pReader->term, nTerm);
4954   dataBufferReplace(&pReader->term, pData+1+n, nTerm);
4955 
4956   /* Position after the first term. */
4957   assert( 1+n+nTerm<nData );
4958   pReader->pData = pData+1+n+nTerm;
4959   pReader->nData = nData-1-n-nTerm;
4960 }
4961 
4962 /* Step the reader forward to the next term. */
leafReaderStep(LeafReader * pReader)4963 static void leafReaderStep(LeafReader *pReader){
4964   int n, nData, nPrefix, nSuffix;
4965   assert( !leafReaderAtEnd(pReader) );
4966 
4967   /* Skip previous entry's data block. */
4968   n = getVarint32(pReader->pData, &nData);
4969   assert( n+nData<=pReader->nData );
4970   pReader->pData += n+nData;
4971   pReader->nData -= n+nData;
4972 
4973   if( !leafReaderAtEnd(pReader) ){
4974     /* Construct the new term using a prefix from the old term plus a
4975     ** suffix from the leaf data.
4976     */
4977     n = getVarint32(pReader->pData, &nPrefix);
4978     n += getVarint32(pReader->pData+n, &nSuffix);
4979     assert( n+nSuffix<pReader->nData );
4980     pReader->term.nData = nPrefix;
4981     dataBufferAppend(&pReader->term, pReader->pData+n, nSuffix);
4982 
4983     pReader->pData += n+nSuffix;
4984     pReader->nData -= n+nSuffix;
4985   }
4986 }
4987 
4988 /* strcmp-style comparison of pReader's current term against pTerm.
4989 ** If isPrefix, equality means equal through nTerm bytes.
4990 */
leafReaderTermCmp(LeafReader * pReader,const char * pTerm,int nTerm,int isPrefix)4991 static int leafReaderTermCmp(LeafReader *pReader,
4992                              const char *pTerm, int nTerm, int isPrefix){
4993   int c, n = pReader->term.nData<nTerm ? pReader->term.nData : nTerm;
4994   if( n==0 ){
4995     if( pReader->term.nData>0 ) return -1;
4996     if(nTerm>0 ) return 1;
4997     return 0;
4998   }
4999 
5000   c = memcmp(pReader->term.pData, pTerm, n);
5001   if( c!=0 ) return c;
5002   if( isPrefix && n==nTerm ) return 0;
5003   return pReader->term.nData - nTerm;
5004 }
5005 
5006 
5007 /****************************************************************/
5008 /* LeavesReader wraps LeafReader to allow iterating over the entire
5009 ** leaf layer of the tree.
5010 */
5011 typedef struct LeavesReader {
5012   int idx;                  /* Index within the segment. */
5013 
5014   sqlite3_stmt *pStmt;      /* Statement we're streaming leaves from. */
5015   int eof;                  /* we've seen SQLITE_DONE from pStmt. */
5016 
5017   LeafReader leafReader;    /* reader for the current leaf. */
5018   DataBuffer rootData;      /* root data for inline. */
5019 } LeavesReader;
5020 
5021 /* Access the current term. */
leavesReaderTermBytes(LeavesReader * pReader)5022 static int leavesReaderTermBytes(LeavesReader *pReader){
5023   assert( !pReader->eof );
5024   return leafReaderTermBytes(&pReader->leafReader);
5025 }
leavesReaderTerm(LeavesReader * pReader)5026 static const char *leavesReaderTerm(LeavesReader *pReader){
5027   assert( !pReader->eof );
5028   return leafReaderTerm(&pReader->leafReader);
5029 }
5030 
5031 /* Access the doclist data for the current term. */
leavesReaderDataBytes(LeavesReader * pReader)5032 static int leavesReaderDataBytes(LeavesReader *pReader){
5033   assert( !pReader->eof );
5034   return leafReaderDataBytes(&pReader->leafReader);
5035 }
leavesReaderData(LeavesReader * pReader)5036 static const char *leavesReaderData(LeavesReader *pReader){
5037   assert( !pReader->eof );
5038   return leafReaderData(&pReader->leafReader);
5039 }
5040 
leavesReaderAtEnd(LeavesReader * pReader)5041 static int leavesReaderAtEnd(LeavesReader *pReader){
5042   return pReader->eof;
5043 }
5044 
5045 /* loadSegmentLeaves() may not read all the way to SQLITE_DONE, thus
5046 ** leaving the statement handle open, which locks the table.
5047 */
5048 /* TODO(shess) This "solution" is not satisfactory.  Really, there
5049 ** should be check-in function for all statement handles which
5050 ** arranges to call sqlite3_reset().  This most likely will require
5051 ** modification to control flow all over the place, though, so for now
5052 ** just punt.
5053 **
5054 ** Note the the current system assumes that segment merges will run to
5055 ** completion, which is why this particular probably hasn't arisen in
5056 ** this case.  Probably a brittle assumption.
5057 */
leavesReaderReset(LeavesReader * pReader)5058 static int leavesReaderReset(LeavesReader *pReader){
5059   return sqlite3_reset(pReader->pStmt);
5060 }
5061 
leavesReaderDestroy(LeavesReader * pReader)5062 static void leavesReaderDestroy(LeavesReader *pReader){
5063   /* If idx is -1, that means we're using a non-cached statement
5064   ** handle in the optimize() case, so we need to release it.
5065   */
5066   if( pReader->pStmt!=NULL && pReader->idx==-1 ){
5067     sqlite3_finalize(pReader->pStmt);
5068   }
5069   leafReaderDestroy(&pReader->leafReader);
5070   dataBufferDestroy(&pReader->rootData);
5071   SCRAMBLE(pReader);
5072 }
5073 
5074 /* Initialize pReader with the given root data (if iStartBlockid==0
5075 ** the leaf data was entirely contained in the root), or from the
5076 ** stream of blocks between iStartBlockid and iEndBlockid, inclusive.
5077 */
leavesReaderInit(fulltext_vtab * v,int idx,sqlite_int64 iStartBlockid,sqlite_int64 iEndBlockid,const char * pRootData,int nRootData,LeavesReader * pReader)5078 static int leavesReaderInit(fulltext_vtab *v,
5079                             int idx,
5080                             sqlite_int64 iStartBlockid,
5081                             sqlite_int64 iEndBlockid,
5082                             const char *pRootData, int nRootData,
5083                             LeavesReader *pReader){
5084   CLEAR(pReader);
5085   pReader->idx = idx;
5086 
5087   dataBufferInit(&pReader->rootData, 0);
5088   if( iStartBlockid==0 ){
5089     /* Entire leaf level fit in root data. */
5090     dataBufferReplace(&pReader->rootData, pRootData, nRootData);
5091     leafReaderInit(pReader->rootData.pData, pReader->rootData.nData,
5092                    &pReader->leafReader);
5093   }else{
5094     sqlite3_stmt *s;
5095     int rc = sql_get_leaf_statement(v, idx, &s);
5096     if( rc!=SQLITE_OK ) return rc;
5097 
5098     rc = sqlite3_bind_int64(s, 1, iStartBlockid);
5099     if( rc!=SQLITE_OK ) return rc;
5100 
5101     rc = sqlite3_bind_int64(s, 2, iEndBlockid);
5102     if( rc!=SQLITE_OK ) return rc;
5103 
5104     rc = sqlite3_step(s);
5105     if( rc==SQLITE_DONE ){
5106       pReader->eof = 1;
5107       return SQLITE_OK;
5108     }
5109     if( rc!=SQLITE_ROW ) return rc;
5110 
5111     pReader->pStmt = s;
5112     leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0),
5113                    sqlite3_column_bytes(pReader->pStmt, 0),
5114                    &pReader->leafReader);
5115   }
5116   return SQLITE_OK;
5117 }
5118 
5119 /* Step the current leaf forward to the next term.  If we reach the
5120 ** end of the current leaf, step forward to the next leaf block.
5121 */
leavesReaderStep(fulltext_vtab * v,LeavesReader * pReader)5122 static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){
5123   assert( !leavesReaderAtEnd(pReader) );
5124   leafReaderStep(&pReader->leafReader);
5125 
5126   if( leafReaderAtEnd(&pReader->leafReader) ){
5127     int rc;
5128     if( pReader->rootData.pData ){
5129       pReader->eof = 1;
5130       return SQLITE_OK;
5131     }
5132     rc = sqlite3_step(pReader->pStmt);
5133     if( rc!=SQLITE_ROW ){
5134       pReader->eof = 1;
5135       return rc==SQLITE_DONE ? SQLITE_OK : rc;
5136     }
5137     leafReaderDestroy(&pReader->leafReader);
5138     leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0),
5139                    sqlite3_column_bytes(pReader->pStmt, 0),
5140                    &pReader->leafReader);
5141   }
5142   return SQLITE_OK;
5143 }
5144 
5145 /* Order LeavesReaders by their term, ignoring idx.  Readers at eof
5146 ** always sort to the end.
5147 */
leavesReaderTermCmp(LeavesReader * lr1,LeavesReader * lr2)5148 static int leavesReaderTermCmp(LeavesReader *lr1, LeavesReader *lr2){
5149   if( leavesReaderAtEnd(lr1) ){
5150     if( leavesReaderAtEnd(lr2) ) return 0;
5151     return 1;
5152   }
5153   if( leavesReaderAtEnd(lr2) ) return -1;
5154 
5155   return leafReaderTermCmp(&lr1->leafReader,
5156                            leavesReaderTerm(lr2), leavesReaderTermBytes(lr2),
5157                            0);
5158 }
5159 
5160 /* Similar to leavesReaderTermCmp(), with additional ordering by idx
5161 ** so that older segments sort before newer segments.
5162 */
leavesReaderCmp(LeavesReader * lr1,LeavesReader * lr2)5163 static int leavesReaderCmp(LeavesReader *lr1, LeavesReader *lr2){
5164   int c = leavesReaderTermCmp(lr1, lr2);
5165   if( c!=0 ) return c;
5166   return lr1->idx-lr2->idx;
5167 }
5168 
5169 /* Assume that pLr[1]..pLr[nLr] are sorted.  Bubble pLr[0] into its
5170 ** sorted position.
5171 */
leavesReaderReorder(LeavesReader * pLr,int nLr)5172 static void leavesReaderReorder(LeavesReader *pLr, int nLr){
5173   while( nLr>1 && leavesReaderCmp(pLr, pLr+1)>0 ){
5174     LeavesReader tmp = pLr[0];
5175     pLr[0] = pLr[1];
5176     pLr[1] = tmp;
5177     nLr--;
5178     pLr++;
5179   }
5180 }
5181 
5182 /* Initializes pReaders with the segments from level iLevel, returning
5183 ** the number of segments in *piReaders.  Leaves pReaders in sorted
5184 ** order.
5185 */
leavesReadersInit(fulltext_vtab * v,int iLevel,LeavesReader * pReaders,int * piReaders)5186 static int leavesReadersInit(fulltext_vtab *v, int iLevel,
5187                              LeavesReader *pReaders, int *piReaders){
5188   sqlite3_stmt *s;
5189   int i, rc = sql_get_statement(v, SEGDIR_SELECT_LEVEL_STMT, &s);
5190   if( rc!=SQLITE_OK ) return rc;
5191 
5192   rc = sqlite3_bind_int(s, 1, iLevel);
5193   if( rc!=SQLITE_OK ) return rc;
5194 
5195   i = 0;
5196   while( (rc = sqlite3_step(s))==SQLITE_ROW ){
5197     sqlite_int64 iStart = sqlite3_column_int64(s, 0);
5198     sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
5199     const char *pRootData = sqlite3_column_blob(s, 2);
5200     int nRootData = sqlite3_column_bytes(s, 2);
5201 
5202     assert( i<MERGE_COUNT );
5203     rc = leavesReaderInit(v, i, iStart, iEnd, pRootData, nRootData,
5204                           &pReaders[i]);
5205     if( rc!=SQLITE_OK ) break;
5206 
5207     i++;
5208   }
5209   if( rc!=SQLITE_DONE ){
5210     while( i-->0 ){
5211       leavesReaderDestroy(&pReaders[i]);
5212     }
5213     return rc;
5214   }
5215 
5216   *piReaders = i;
5217 
5218   /* Leave our results sorted by term, then age. */
5219   while( i-- ){
5220     leavesReaderReorder(pReaders+i, *piReaders-i);
5221   }
5222   return SQLITE_OK;
5223 }
5224 
5225 /* Merge doclists from pReaders[nReaders] into a single doclist, which
5226 ** is written to pWriter.  Assumes pReaders is ordered oldest to
5227 ** newest.
5228 */
5229 /* TODO(shess) Consider putting this inline in segmentMerge(). */
leavesReadersMerge(fulltext_vtab * v,LeavesReader * pReaders,int nReaders,LeafWriter * pWriter)5230 static int leavesReadersMerge(fulltext_vtab *v,
5231                               LeavesReader *pReaders, int nReaders,
5232                               LeafWriter *pWriter){
5233   DLReader dlReaders[MERGE_COUNT];
5234   const char *pTerm = leavesReaderTerm(pReaders);
5235   int i, nTerm = leavesReaderTermBytes(pReaders);
5236 
5237   assert( nReaders<=MERGE_COUNT );
5238 
5239   for(i=0; i<nReaders; i++){
5240     dlrInit(&dlReaders[i], DL_DEFAULT,
5241             leavesReaderData(pReaders+i),
5242             leavesReaderDataBytes(pReaders+i));
5243   }
5244 
5245   return leafWriterStepMerge(v, pWriter, pTerm, nTerm, dlReaders, nReaders);
5246 }
5247 
5248 /* Forward ref due to mutual recursion with segdirNextIndex(). */
5249 static int segmentMerge(fulltext_vtab *v, int iLevel);
5250 
5251 /* Put the next available index at iLevel into *pidx.  If iLevel
5252 ** already has MERGE_COUNT segments, they are merged to a higher
5253 ** level to make room.
5254 */
segdirNextIndex(fulltext_vtab * v,int iLevel,int * pidx)5255 static int segdirNextIndex(fulltext_vtab *v, int iLevel, int *pidx){
5256   int rc = segdir_max_index(v, iLevel, pidx);
5257   if( rc==SQLITE_DONE ){              /* No segments at iLevel. */
5258     *pidx = 0;
5259   }else if( rc==SQLITE_ROW ){
5260     if( *pidx==(MERGE_COUNT-1) ){
5261       rc = segmentMerge(v, iLevel);
5262       if( rc!=SQLITE_OK ) return rc;
5263       *pidx = 0;
5264     }else{
5265       (*pidx)++;
5266     }
5267   }else{
5268     return rc;
5269   }
5270   return SQLITE_OK;
5271 }
5272 
5273 /* Merge MERGE_COUNT segments at iLevel into a new segment at
5274 ** iLevel+1.  If iLevel+1 is already full of segments, those will be
5275 ** merged to make room.
5276 */
segmentMerge(fulltext_vtab * v,int iLevel)5277 static int segmentMerge(fulltext_vtab *v, int iLevel){
5278   LeafWriter writer;
5279   LeavesReader lrs[MERGE_COUNT];
5280   int i, rc, idx = 0;
5281 
5282   /* Determine the next available segment index at the next level,
5283   ** merging as necessary.
5284   */
5285   rc = segdirNextIndex(v, iLevel+1, &idx);
5286   if( rc!=SQLITE_OK ) return rc;
5287 
5288   /* TODO(shess) This assumes that we'll always see exactly
5289   ** MERGE_COUNT segments to merge at a given level.  That will be
5290   ** broken if we allow the developer to request preemptive or
5291   ** deferred merging.
5292   */
5293   memset(&lrs, '\0', sizeof(lrs));
5294   rc = leavesReadersInit(v, iLevel, lrs, &i);
5295   if( rc!=SQLITE_OK ) return rc;
5296   assert( i==MERGE_COUNT );
5297 
5298   leafWriterInit(iLevel+1, idx, &writer);
5299 
5300   /* Since leavesReaderReorder() pushes readers at eof to the end,
5301   ** when the first reader is empty, all will be empty.
5302   */
5303   while( !leavesReaderAtEnd(lrs) ){
5304     /* Figure out how many readers share their next term. */
5305     for(i=1; i<MERGE_COUNT && !leavesReaderAtEnd(lrs+i); i++){
5306       if( 0!=leavesReaderTermCmp(lrs, lrs+i) ) break;
5307     }
5308 
5309     rc = leavesReadersMerge(v, lrs, i, &writer);
5310     if( rc!=SQLITE_OK ) goto err;
5311 
5312     /* Step forward those that were merged. */
5313     while( i-->0 ){
5314       rc = leavesReaderStep(v, lrs+i);
5315       if( rc!=SQLITE_OK ) goto err;
5316 
5317       /* Reorder by term, then by age. */
5318       leavesReaderReorder(lrs+i, MERGE_COUNT-i);
5319     }
5320   }
5321 
5322   for(i=0; i<MERGE_COUNT; i++){
5323     leavesReaderDestroy(&lrs[i]);
5324   }
5325 
5326   rc = leafWriterFinalize(v, &writer);
5327   leafWriterDestroy(&writer);
5328   if( rc!=SQLITE_OK ) return rc;
5329 
5330   /* Delete the merged segment data. */
5331   return segdir_delete(v, iLevel);
5332 
5333  err:
5334   for(i=0; i<MERGE_COUNT; i++){
5335     leavesReaderDestroy(&lrs[i]);
5336   }
5337   leafWriterDestroy(&writer);
5338   return rc;
5339 }
5340 
5341 /* Accumulate the union of *acc and *pData into *acc. */
docListAccumulateUnion(DataBuffer * acc,const char * pData,int nData)5342 static void docListAccumulateUnion(DataBuffer *acc,
5343                                    const char *pData, int nData) {
5344   DataBuffer tmp = *acc;
5345   dataBufferInit(acc, tmp.nData+nData);
5346   docListUnion(tmp.pData, tmp.nData, pData, nData, acc);
5347   dataBufferDestroy(&tmp);
5348 }
5349 
5350 /* TODO(shess) It might be interesting to explore different merge
5351 ** strategies, here.  For instance, since this is a sorted merge, we
5352 ** could easily merge many doclists in parallel.  With some
5353 ** comprehension of the storage format, we could merge all of the
5354 ** doclists within a leaf node directly from the leaf node's storage.
5355 ** It may be worthwhile to merge smaller doclists before larger
5356 ** doclists, since they can be traversed more quickly - but the
5357 ** results may have less overlap, making them more expensive in a
5358 ** different way.
5359 */
5360 
5361 /* Scan pReader for pTerm/nTerm, and merge the term's doclist over
5362 ** *out (any doclists with duplicate docids overwrite those in *out).
5363 ** Internal function for loadSegmentLeaf().
5364 */
loadSegmentLeavesInt(fulltext_vtab * v,LeavesReader * pReader,const char * pTerm,int nTerm,int isPrefix,DataBuffer * out)5365 static int loadSegmentLeavesInt(fulltext_vtab *v, LeavesReader *pReader,
5366                                 const char *pTerm, int nTerm, int isPrefix,
5367                                 DataBuffer *out){
5368   /* doclist data is accumulated into pBuffers similar to how one does
5369   ** increment in binary arithmetic.  If index 0 is empty, the data is
5370   ** stored there.  If there is data there, it is merged and the
5371   ** results carried into position 1, with further merge-and-carry
5372   ** until an empty position is found.
5373   */
5374   DataBuffer *pBuffers = NULL;
5375   int nBuffers = 0, nMaxBuffers = 0, rc;
5376 
5377   assert( nTerm>0 );
5378 
5379   for(rc=SQLITE_OK; rc==SQLITE_OK && !leavesReaderAtEnd(pReader);
5380       rc=leavesReaderStep(v, pReader)){
5381     /* TODO(shess) Really want leavesReaderTermCmp(), but that name is
5382     ** already taken to compare the terms of two LeavesReaders.  Think
5383     ** on a better name.  [Meanwhile, break encapsulation rather than
5384     ** use a confusing name.]
5385     */
5386     int c = leafReaderTermCmp(&pReader->leafReader, pTerm, nTerm, isPrefix);
5387     if( c>0 ) break;      /* Past any possible matches. */
5388     if( c==0 ){
5389       const char *pData = leavesReaderData(pReader);
5390       int iBuffer, nData = leavesReaderDataBytes(pReader);
5391 
5392       /* Find the first empty buffer. */
5393       for(iBuffer=0; iBuffer<nBuffers; ++iBuffer){
5394         if( 0==pBuffers[iBuffer].nData ) break;
5395       }
5396 
5397       /* Out of buffers, add an empty one. */
5398       if( iBuffer==nBuffers ){
5399         if( nBuffers==nMaxBuffers ){
5400           DataBuffer *p;
5401           nMaxBuffers += 20;
5402 
5403           /* Manual realloc so we can handle NULL appropriately. */
5404           p = sqlite3_malloc(nMaxBuffers*sizeof(*pBuffers));
5405           if( p==NULL ){
5406             rc = SQLITE_NOMEM;
5407             break;
5408           }
5409 
5410           if( nBuffers>0 ){
5411             assert(pBuffers!=NULL);
5412             memcpy(p, pBuffers, nBuffers*sizeof(*pBuffers));
5413             sqlite3_free(pBuffers);
5414           }
5415           pBuffers = p;
5416         }
5417         dataBufferInit(&(pBuffers[nBuffers]), 0);
5418         nBuffers++;
5419       }
5420 
5421       /* At this point, must have an empty at iBuffer. */
5422       assert(iBuffer<nBuffers && pBuffers[iBuffer].nData==0);
5423 
5424       /* If empty was first buffer, no need for merge logic. */
5425       if( iBuffer==0 ){
5426         dataBufferReplace(&(pBuffers[0]), pData, nData);
5427       }else{
5428         /* pAcc is the empty buffer the merged data will end up in. */
5429         DataBuffer *pAcc = &(pBuffers[iBuffer]);
5430         DataBuffer *p = &(pBuffers[0]);
5431 
5432         /* Handle position 0 specially to avoid need to prime pAcc
5433         ** with pData/nData.
5434         */
5435         dataBufferSwap(p, pAcc);
5436         docListAccumulateUnion(pAcc, pData, nData);
5437 
5438         /* Accumulate remaining doclists into pAcc. */
5439         for(++p; p<pAcc; ++p){
5440           docListAccumulateUnion(pAcc, p->pData, p->nData);
5441 
5442           /* dataBufferReset() could allow a large doclist to blow up
5443           ** our memory requirements.
5444           */
5445           if( p->nCapacity<1024 ){
5446             dataBufferReset(p);
5447           }else{
5448             dataBufferDestroy(p);
5449             dataBufferInit(p, 0);
5450           }
5451         }
5452       }
5453     }
5454   }
5455 
5456   /* Union all the doclists together into *out. */
5457   /* TODO(shess) What if *out is big?  Sigh. */
5458   if( rc==SQLITE_OK && nBuffers>0 ){
5459     int iBuffer;
5460     for(iBuffer=0; iBuffer<nBuffers; ++iBuffer){
5461       if( pBuffers[iBuffer].nData>0 ){
5462         if( out->nData==0 ){
5463           dataBufferSwap(out, &(pBuffers[iBuffer]));
5464         }else{
5465           docListAccumulateUnion(out, pBuffers[iBuffer].pData,
5466                                  pBuffers[iBuffer].nData);
5467         }
5468       }
5469     }
5470   }
5471 
5472   while( nBuffers-- ){
5473     dataBufferDestroy(&(pBuffers[nBuffers]));
5474   }
5475   if( pBuffers!=NULL ) sqlite3_free(pBuffers);
5476 
5477   return rc;
5478 }
5479 
5480 /* Call loadSegmentLeavesInt() with pData/nData as input. */
loadSegmentLeaf(fulltext_vtab * v,const char * pData,int nData,const char * pTerm,int nTerm,int isPrefix,DataBuffer * out)5481 static int loadSegmentLeaf(fulltext_vtab *v, const char *pData, int nData,
5482                            const char *pTerm, int nTerm, int isPrefix,
5483                            DataBuffer *out){
5484   LeavesReader reader;
5485   int rc;
5486 
5487   assert( nData>1 );
5488   assert( *pData=='\0' );
5489   rc = leavesReaderInit(v, 0, 0, 0, pData, nData, &reader);
5490   if( rc!=SQLITE_OK ) return rc;
5491 
5492   rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, isPrefix, out);
5493   leavesReaderReset(&reader);
5494   leavesReaderDestroy(&reader);
5495   return rc;
5496 }
5497 
5498 /* Call loadSegmentLeavesInt() with the leaf nodes from iStartLeaf to
5499 ** iEndLeaf (inclusive) as input, and merge the resulting doclist into
5500 ** out.
5501 */
loadSegmentLeaves(fulltext_vtab * v,sqlite_int64 iStartLeaf,sqlite_int64 iEndLeaf,const char * pTerm,int nTerm,int isPrefix,DataBuffer * out)5502 static int loadSegmentLeaves(fulltext_vtab *v,
5503                              sqlite_int64 iStartLeaf, sqlite_int64 iEndLeaf,
5504                              const char *pTerm, int nTerm, int isPrefix,
5505                              DataBuffer *out){
5506   int rc;
5507   LeavesReader reader;
5508 
5509   assert( iStartLeaf<=iEndLeaf );
5510   rc = leavesReaderInit(v, 0, iStartLeaf, iEndLeaf, NULL, 0, &reader);
5511   if( rc!=SQLITE_OK ) return rc;
5512 
5513   rc = loadSegmentLeavesInt(v, &reader, pTerm, nTerm, isPrefix, out);
5514   leavesReaderReset(&reader);
5515   leavesReaderDestroy(&reader);
5516   return rc;
5517 }
5518 
5519 /* Taking pData/nData as an interior node, find the sequence of child
5520 ** nodes which could include pTerm/nTerm/isPrefix.  Note that the
5521 ** interior node terms logically come between the blocks, so there is
5522 ** one more blockid than there are terms (that block contains terms >=
5523 ** the last interior-node term).
5524 */
5525 /* TODO(shess) The calling code may already know that the end child is
5526 ** not worth calculating, because the end may be in a later sibling
5527 ** node.  Consider whether breaking symmetry is worthwhile.  I suspect
5528 ** it is not worthwhile.
5529 */
getChildrenContaining(const char * pData,int nData,const char * pTerm,int nTerm,int isPrefix,sqlite_int64 * piStartChild,sqlite_int64 * piEndChild)5530 static void getChildrenContaining(const char *pData, int nData,
5531                                   const char *pTerm, int nTerm, int isPrefix,
5532                                   sqlite_int64 *piStartChild,
5533                                   sqlite_int64 *piEndChild){
5534   InteriorReader reader;
5535 
5536   assert( nData>1 );
5537   assert( *pData!='\0' );
5538   interiorReaderInit(pData, nData, &reader);
5539 
5540   /* Scan for the first child which could contain pTerm/nTerm. */
5541   while( !interiorReaderAtEnd(&reader) ){
5542     if( interiorReaderTermCmp(&reader, pTerm, nTerm, 0)>0 ) break;
5543     interiorReaderStep(&reader);
5544   }
5545   *piStartChild = interiorReaderCurrentBlockid(&reader);
5546 
5547   /* Keep scanning to find a term greater than our term, using prefix
5548   ** comparison if indicated.  If isPrefix is false, this will be the
5549   ** same blockid as the starting block.
5550   */
5551   while( !interiorReaderAtEnd(&reader) ){
5552     if( interiorReaderTermCmp(&reader, pTerm, nTerm, isPrefix)>0 ) break;
5553     interiorReaderStep(&reader);
5554   }
5555   *piEndChild = interiorReaderCurrentBlockid(&reader);
5556 
5557   interiorReaderDestroy(&reader);
5558 
5559   /* Children must ascend, and if !prefix, both must be the same. */
5560   assert( *piEndChild>=*piStartChild );
5561   assert( isPrefix || *piStartChild==*piEndChild );
5562 }
5563 
5564 /* Read block at iBlockid and pass it with other params to
5565 ** getChildrenContaining().
5566 */
loadAndGetChildrenContaining(fulltext_vtab * v,sqlite_int64 iBlockid,const char * pTerm,int nTerm,int isPrefix,sqlite_int64 * piStartChild,sqlite_int64 * piEndChild)5567 static int loadAndGetChildrenContaining(
5568   fulltext_vtab *v,
5569   sqlite_int64 iBlockid,
5570   const char *pTerm, int nTerm, int isPrefix,
5571   sqlite_int64 *piStartChild, sqlite_int64 *piEndChild
5572 ){
5573   sqlite3_stmt *s = NULL;
5574   int rc;
5575 
5576   assert( iBlockid!=0 );
5577   assert( pTerm!=NULL );
5578   assert( nTerm!=0 );        /* TODO(shess) Why not allow this? */
5579   assert( piStartChild!=NULL );
5580   assert( piEndChild!=NULL );
5581 
5582   rc = sql_get_statement(v, BLOCK_SELECT_STMT, &s);
5583   if( rc!=SQLITE_OK ) return rc;
5584 
5585   rc = sqlite3_bind_int64(s, 1, iBlockid);
5586   if( rc!=SQLITE_OK ) return rc;
5587 
5588   rc = sqlite3_step(s);
5589   if( rc==SQLITE_DONE ) return SQLITE_ERROR;
5590   if( rc!=SQLITE_ROW ) return rc;
5591 
5592   getChildrenContaining(sqlite3_column_blob(s, 0), sqlite3_column_bytes(s, 0),
5593                         pTerm, nTerm, isPrefix, piStartChild, piEndChild);
5594 
5595   /* We expect only one row.  We must execute another sqlite3_step()
5596    * to complete the iteration; otherwise the table will remain
5597    * locked. */
5598   rc = sqlite3_step(s);
5599   if( rc==SQLITE_ROW ) return SQLITE_ERROR;
5600   if( rc!=SQLITE_DONE ) return rc;
5601 
5602   return SQLITE_OK;
5603 }
5604 
5605 /* Traverse the tree represented by pData[nData] looking for
5606 ** pTerm[nTerm], placing its doclist into *out.  This is internal to
5607 ** loadSegment() to make error-handling cleaner.
5608 */
loadSegmentInt(fulltext_vtab * v,const char * pData,int nData,sqlite_int64 iLeavesEnd,const char * pTerm,int nTerm,int isPrefix,DataBuffer * out)5609 static int loadSegmentInt(fulltext_vtab *v, const char *pData, int nData,
5610                           sqlite_int64 iLeavesEnd,
5611                           const char *pTerm, int nTerm, int isPrefix,
5612                           DataBuffer *out){
5613   /* Special case where root is a leaf. */
5614   if( *pData=='\0' ){
5615     return loadSegmentLeaf(v, pData, nData, pTerm, nTerm, isPrefix, out);
5616   }else{
5617     int rc;
5618     sqlite_int64 iStartChild, iEndChild;
5619 
5620     /* Process pData as an interior node, then loop down the tree
5621     ** until we find the set of leaf nodes to scan for the term.
5622     */
5623     getChildrenContaining(pData, nData, pTerm, nTerm, isPrefix,
5624                           &iStartChild, &iEndChild);
5625     while( iStartChild>iLeavesEnd ){
5626       sqlite_int64 iNextStart, iNextEnd;
5627       rc = loadAndGetChildrenContaining(v, iStartChild, pTerm, nTerm, isPrefix,
5628                                         &iNextStart, &iNextEnd);
5629       if( rc!=SQLITE_OK ) return rc;
5630 
5631       /* If we've branched, follow the end branch, too. */
5632       if( iStartChild!=iEndChild ){
5633         sqlite_int64 iDummy;
5634         rc = loadAndGetChildrenContaining(v, iEndChild, pTerm, nTerm, isPrefix,
5635                                           &iDummy, &iNextEnd);
5636         if( rc!=SQLITE_OK ) return rc;
5637       }
5638 
5639       assert( iNextStart<=iNextEnd );
5640       iStartChild = iNextStart;
5641       iEndChild = iNextEnd;
5642     }
5643     assert( iStartChild<=iLeavesEnd );
5644     assert( iEndChild<=iLeavesEnd );
5645 
5646     /* Scan through the leaf segments for doclists. */
5647     return loadSegmentLeaves(v, iStartChild, iEndChild,
5648                              pTerm, nTerm, isPrefix, out);
5649   }
5650 }
5651 
5652 /* Call loadSegmentInt() to collect the doclist for pTerm/nTerm, then
5653 ** merge its doclist over *out (any duplicate doclists read from the
5654 ** segment rooted at pData will overwrite those in *out).
5655 */
5656 /* TODO(shess) Consider changing this to determine the depth of the
5657 ** leaves using either the first characters of interior nodes (when
5658 ** ==1, we're one level above the leaves), or the first character of
5659 ** the root (which will describe the height of the tree directly).
5660 ** Either feels somewhat tricky to me.
5661 */
5662 /* TODO(shess) The current merge is likely to be slow for large
5663 ** doclists (though it should process from newest/smallest to
5664 ** oldest/largest, so it may not be that bad).  It might be useful to
5665 ** modify things to allow for N-way merging.  This could either be
5666 ** within a segment, with pairwise merges across segments, or across
5667 ** all segments at once.
5668 */
loadSegment(fulltext_vtab * v,const char * pData,int nData,sqlite_int64 iLeavesEnd,const char * pTerm,int nTerm,int isPrefix,DataBuffer * out)5669 static int loadSegment(fulltext_vtab *v, const char *pData, int nData,
5670                        sqlite_int64 iLeavesEnd,
5671                        const char *pTerm, int nTerm, int isPrefix,
5672                        DataBuffer *out){
5673   DataBuffer result;
5674   int rc;
5675 
5676   assert( nData>1 );
5677 
5678   /* This code should never be called with buffered updates. */
5679   assert( v->nPendingData<0 );
5680 
5681   dataBufferInit(&result, 0);
5682   rc = loadSegmentInt(v, pData, nData, iLeavesEnd,
5683                       pTerm, nTerm, isPrefix, &result);
5684   if( rc==SQLITE_OK && result.nData>0 ){
5685     if( out->nData==0 ){
5686       DataBuffer tmp = *out;
5687       *out = result;
5688       result = tmp;
5689     }else{
5690       DataBuffer merged;
5691       DLReader readers[2];
5692 
5693       dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData);
5694       dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData);
5695       dataBufferInit(&merged, out->nData+result.nData);
5696       docListMerge(&merged, readers, 2);
5697       dataBufferDestroy(out);
5698       *out = merged;
5699       dlrDestroy(&readers[0]);
5700       dlrDestroy(&readers[1]);
5701     }
5702   }
5703   dataBufferDestroy(&result);
5704   return rc;
5705 }
5706 
5707 /* Scan the database and merge together the posting lists for the term
5708 ** into *out.
5709 */
termSelect(fulltext_vtab * v,int iColumn,const char * pTerm,int nTerm,int isPrefix,DocListType iType,DataBuffer * out)5710 static int termSelect(fulltext_vtab *v, int iColumn,
5711                       const char *pTerm, int nTerm, int isPrefix,
5712                       DocListType iType, DataBuffer *out){
5713   DataBuffer doclist;
5714   sqlite3_stmt *s;
5715   int rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
5716   if( rc!=SQLITE_OK ) return rc;
5717 
5718   /* This code should never be called with buffered updates. */
5719   assert( v->nPendingData<0 );
5720 
5721   dataBufferInit(&doclist, 0);
5722 
5723   /* Traverse the segments from oldest to newest so that newer doclist
5724   ** elements for given docids overwrite older elements.
5725   */
5726   while( (rc = sqlite3_step(s))==SQLITE_ROW ){
5727     const char *pData = sqlite3_column_blob(s, 2);
5728     const int nData = sqlite3_column_bytes(s, 2);
5729     const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
5730     rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, isPrefix,
5731                      &doclist);
5732     if( rc!=SQLITE_OK ) goto err;
5733   }
5734   if( rc==SQLITE_DONE ){
5735     if( doclist.nData!=0 ){
5736       /* TODO(shess) The old term_select_all() code applied the column
5737       ** restrict as we merged segments, leading to smaller buffers.
5738       ** This is probably worthwhile to bring back, once the new storage
5739       ** system is checked in.
5740       */
5741       if( iColumn==v->nColumn) iColumn = -1;
5742       docListTrim(DL_DEFAULT, doclist.pData, doclist.nData,
5743                   iColumn, iType, out);
5744     }
5745     rc = SQLITE_OK;
5746   }
5747 
5748  err:
5749   dataBufferDestroy(&doclist);
5750   return rc;
5751 }
5752 
5753 /****************************************************************/
5754 /* Used to hold hashtable data for sorting. */
5755 typedef struct TermData {
5756   const char *pTerm;
5757   int nTerm;
5758   DLCollector *pCollector;
5759 } TermData;
5760 
5761 /* Orders TermData elements in strcmp fashion ( <0 for less-than, 0
5762 ** for equal, >0 for greater-than).
5763 */
termDataCmp(const void * av,const void * bv)5764 static int termDataCmp(const void *av, const void *bv){
5765   const TermData *a = (const TermData *)av;
5766   const TermData *b = (const TermData *)bv;
5767   int n = a->nTerm<b->nTerm ? a->nTerm : b->nTerm;
5768   int c = memcmp(a->pTerm, b->pTerm, n);
5769   if( c!=0 ) return c;
5770   return a->nTerm-b->nTerm;
5771 }
5772 
5773 /* Order pTerms data by term, then write a new level 0 segment using
5774 ** LeafWriter.
5775 */
writeZeroSegment(fulltext_vtab * v,fts2Hash * pTerms)5776 static int writeZeroSegment(fulltext_vtab *v, fts2Hash *pTerms){
5777   fts2HashElem *e;
5778   int idx, rc, i, n;
5779   TermData *pData;
5780   LeafWriter writer;
5781   DataBuffer dl;
5782 
5783   /* Determine the next index at level 0, merging as necessary. */
5784   rc = segdirNextIndex(v, 0, &idx);
5785   if( rc!=SQLITE_OK ) return rc;
5786 
5787   n = fts2HashCount(pTerms);
5788   pData = sqlite3_malloc(n*sizeof(TermData));
5789 
5790   for(i = 0, e = fts2HashFirst(pTerms); e; i++, e = fts2HashNext(e)){
5791     assert( i<n );
5792     pData[i].pTerm = fts2HashKey(e);
5793     pData[i].nTerm = fts2HashKeysize(e);
5794     pData[i].pCollector = fts2HashData(e);
5795   }
5796   assert( i==n );
5797 
5798   /* TODO(shess) Should we allow user-defined collation sequences,
5799   ** here?  I think we only need that once we support prefix searches.
5800   */
5801   if( n>1 ) qsort(pData, n, sizeof(*pData), termDataCmp);
5802 
5803   /* TODO(shess) Refactor so that we can write directly to the segment
5804   ** DataBuffer, as happens for segment merges.
5805   */
5806   leafWriterInit(0, idx, &writer);
5807   dataBufferInit(&dl, 0);
5808   for(i=0; i<n; i++){
5809     dataBufferReset(&dl);
5810     dlcAddDoclist(pData[i].pCollector, &dl);
5811     rc = leafWriterStep(v, &writer,
5812                         pData[i].pTerm, pData[i].nTerm, dl.pData, dl.nData);
5813     if( rc!=SQLITE_OK ) goto err;
5814   }
5815   rc = leafWriterFinalize(v, &writer);
5816 
5817  err:
5818   dataBufferDestroy(&dl);
5819   sqlite3_free(pData);
5820   leafWriterDestroy(&writer);
5821   return rc;
5822 }
5823 
5824 /* If pendingTerms has data, free it. */
clearPendingTerms(fulltext_vtab * v)5825 static int clearPendingTerms(fulltext_vtab *v){
5826   if( v->nPendingData>=0 ){
5827     fts2HashElem *e;
5828     for(e=fts2HashFirst(&v->pendingTerms); e; e=fts2HashNext(e)){
5829       dlcDelete(fts2HashData(e));
5830     }
5831     fts2HashClear(&v->pendingTerms);
5832     v->nPendingData = -1;
5833   }
5834   return SQLITE_OK;
5835 }
5836 
5837 /* If pendingTerms has data, flush it to a level-zero segment, and
5838 ** free it.
5839 */
flushPendingTerms(fulltext_vtab * v)5840 static int flushPendingTerms(fulltext_vtab *v){
5841   if( v->nPendingData>=0 ){
5842     int rc = writeZeroSegment(v, &v->pendingTerms);
5843     if( rc==SQLITE_OK ) clearPendingTerms(v);
5844     return rc;
5845   }
5846   return SQLITE_OK;
5847 }
5848 
5849 /* If pendingTerms is "too big", or docid is out of order, flush it.
5850 ** Regardless, be certain that pendingTerms is initialized for use.
5851 */
initPendingTerms(fulltext_vtab * v,sqlite_int64 iDocid)5852 static int initPendingTerms(fulltext_vtab *v, sqlite_int64 iDocid){
5853   /* TODO(shess) Explore whether partially flushing the buffer on
5854   ** forced-flush would provide better performance.  I suspect that if
5855   ** we ordered the doclists by size and flushed the largest until the
5856   ** buffer was half empty, that would let the less frequent terms
5857   ** generate longer doclists.
5858   */
5859   if( iDocid<=v->iPrevDocid || v->nPendingData>kPendingThreshold ){
5860     int rc = flushPendingTerms(v);
5861     if( rc!=SQLITE_OK ) return rc;
5862   }
5863   if( v->nPendingData<0 ){
5864     fts2HashInit(&v->pendingTerms, FTS2_HASH_STRING, 1);
5865     v->nPendingData = 0;
5866   }
5867   v->iPrevDocid = iDocid;
5868   return SQLITE_OK;
5869 }
5870 
5871 /* This function implements the xUpdate callback; it is the top-level entry
5872  * point for inserting, deleting or updating a row in a full-text table. */
fulltextUpdate(sqlite3_vtab * pVtab,int nArg,sqlite3_value ** ppArg,sqlite_int64 * pRowid)5873 static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg,
5874                    sqlite_int64 *pRowid){
5875   fulltext_vtab *v = (fulltext_vtab *) pVtab;
5876   int rc;
5877 
5878   TRACE(("FTS2 Update %p\n", pVtab));
5879 
5880   if( nArg<2 ){
5881     rc = index_delete(v, sqlite3_value_int64(ppArg[0]));
5882     if( rc==SQLITE_OK ){
5883       /* If we just deleted the last row in the table, clear out the
5884       ** index data.
5885       */
5886       rc = content_exists(v);
5887       if( rc==SQLITE_ROW ){
5888         rc = SQLITE_OK;
5889       }else if( rc==SQLITE_DONE ){
5890         /* Clear the pending terms so we don't flush a useless level-0
5891         ** segment when the transaction closes.
5892         */
5893         rc = clearPendingTerms(v);
5894         if( rc==SQLITE_OK ){
5895           rc = segdir_delete_all(v);
5896         }
5897       }
5898     }
5899   } else if( sqlite3_value_type(ppArg[0]) != SQLITE_NULL ){
5900     /* An update:
5901      * ppArg[0] = old rowid
5902      * ppArg[1] = new rowid
5903      * ppArg[2..2+v->nColumn-1] = values
5904      * ppArg[2+v->nColumn] = value for magic column (we ignore this)
5905      */
5906     sqlite_int64 rowid = sqlite3_value_int64(ppArg[0]);
5907     if( sqlite3_value_type(ppArg[1]) != SQLITE_INTEGER ||
5908       sqlite3_value_int64(ppArg[1]) != rowid ){
5909       rc = SQLITE_ERROR;  /* we don't allow changing the rowid */
5910     } else {
5911       assert( nArg==2+v->nColumn+1);
5912       rc = index_update(v, rowid, &ppArg[2]);
5913     }
5914   } else {
5915     /* An insert:
5916      * ppArg[1] = requested rowid
5917      * ppArg[2..2+v->nColumn-1] = values
5918      * ppArg[2+v->nColumn] = value for magic column (we ignore this)
5919      */
5920     assert( nArg==2+v->nColumn+1);
5921     rc = index_insert(v, ppArg[1], &ppArg[2], pRowid);
5922   }
5923 
5924   return rc;
5925 }
5926 
fulltextSync(sqlite3_vtab * pVtab)5927 static int fulltextSync(sqlite3_vtab *pVtab){
5928   TRACE(("FTS2 xSync()\n"));
5929   return flushPendingTerms((fulltext_vtab *)pVtab);
5930 }
5931 
fulltextBegin(sqlite3_vtab * pVtab)5932 static int fulltextBegin(sqlite3_vtab *pVtab){
5933   fulltext_vtab *v = (fulltext_vtab *) pVtab;
5934   TRACE(("FTS2 xBegin()\n"));
5935 
5936   /* Any buffered updates should have been cleared by the previous
5937   ** transaction.
5938   */
5939   assert( v->nPendingData<0 );
5940   return clearPendingTerms(v);
5941 }
5942 
fulltextCommit(sqlite3_vtab * pVtab)5943 static int fulltextCommit(sqlite3_vtab *pVtab){
5944   fulltext_vtab *v = (fulltext_vtab *) pVtab;
5945   TRACE(("FTS2 xCommit()\n"));
5946 
5947   /* Buffered updates should have been cleared by fulltextSync(). */
5948   assert( v->nPendingData<0 );
5949   return clearPendingTerms(v);
5950 }
5951 
fulltextRollback(sqlite3_vtab * pVtab)5952 static int fulltextRollback(sqlite3_vtab *pVtab){
5953   TRACE(("FTS2 xRollback()\n"));
5954   return clearPendingTerms((fulltext_vtab *)pVtab);
5955 }
5956 
5957 /*
5958 ** Implementation of the snippet() function for FTS2
5959 */
snippetFunc(sqlite3_context * pContext,int argc,sqlite3_value ** argv)5960 static void snippetFunc(
5961   sqlite3_context *pContext,
5962   int argc,
5963   sqlite3_value **argv
5964 ){
5965   fulltext_cursor *pCursor;
5966   if( argc<1 ) return;
5967   if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
5968       sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
5969     sqlite3_result_error(pContext, "illegal first argument to html_snippet",-1);
5970   }else{
5971     const char *zStart = "<b>";
5972     const char *zEnd = "</b>";
5973     const char *zEllipsis = "<b>...</b>";
5974     memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
5975     if( argc>=2 ){
5976       zStart = (const char*)sqlite3_value_text(argv[1]);
5977       if( argc>=3 ){
5978         zEnd = (const char*)sqlite3_value_text(argv[2]);
5979         if( argc>=4 ){
5980           zEllipsis = (const char*)sqlite3_value_text(argv[3]);
5981         }
5982       }
5983     }
5984     snippetAllOffsets(pCursor);
5985     snippetText(pCursor, zStart, zEnd, zEllipsis);
5986     sqlite3_result_text(pContext, pCursor->snippet.zSnippet,
5987                         pCursor->snippet.nSnippet, SQLITE_STATIC);
5988   }
5989 }
5990 
5991 /*
5992 ** Implementation of the offsets() function for FTS2
5993 */
snippetOffsetsFunc(sqlite3_context * pContext,int argc,sqlite3_value ** argv)5994 static void snippetOffsetsFunc(
5995   sqlite3_context *pContext,
5996   int argc,
5997   sqlite3_value **argv
5998 ){
5999   fulltext_cursor *pCursor;
6000   if( argc<1 ) return;
6001   if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
6002       sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
6003     sqlite3_result_error(pContext, "illegal first argument to offsets",-1);
6004   }else{
6005     memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
6006     snippetAllOffsets(pCursor);
6007     snippetOffsetText(&pCursor->snippet);
6008     sqlite3_result_text(pContext,
6009                         pCursor->snippet.zOffset, pCursor->snippet.nOffset,
6010                         SQLITE_STATIC);
6011   }
6012 }
6013 
6014 /* OptLeavesReader is nearly identical to LeavesReader, except that
6015 ** where LeavesReader is geared towards the merging of complete
6016 ** segment levels (with exactly MERGE_COUNT segments), OptLeavesReader
6017 ** is geared towards implementation of the optimize() function, and
6018 ** can merge all segments simultaneously.  This version may be
6019 ** somewhat less efficient than LeavesReader because it merges into an
6020 ** accumulator rather than doing an N-way merge, but since segment
6021 ** size grows exponentially (so segment count logrithmically) this is
6022 ** probably not an immediate problem.
6023 */
6024 /* TODO(shess): Prove that assertion, or extend the merge code to
6025 ** merge tree fashion (like the prefix-searching code does).
6026 */
6027 /* TODO(shess): OptLeavesReader and LeavesReader could probably be
6028 ** merged with little or no loss of performance for LeavesReader.  The
6029 ** merged code would need to handle >MERGE_COUNT segments, and would
6030 ** also need to be able to optionally optimize away deletes.
6031 */
6032 typedef struct OptLeavesReader {
6033   /* Segment number, to order readers by age. */
6034   int segment;
6035   LeavesReader reader;
6036 } OptLeavesReader;
6037 
optLeavesReaderAtEnd(OptLeavesReader * pReader)6038 static int optLeavesReaderAtEnd(OptLeavesReader *pReader){
6039   return leavesReaderAtEnd(&pReader->reader);
6040 }
optLeavesReaderTermBytes(OptLeavesReader * pReader)6041 static int optLeavesReaderTermBytes(OptLeavesReader *pReader){
6042   return leavesReaderTermBytes(&pReader->reader);
6043 }
optLeavesReaderData(OptLeavesReader * pReader)6044 static const char *optLeavesReaderData(OptLeavesReader *pReader){
6045   return leavesReaderData(&pReader->reader);
6046 }
optLeavesReaderDataBytes(OptLeavesReader * pReader)6047 static int optLeavesReaderDataBytes(OptLeavesReader *pReader){
6048   return leavesReaderDataBytes(&pReader->reader);
6049 }
optLeavesReaderTerm(OptLeavesReader * pReader)6050 static const char *optLeavesReaderTerm(OptLeavesReader *pReader){
6051   return leavesReaderTerm(&pReader->reader);
6052 }
optLeavesReaderStep(fulltext_vtab * v,OptLeavesReader * pReader)6053 static int optLeavesReaderStep(fulltext_vtab *v, OptLeavesReader *pReader){
6054   return leavesReaderStep(v, &pReader->reader);
6055 }
optLeavesReaderTermCmp(OptLeavesReader * lr1,OptLeavesReader * lr2)6056 static int optLeavesReaderTermCmp(OptLeavesReader *lr1, OptLeavesReader *lr2){
6057   return leavesReaderTermCmp(&lr1->reader, &lr2->reader);
6058 }
6059 /* Order by term ascending, segment ascending (oldest to newest), with
6060 ** exhausted readers to the end.
6061 */
optLeavesReaderCmp(OptLeavesReader * lr1,OptLeavesReader * lr2)6062 static int optLeavesReaderCmp(OptLeavesReader *lr1, OptLeavesReader *lr2){
6063   int c = optLeavesReaderTermCmp(lr1, lr2);
6064   if( c!=0 ) return c;
6065   return lr1->segment-lr2->segment;
6066 }
6067 /* Bubble pLr[0] to appropriate place in pLr[1..nLr-1].  Assumes that
6068 ** pLr[1..nLr-1] is already sorted.
6069 */
optLeavesReaderReorder(OptLeavesReader * pLr,int nLr)6070 static void optLeavesReaderReorder(OptLeavesReader *pLr, int nLr){
6071   while( nLr>1 && optLeavesReaderCmp(pLr, pLr+1)>0 ){
6072     OptLeavesReader tmp = pLr[0];
6073     pLr[0] = pLr[1];
6074     pLr[1] = tmp;
6075     nLr--;
6076     pLr++;
6077   }
6078 }
6079 
6080 /* optimize() helper function.  Put the readers in order and iterate
6081 ** through them, merging doclists for matching terms into pWriter.
6082 ** Returns SQLITE_OK on success, or the SQLite error code which
6083 ** prevented success.
6084 */
optimizeInternal(fulltext_vtab * v,OptLeavesReader * readers,int nReaders,LeafWriter * pWriter)6085 static int optimizeInternal(fulltext_vtab *v,
6086                             OptLeavesReader *readers, int nReaders,
6087                             LeafWriter *pWriter){
6088   int i, rc = SQLITE_OK;
6089   DataBuffer doclist, merged, tmp;
6090 
6091   /* Order the readers. */
6092   i = nReaders;
6093   while( i-- > 0 ){
6094     optLeavesReaderReorder(&readers[i], nReaders-i);
6095   }
6096 
6097   dataBufferInit(&doclist, LEAF_MAX);
6098   dataBufferInit(&merged, LEAF_MAX);
6099 
6100   /* Exhausted readers bubble to the end, so when the first reader is
6101   ** at eof, all are at eof.
6102   */
6103   while( !optLeavesReaderAtEnd(&readers[0]) ){
6104 
6105     /* Figure out how many readers share the next term. */
6106     for(i=1; i<nReaders && !optLeavesReaderAtEnd(&readers[i]); i++){
6107       if( 0!=optLeavesReaderTermCmp(&readers[0], &readers[i]) ) break;
6108     }
6109 
6110     /* Special-case for no merge. */
6111     if( i==1 ){
6112       /* Trim deletions from the doclist. */
6113       dataBufferReset(&merged);
6114       docListTrim(DL_DEFAULT,
6115                   optLeavesReaderData(&readers[0]),
6116                   optLeavesReaderDataBytes(&readers[0]),
6117                   -1, DL_DEFAULT, &merged);
6118     }else{
6119       DLReader dlReaders[MERGE_COUNT];
6120       int iReader, nReaders;
6121 
6122       /* Prime the pipeline with the first reader's doclist.  After
6123       ** one pass index 0 will reference the accumulated doclist.
6124       */
6125       dlrInit(&dlReaders[0], DL_DEFAULT,
6126               optLeavesReaderData(&readers[0]),
6127               optLeavesReaderDataBytes(&readers[0]));
6128       iReader = 1;
6129 
6130       assert( iReader<i );  /* Must execute the loop at least once. */
6131       while( iReader<i ){
6132         /* Merge 16 inputs per pass. */
6133         for( nReaders=1; iReader<i && nReaders<MERGE_COUNT;
6134              iReader++, nReaders++ ){
6135           dlrInit(&dlReaders[nReaders], DL_DEFAULT,
6136                   optLeavesReaderData(&readers[iReader]),
6137                   optLeavesReaderDataBytes(&readers[iReader]));
6138         }
6139 
6140         /* Merge doclists and swap result into accumulator. */
6141         dataBufferReset(&merged);
6142         docListMerge(&merged, dlReaders, nReaders);
6143         tmp = merged;
6144         merged = doclist;
6145         doclist = tmp;
6146 
6147         while( nReaders-- > 0 ){
6148           dlrDestroy(&dlReaders[nReaders]);
6149         }
6150 
6151         /* Accumulated doclist to reader 0 for next pass. */
6152         dlrInit(&dlReaders[0], DL_DEFAULT, doclist.pData, doclist.nData);
6153       }
6154 
6155       /* Destroy reader that was left in the pipeline. */
6156       dlrDestroy(&dlReaders[0]);
6157 
6158       /* Trim deletions from the doclist. */
6159       dataBufferReset(&merged);
6160       docListTrim(DL_DEFAULT, doclist.pData, doclist.nData,
6161                   -1, DL_DEFAULT, &merged);
6162     }
6163 
6164     /* Only pass doclists with hits (skip if all hits deleted). */
6165     if( merged.nData>0 ){
6166       rc = leafWriterStep(v, pWriter,
6167                           optLeavesReaderTerm(&readers[0]),
6168                           optLeavesReaderTermBytes(&readers[0]),
6169                           merged.pData, merged.nData);
6170       if( rc!=SQLITE_OK ) goto err;
6171     }
6172 
6173     /* Step merged readers to next term and reorder. */
6174     while( i-- > 0 ){
6175       rc = optLeavesReaderStep(v, &readers[i]);
6176       if( rc!=SQLITE_OK ) goto err;
6177 
6178       optLeavesReaderReorder(&readers[i], nReaders-i);
6179     }
6180   }
6181 
6182  err:
6183   dataBufferDestroy(&doclist);
6184   dataBufferDestroy(&merged);
6185   return rc;
6186 }
6187 
6188 /* Implement optimize() function for FTS3.  optimize(t) merges all
6189 ** segments in the fts index into a single segment.  't' is the magic
6190 ** table-named column.
6191 */
optimizeFunc(sqlite3_context * pContext,int argc,sqlite3_value ** argv)6192 static void optimizeFunc(sqlite3_context *pContext,
6193                          int argc, sqlite3_value **argv){
6194   fulltext_cursor *pCursor;
6195   if( argc>1 ){
6196     sqlite3_result_error(pContext, "excess arguments to optimize()",-1);
6197   }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
6198             sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
6199     sqlite3_result_error(pContext, "illegal first argument to optimize",-1);
6200   }else{
6201     fulltext_vtab *v;
6202     int i, rc, iMaxLevel;
6203     OptLeavesReader *readers;
6204     int nReaders;
6205     LeafWriter writer;
6206     sqlite3_stmt *s;
6207 
6208     memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
6209     v = cursor_vtab(pCursor);
6210 
6211     /* Flush any buffered updates before optimizing. */
6212     rc = flushPendingTerms(v);
6213     if( rc!=SQLITE_OK ) goto err;
6214 
6215     rc = segdir_count(v, &nReaders, &iMaxLevel);
6216     if( rc!=SQLITE_OK ) goto err;
6217     if( nReaders==0 || nReaders==1 ){
6218       sqlite3_result_text(pContext, "Index already optimal", -1,
6219                           SQLITE_STATIC);
6220       return;
6221     }
6222 
6223     rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
6224     if( rc!=SQLITE_OK ) goto err;
6225 
6226     readers = sqlite3_malloc(nReaders*sizeof(readers[0]));
6227     if( readers==NULL ) goto err;
6228 
6229     /* Note that there will already be a segment at this position
6230     ** until we call segdir_delete() on iMaxLevel.
6231     */
6232     leafWriterInit(iMaxLevel, 0, &writer);
6233 
6234     i = 0;
6235     while( (rc = sqlite3_step(s))==SQLITE_ROW ){
6236       sqlite_int64 iStart = sqlite3_column_int64(s, 0);
6237       sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
6238       const char *pRootData = sqlite3_column_blob(s, 2);
6239       int nRootData = sqlite3_column_bytes(s, 2);
6240 
6241       assert( i<nReaders );
6242       rc = leavesReaderInit(v, -1, iStart, iEnd, pRootData, nRootData,
6243                             &readers[i].reader);
6244       if( rc!=SQLITE_OK ) break;
6245 
6246       readers[i].segment = i;
6247       i++;
6248     }
6249 
6250     /* If we managed to successfully read them all, optimize them. */
6251     if( rc==SQLITE_DONE ){
6252       assert( i==nReaders );
6253       rc = optimizeInternal(v, readers, nReaders, &writer);
6254     }
6255 
6256     while( i-- > 0 ){
6257       leavesReaderDestroy(&readers[i].reader);
6258     }
6259     sqlite3_free(readers);
6260 
6261     /* If we've successfully gotten to here, delete the old segments
6262     ** and flush the interior structure of the new segment.
6263     */
6264     if( rc==SQLITE_OK ){
6265       for( i=0; i<=iMaxLevel; i++ ){
6266         rc = segdir_delete(v, i);
6267         if( rc!=SQLITE_OK ) break;
6268       }
6269 
6270       if( rc==SQLITE_OK ) rc = leafWriterFinalize(v, &writer);
6271     }
6272 
6273     leafWriterDestroy(&writer);
6274 
6275     if( rc!=SQLITE_OK ) goto err;
6276 
6277     sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC);
6278     return;
6279 
6280     /* TODO(shess): Error-handling needs to be improved along the
6281     ** lines of the dump_ functions.
6282     */
6283  err:
6284     {
6285       char buf[512];
6286       sqlite3_snprintf(sizeof(buf), buf, "Error in optimize: %s",
6287                        sqlite3_errmsg(sqlite3_context_db_handle(pContext)));
6288       sqlite3_result_error(pContext, buf, -1);
6289     }
6290   }
6291 }
6292 
6293 #ifdef SQLITE_TEST
6294 /* Generate an error of the form "<prefix>: <msg>".  If msg is NULL,
6295 ** pull the error from the context's db handle.
6296 */
generateError(sqlite3_context * pContext,const char * prefix,const char * msg)6297 static void generateError(sqlite3_context *pContext,
6298                           const char *prefix, const char *msg){
6299   char buf[512];
6300   if( msg==NULL ) msg = sqlite3_errmsg(sqlite3_context_db_handle(pContext));
6301   sqlite3_snprintf(sizeof(buf), buf, "%s: %s", prefix, msg);
6302   sqlite3_result_error(pContext, buf, -1);
6303 }
6304 
6305 /* Helper function to collect the set of terms in the segment into
6306 ** pTerms.  The segment is defined by the leaf nodes between
6307 ** iStartBlockid and iEndBlockid, inclusive, or by the contents of
6308 ** pRootData if iStartBlockid is 0 (in which case the entire segment
6309 ** fit in a leaf).
6310 */
collectSegmentTerms(fulltext_vtab * v,sqlite3_stmt * s,fts2Hash * pTerms)6311 static int collectSegmentTerms(fulltext_vtab *v, sqlite3_stmt *s,
6312                                fts2Hash *pTerms){
6313   const sqlite_int64 iStartBlockid = sqlite3_column_int64(s, 0);
6314   const sqlite_int64 iEndBlockid = sqlite3_column_int64(s, 1);
6315   const char *pRootData = sqlite3_column_blob(s, 2);
6316   const int nRootData = sqlite3_column_bytes(s, 2);
6317   LeavesReader reader;
6318   int rc = leavesReaderInit(v, 0, iStartBlockid, iEndBlockid,
6319                             pRootData, nRootData, &reader);
6320   if( rc!=SQLITE_OK ) return rc;
6321 
6322   while( rc==SQLITE_OK && !leavesReaderAtEnd(&reader) ){
6323     const char *pTerm = leavesReaderTerm(&reader);
6324     const int nTerm = leavesReaderTermBytes(&reader);
6325     void *oldValue = sqlite3Fts2HashFind(pTerms, pTerm, nTerm);
6326     void *newValue = (void *)((char *)oldValue+1);
6327 
6328     /* From the comment before sqlite3Fts2HashInsert in fts2_hash.c,
6329     ** the data value passed is returned in case of malloc failure.
6330     */
6331     if( newValue==sqlite3Fts2HashInsert(pTerms, pTerm, nTerm, newValue) ){
6332       rc = SQLITE_NOMEM;
6333     }else{
6334       rc = leavesReaderStep(v, &reader);
6335     }
6336   }
6337 
6338   leavesReaderDestroy(&reader);
6339   return rc;
6340 }
6341 
6342 /* Helper function to build the result string for dump_terms(). */
generateTermsResult(sqlite3_context * pContext,fts2Hash * pTerms)6343 static int generateTermsResult(sqlite3_context *pContext, fts2Hash *pTerms){
6344   int iTerm, nTerms, nResultBytes, iByte;
6345   char *result;
6346   TermData *pData;
6347   fts2HashElem *e;
6348 
6349   /* Iterate pTerms to generate an array of terms in pData for
6350   ** sorting.
6351   */
6352   nTerms = fts2HashCount(pTerms);
6353   assert( nTerms>0 );
6354   pData = sqlite3_malloc(nTerms*sizeof(TermData));
6355   if( pData==NULL ) return SQLITE_NOMEM;
6356 
6357   nResultBytes = 0;
6358   for(iTerm = 0, e = fts2HashFirst(pTerms); e; iTerm++, e = fts2HashNext(e)){
6359     nResultBytes += fts2HashKeysize(e)+1;   /* Term plus trailing space */
6360     assert( iTerm<nTerms );
6361     pData[iTerm].pTerm = fts2HashKey(e);
6362     pData[iTerm].nTerm = fts2HashKeysize(e);
6363     pData[iTerm].pCollector = fts2HashData(e);  /* unused */
6364   }
6365   assert( iTerm==nTerms );
6366 
6367   assert( nResultBytes>0 );   /* nTerms>0, nResultsBytes must be, too. */
6368   result = sqlite3_malloc(nResultBytes);
6369   if( result==NULL ){
6370     sqlite3_free(pData);
6371     return SQLITE_NOMEM;
6372   }
6373 
6374   if( nTerms>1 ) qsort(pData, nTerms, sizeof(*pData), termDataCmp);
6375 
6376   /* Read the terms in order to build the result. */
6377   iByte = 0;
6378   for(iTerm=0; iTerm<nTerms; ++iTerm){
6379     memcpy(result+iByte, pData[iTerm].pTerm, pData[iTerm].nTerm);
6380     iByte += pData[iTerm].nTerm;
6381     result[iByte++] = ' ';
6382   }
6383   assert( iByte==nResultBytes );
6384   assert( result[nResultBytes-1]==' ' );
6385   result[nResultBytes-1] = '\0';
6386 
6387   /* Passes away ownership of result. */
6388   sqlite3_result_text(pContext, result, nResultBytes-1, sqlite3_free);
6389   sqlite3_free(pData);
6390   return SQLITE_OK;
6391 }
6392 
6393 /* Implements dump_terms() for use in inspecting the fts2 index from
6394 ** tests.  TEXT result containing the ordered list of terms joined by
6395 ** spaces.  dump_terms(t, level, idx) dumps the terms for the segment
6396 ** specified by level, idx (in %_segdir), while dump_terms(t) dumps
6397 ** all terms in the index.  In both cases t is the fts table's magic
6398 ** table-named column.
6399 */
dumpTermsFunc(sqlite3_context * pContext,int argc,sqlite3_value ** argv)6400 static void dumpTermsFunc(
6401   sqlite3_context *pContext,
6402   int argc, sqlite3_value **argv
6403 ){
6404   fulltext_cursor *pCursor;
6405   if( argc!=3 && argc!=1 ){
6406     generateError(pContext, "dump_terms", "incorrect arguments");
6407   }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
6408             sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
6409     generateError(pContext, "dump_terms", "illegal first argument");
6410   }else{
6411     fulltext_vtab *v;
6412     fts2Hash terms;
6413     sqlite3_stmt *s = NULL;
6414     int rc;
6415 
6416     memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
6417     v = cursor_vtab(pCursor);
6418 
6419     /* If passed only the cursor column, get all segments.  Otherwise
6420     ** get the segment described by the following two arguments.
6421     */
6422     if( argc==1 ){
6423       rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
6424     }else{
6425       rc = sql_get_statement(v, SEGDIR_SELECT_SEGMENT_STMT, &s);
6426       if( rc==SQLITE_OK ){
6427         rc = sqlite3_bind_int(s, 1, sqlite3_value_int(argv[1]));
6428         if( rc==SQLITE_OK ){
6429           rc = sqlite3_bind_int(s, 2, sqlite3_value_int(argv[2]));
6430         }
6431       }
6432     }
6433 
6434     if( rc!=SQLITE_OK ){
6435       generateError(pContext, "dump_terms", NULL);
6436       return;
6437     }
6438 
6439     /* Collect the terms for each segment. */
6440     sqlite3Fts2HashInit(&terms, FTS2_HASH_STRING, 1);
6441     while( (rc = sqlite3_step(s))==SQLITE_ROW ){
6442       rc = collectSegmentTerms(v, s, &terms);
6443       if( rc!=SQLITE_OK ) break;
6444     }
6445 
6446     if( rc!=SQLITE_DONE ){
6447       sqlite3_reset(s);
6448       generateError(pContext, "dump_terms", NULL);
6449     }else{
6450       const int nTerms = fts2HashCount(&terms);
6451       if( nTerms>0 ){
6452         rc = generateTermsResult(pContext, &terms);
6453         if( rc==SQLITE_NOMEM ){
6454           generateError(pContext, "dump_terms", "out of memory");
6455         }else{
6456           assert( rc==SQLITE_OK );
6457         }
6458       }else if( argc==3 ){
6459         /* The specific segment asked for could not be found. */
6460         generateError(pContext, "dump_terms", "segment not found");
6461       }else{
6462         /* No segments found. */
6463         /* TODO(shess): It should be impossible to reach this.  This
6464         ** case can only happen for an empty table, in which case
6465         ** SQLite has no rows to call this function on.
6466         */
6467         sqlite3_result_null(pContext);
6468       }
6469     }
6470     sqlite3Fts2HashClear(&terms);
6471   }
6472 }
6473 
6474 /* Expand the DL_DEFAULT doclist in pData into a text result in
6475 ** pContext.
6476 */
createDoclistResult(sqlite3_context * pContext,const char * pData,int nData)6477 static void createDoclistResult(sqlite3_context *pContext,
6478                                 const char *pData, int nData){
6479   DataBuffer dump;
6480   DLReader dlReader;
6481 
6482   assert( pData!=NULL && nData>0 );
6483 
6484   dataBufferInit(&dump, 0);
6485   dlrInit(&dlReader, DL_DEFAULT, pData, nData);
6486   for( ; !dlrAtEnd(&dlReader); dlrStep(&dlReader) ){
6487     char buf[256];
6488     PLReader plReader;
6489 
6490     plrInit(&plReader, &dlReader);
6491     if( DL_DEFAULT==DL_DOCIDS || plrAtEnd(&plReader) ){
6492       sqlite3_snprintf(sizeof(buf), buf, "[%lld] ", dlrDocid(&dlReader));
6493       dataBufferAppend(&dump, buf, strlen(buf));
6494     }else{
6495       int iColumn = plrColumn(&plReader);
6496 
6497       sqlite3_snprintf(sizeof(buf), buf, "[%lld %d[",
6498                        dlrDocid(&dlReader), iColumn);
6499       dataBufferAppend(&dump, buf, strlen(buf));
6500 
6501       for( ; !plrAtEnd(&plReader); plrStep(&plReader) ){
6502         if( plrColumn(&plReader)!=iColumn ){
6503           iColumn = plrColumn(&plReader);
6504           sqlite3_snprintf(sizeof(buf), buf, "] %d[", iColumn);
6505           assert( dump.nData>0 );
6506           dump.nData--;                     /* Overwrite trailing space. */
6507           assert( dump.pData[dump.nData]==' ');
6508           dataBufferAppend(&dump, buf, strlen(buf));
6509         }
6510         if( DL_DEFAULT==DL_POSITIONS_OFFSETS ){
6511           sqlite3_snprintf(sizeof(buf), buf, "%d,%d,%d ",
6512                            plrPosition(&plReader),
6513                            plrStartOffset(&plReader), plrEndOffset(&plReader));
6514         }else if( DL_DEFAULT==DL_POSITIONS ){
6515           sqlite3_snprintf(sizeof(buf), buf, "%d ", plrPosition(&plReader));
6516         }else{
6517           assert( NULL=="Unhandled DL_DEFAULT value");
6518         }
6519         dataBufferAppend(&dump, buf, strlen(buf));
6520       }
6521       plrDestroy(&plReader);
6522 
6523       assert( dump.nData>0 );
6524       dump.nData--;                     /* Overwrite trailing space. */
6525       assert( dump.pData[dump.nData]==' ');
6526       dataBufferAppend(&dump, "]] ", 3);
6527     }
6528   }
6529   dlrDestroy(&dlReader);
6530 
6531   assert( dump.nData>0 );
6532   dump.nData--;                     /* Overwrite trailing space. */
6533   assert( dump.pData[dump.nData]==' ');
6534   dump.pData[dump.nData] = '\0';
6535   assert( dump.nData>0 );
6536 
6537   /* Passes ownership of dump's buffer to pContext. */
6538   sqlite3_result_text(pContext, dump.pData, dump.nData, sqlite3_free);
6539   dump.pData = NULL;
6540   dump.nData = dump.nCapacity = 0;
6541 }
6542 
6543 /* Implements dump_doclist() for use in inspecting the fts2 index from
6544 ** tests.  TEXT result containing a string representation of the
6545 ** doclist for the indicated term.  dump_doclist(t, term, level, idx)
6546 ** dumps the doclist for term from the segment specified by level, idx
6547 ** (in %_segdir), while dump_doclist(t, term) dumps the logical
6548 ** doclist for the term across all segments.  The per-segment doclist
6549 ** can contain deletions, while the full-index doclist will not
6550 ** (deletions are omitted).
6551 **
6552 ** Result formats differ with the setting of DL_DEFAULTS.  Examples:
6553 **
6554 ** DL_DOCIDS: [1] [3] [7]
6555 ** DL_POSITIONS: [1 0[0 4] 1[17]] [3 1[5]]
6556 ** DL_POSITIONS_OFFSETS: [1 0[0,0,3 4,23,26] 1[17,102,105]] [3 1[5,20,23]]
6557 **
6558 ** In each case the number after the outer '[' is the docid.  In the
6559 ** latter two cases, the number before the inner '[' is the column
6560 ** associated with the values within.  For DL_POSITIONS the numbers
6561 ** within are the positions, for DL_POSITIONS_OFFSETS they are the
6562 ** position, the start offset, and the end offset.
6563 */
dumpDoclistFunc(sqlite3_context * pContext,int argc,sqlite3_value ** argv)6564 static void dumpDoclistFunc(
6565   sqlite3_context *pContext,
6566   int argc, sqlite3_value **argv
6567 ){
6568   fulltext_cursor *pCursor;
6569   if( argc!=2 && argc!=4 ){
6570     generateError(pContext, "dump_doclist", "incorrect arguments");
6571   }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
6572             sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
6573     generateError(pContext, "dump_doclist", "illegal first argument");
6574   }else if( sqlite3_value_text(argv[1])==NULL ||
6575             sqlite3_value_text(argv[1])[0]=='\0' ){
6576     generateError(pContext, "dump_doclist", "empty second argument");
6577   }else{
6578     const char *pTerm = (const char *)sqlite3_value_text(argv[1]);
6579     const int nTerm = strlen(pTerm);
6580     fulltext_vtab *v;
6581     int rc;
6582     DataBuffer doclist;
6583 
6584     memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
6585     v = cursor_vtab(pCursor);
6586 
6587     dataBufferInit(&doclist, 0);
6588 
6589     /* termSelect() yields the same logical doclist that queries are
6590     ** run against.
6591     */
6592     if( argc==2 ){
6593       rc = termSelect(v, v->nColumn, pTerm, nTerm, 0, DL_DEFAULT, &doclist);
6594     }else{
6595       sqlite3_stmt *s = NULL;
6596 
6597       /* Get our specific segment's information. */
6598       rc = sql_get_statement(v, SEGDIR_SELECT_SEGMENT_STMT, &s);
6599       if( rc==SQLITE_OK ){
6600         rc = sqlite3_bind_int(s, 1, sqlite3_value_int(argv[2]));
6601         if( rc==SQLITE_OK ){
6602           rc = sqlite3_bind_int(s, 2, sqlite3_value_int(argv[3]));
6603         }
6604       }
6605 
6606       if( rc==SQLITE_OK ){
6607         rc = sqlite3_step(s);
6608 
6609         if( rc==SQLITE_DONE ){
6610           dataBufferDestroy(&doclist);
6611           generateError(pContext, "dump_doclist", "segment not found");
6612           return;
6613         }
6614 
6615         /* Found a segment, load it into doclist. */
6616         if( rc==SQLITE_ROW ){
6617           const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
6618           const char *pData = sqlite3_column_blob(s, 2);
6619           const int nData = sqlite3_column_bytes(s, 2);
6620 
6621           /* loadSegment() is used by termSelect() to load each
6622           ** segment's data.
6623           */
6624           rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, 0,
6625                            &doclist);
6626           if( rc==SQLITE_OK ){
6627             rc = sqlite3_step(s);
6628 
6629             /* Should not have more than one matching segment. */
6630             if( rc!=SQLITE_DONE ){
6631               sqlite3_reset(s);
6632               dataBufferDestroy(&doclist);
6633               generateError(pContext, "dump_doclist", "invalid segdir");
6634               return;
6635             }
6636             rc = SQLITE_OK;
6637           }
6638         }
6639       }
6640 
6641       sqlite3_reset(s);
6642     }
6643 
6644     if( rc==SQLITE_OK ){
6645       if( doclist.nData>0 ){
6646         createDoclistResult(pContext, doclist.pData, doclist.nData);
6647       }else{
6648         /* TODO(shess): This can happen if the term is not present, or
6649         ** if all instances of the term have been deleted and this is
6650         ** an all-index dump.  It may be interesting to distinguish
6651         ** these cases.
6652         */
6653         sqlite3_result_text(pContext, "", 0, SQLITE_STATIC);
6654       }
6655     }else if( rc==SQLITE_NOMEM ){
6656       /* Handle out-of-memory cases specially because if they are
6657       ** generated in fts2 code they may not be reflected in the db
6658       ** handle.
6659       */
6660       /* TODO(shess): Handle this more comprehensively.
6661       ** sqlite3ErrStr() has what I need, but is internal.
6662       */
6663       generateError(pContext, "dump_doclist", "out of memory");
6664     }else{
6665       generateError(pContext, "dump_doclist", NULL);
6666     }
6667 
6668     dataBufferDestroy(&doclist);
6669   }
6670 }
6671 #endif
6672 
6673 /*
6674 ** This routine implements the xFindFunction method for the FTS2
6675 ** virtual table.
6676 */
fulltextFindFunction(sqlite3_vtab * pVtab,int nArg,const char * zName,void (** pxFunc)(sqlite3_context *,int,sqlite3_value **),void ** ppArg)6677 static int fulltextFindFunction(
6678   sqlite3_vtab *pVtab,
6679   int nArg,
6680   const char *zName,
6681   void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
6682   void **ppArg
6683 ){
6684   if( strcmp(zName,"snippet")==0 ){
6685     *pxFunc = snippetFunc;
6686     return 1;
6687   }else if( strcmp(zName,"offsets")==0 ){
6688     *pxFunc = snippetOffsetsFunc;
6689     return 1;
6690   }else if( strcmp(zName,"optimize")==0 ){
6691     *pxFunc = optimizeFunc;
6692     return 1;
6693 #ifdef SQLITE_TEST
6694     /* NOTE(shess): These functions are present only for testing
6695     ** purposes.  No particular effort is made to optimize their
6696     ** execution or how they build their results.
6697     */
6698   }else if( strcmp(zName,"dump_terms")==0 ){
6699     /* fprintf(stderr, "Found dump_terms\n"); */
6700     *pxFunc = dumpTermsFunc;
6701     return 1;
6702   }else if( strcmp(zName,"dump_doclist")==0 ){
6703     /* fprintf(stderr, "Found dump_doclist\n"); */
6704     *pxFunc = dumpDoclistFunc;
6705     return 1;
6706 #endif
6707   }
6708   return 0;
6709 }
6710 
6711 /*
6712 ** Rename an fts2 table.
6713 */
fulltextRename(sqlite3_vtab * pVtab,const char * zName)6714 static int fulltextRename(
6715   sqlite3_vtab *pVtab,
6716   const char *zName
6717 ){
6718   fulltext_vtab *p = (fulltext_vtab *)pVtab;
6719   int rc = SQLITE_NOMEM;
6720   char *zSql = sqlite3_mprintf(
6721     "ALTER TABLE %Q.'%q_content'  RENAME TO '%q_content';"
6722     "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';"
6723     "ALTER TABLE %Q.'%q_segdir'   RENAME TO '%q_segdir';"
6724     , p->zDb, p->zName, zName
6725     , p->zDb, p->zName, zName
6726     , p->zDb, p->zName, zName
6727   );
6728   if( zSql ){
6729     rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
6730     sqlite3_free(zSql);
6731   }
6732   return rc;
6733 }
6734 
6735 static const sqlite3_module fts2Module = {
6736   /* iVersion      */ 0,
6737   /* xCreate       */ fulltextCreate,
6738   /* xConnect      */ fulltextConnect,
6739   /* xBestIndex    */ fulltextBestIndex,
6740   /* xDisconnect   */ fulltextDisconnect,
6741   /* xDestroy      */ fulltextDestroy,
6742   /* xOpen         */ fulltextOpen,
6743   /* xClose        */ fulltextClose,
6744   /* xFilter       */ fulltextFilter,
6745   /* xNext         */ fulltextNext,
6746   /* xEof          */ fulltextEof,
6747   /* xColumn       */ fulltextColumn,
6748   /* xRowid        */ fulltextRowid,
6749   /* xUpdate       */ fulltextUpdate,
6750   /* xBegin        */ fulltextBegin,
6751   /* xSync         */ fulltextSync,
6752   /* xCommit       */ fulltextCommit,
6753   /* xRollback     */ fulltextRollback,
6754   /* xFindFunction */ fulltextFindFunction,
6755   /* xRename */       fulltextRename,
6756 };
6757 
hashDestroy(void * p)6758 static void hashDestroy(void *p){
6759   fts2Hash *pHash = (fts2Hash *)p;
6760   sqlite3Fts2HashClear(pHash);
6761   sqlite3_free(pHash);
6762 }
6763 
6764 /*
6765 ** The fts2 built-in tokenizers - "simple" and "porter" - are implemented
6766 ** in files fts2_tokenizer1.c and fts2_porter.c respectively. The following
6767 ** two forward declarations are for functions declared in these files
6768 ** used to retrieve the respective implementations.
6769 **
6770 ** Calling sqlite3Fts2SimpleTokenizerModule() sets the value pointed
6771 ** to by the argument to point a the "simple" tokenizer implementation.
6772 ** Function ...PorterTokenizerModule() sets *pModule to point to the
6773 ** porter tokenizer/stemmer implementation.
6774 */
6775 void sqlite3Fts2SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
6776 void sqlite3Fts2PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
6777 void sqlite3Fts2IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
6778 
6779 int sqlite3Fts2InitHashTable(sqlite3 *, fts2Hash *, const char *);
6780 
6781 /*
6782 ** Initialise the fts2 extension. If this extension is built as part
6783 ** of the sqlite library, then this function is called directly by
6784 ** SQLite. If fts2 is built as a dynamically loadable extension, this
6785 ** function is called by the sqlite3_extension_init() entry point.
6786 */
sqlite3Fts2Init(sqlite3 * db)6787 int sqlite3Fts2Init(sqlite3 *db){
6788   int rc = SQLITE_OK;
6789   fts2Hash *pHash = 0;
6790   const sqlite3_tokenizer_module *pSimple = 0;
6791   const sqlite3_tokenizer_module *pPorter = 0;
6792   const sqlite3_tokenizer_module *pIcu = 0;
6793 
6794   sqlite3Fts2SimpleTokenizerModule(&pSimple);
6795   sqlite3Fts2PorterTokenizerModule(&pPorter);
6796 #ifdef SQLITE_ENABLE_ICU
6797   sqlite3Fts2IcuTokenizerModule(&pIcu);
6798 #endif
6799 
6800   /* Allocate and initialise the hash-table used to store tokenizers. */
6801   pHash = sqlite3_malloc(sizeof(fts2Hash));
6802   if( !pHash ){
6803     rc = SQLITE_NOMEM;
6804   }else{
6805     sqlite3Fts2HashInit(pHash, FTS2_HASH_STRING, 1);
6806   }
6807 
6808   /* Load the built-in tokenizers into the hash table */
6809   if( rc==SQLITE_OK ){
6810     if( sqlite3Fts2HashInsert(pHash, "simple", 7, (void *)pSimple)
6811      || sqlite3Fts2HashInsert(pHash, "porter", 7, (void *)pPorter)
6812      || (pIcu && sqlite3Fts2HashInsert(pHash, "icu", 4, (void *)pIcu))
6813     ){
6814       rc = SQLITE_NOMEM;
6815     }
6816   }
6817 
6818   /* Create the virtual table wrapper around the hash-table and overload
6819   ** the two scalar functions. If this is successful, register the
6820   ** module with sqlite.
6821   */
6822   if( SQLITE_OK==rc
6823    && SQLITE_OK==(rc = sqlite3Fts2InitHashTable(db, pHash, "fts2_tokenizer"))
6824    && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
6825    && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", -1))
6826    && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", -1))
6827 #ifdef SQLITE_TEST
6828    && SQLITE_OK==(rc = sqlite3_overload_function(db, "dump_terms", -1))
6829    && SQLITE_OK==(rc = sqlite3_overload_function(db, "dump_doclist", -1))
6830 #endif
6831   ){
6832     return sqlite3_create_module_v2(
6833         db, "fts2", &fts2Module, (void *)pHash, hashDestroy
6834     );
6835   }
6836 
6837   /* An error has occurred. Delete the hash table and return the error code. */
6838   assert( rc!=SQLITE_OK );
6839   if( pHash ){
6840     sqlite3Fts2HashClear(pHash);
6841     sqlite3_free(pHash);
6842   }
6843   return rc;
6844 }
6845 
6846 #if !SQLITE_CORE
sqlite3_extension_init(sqlite3 * db,char ** pzErrMsg,const sqlite3_api_routines * pApi)6847 int sqlite3_extension_init(
6848   sqlite3 *db,
6849   char **pzErrMsg,
6850   const sqlite3_api_routines *pApi
6851 ){
6852   SQLITE_EXTENSION_INIT2(pApi)
6853   return sqlite3Fts2Init(db);
6854 }
6855 #endif
6856 
6857 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS2) */
6858