Annotation of embedaddon/sqlite3/ext/fts3/fts3_write.c, revision 1.1

1.1     ! misho       1: /*
        !             2: ** 2009 Oct 23
        !             3: **
        !             4: ** The author disclaims copyright to this source code.  In place of
        !             5: ** a legal notice, here is a blessing:
        !             6: **
        !             7: **    May you do good and not evil.
        !             8: **    May you find forgiveness for yourself and forgive others.
        !             9: **    May you share freely, never taking more than you give.
        !            10: **
        !            11: ******************************************************************************
        !            12: **
        !            13: ** This file is part of the SQLite FTS3 extension module. Specifically,
        !            14: ** this file contains code to insert, update and delete rows from FTS3
        !            15: ** tables. It also contains code to merge FTS3 b-tree segments. Some
        !            16: ** of the sub-routines used to merge segments are also used by the query 
        !            17: ** code in fts3.c.
        !            18: */
        !            19: 
        !            20: #include "fts3Int.h"
        !            21: #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
        !            22: 
        !            23: #include <string.h>
        !            24: #include <assert.h>
        !            25: #include <stdlib.h>
        !            26: 
        !            27: /*
        !            28: ** When full-text index nodes are loaded from disk, the buffer that they
        !            29: ** are loaded into has the following number of bytes of padding at the end 
        !            30: ** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer
        !            31: ** of 920 bytes is allocated for it.
        !            32: **
        !            33: ** This means that if we have a pointer into a buffer containing node data,
        !            34: ** it is always safe to read up to two varints from it without risking an
        !            35: ** overread, even if the node data is corrupted.
        !            36: */
        !            37: #define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2)
        !            38: 
        !            39: /*
        !            40: ** Under certain circumstances, b-tree nodes (doclists) can be loaded into
        !            41: ** memory incrementally instead of all at once. This can be a big performance
        !            42: ** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext()
        !            43: ** method before retrieving all query results (as may happen, for example,
        !            44: ** if a query has a LIMIT clause).
        !            45: **
        !            46: ** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD 
        !            47: ** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes.
        !            48: ** The code is written so that the hard lower-limit for each of these values 
        !            49: ** is 1. Clearly such small values would be inefficient, but can be useful 
        !            50: ** for testing purposes.
        !            51: **
        !            52: ** If this module is built with SQLITE_TEST defined, these constants may
        !            53: ** be overridden at runtime for testing purposes. File fts3_test.c contains
        !            54: ** a Tcl interface to read and write the values.
        !            55: */
        !            56: #ifdef SQLITE_TEST
        !            57: int test_fts3_node_chunksize = (4*1024);
        !            58: int test_fts3_node_chunk_threshold = (4*1024)*4;
        !            59: # define FTS3_NODE_CHUNKSIZE       test_fts3_node_chunksize
        !            60: # define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold
        !            61: #else
        !            62: # define FTS3_NODE_CHUNKSIZE (4*1024) 
        !            63: # define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4)
        !            64: #endif
        !            65: 
        !            66: typedef struct PendingList PendingList;
        !            67: typedef struct SegmentNode SegmentNode;
        !            68: typedef struct SegmentWriter SegmentWriter;
        !            69: 
        !            70: /*
        !            71: ** An instance of the following data structure is used to build doclists
        !            72: ** incrementally. See function fts3PendingListAppend() for details.
        !            73: */
        !            74: struct PendingList {
        !            75:   int nData;
        !            76:   char *aData;
        !            77:   int nSpace;
        !            78:   sqlite3_int64 iLastDocid;
        !            79:   sqlite3_int64 iLastCol;
        !            80:   sqlite3_int64 iLastPos;
        !            81: };
        !            82: 
        !            83: 
        !            84: /*
        !            85: ** Each cursor has a (possibly empty) linked list of the following objects.
        !            86: */
        !            87: struct Fts3DeferredToken {
        !            88:   Fts3PhraseToken *pToken;        /* Pointer to corresponding expr token */
        !            89:   int iCol;                       /* Column token must occur in */
        !            90:   Fts3DeferredToken *pNext;       /* Next in list of deferred tokens */
        !            91:   PendingList *pList;             /* Doclist is assembled here */
        !            92: };
        !            93: 
        !            94: /*
        !            95: ** An instance of this structure is used to iterate through the terms on
        !            96: ** a contiguous set of segment b-tree leaf nodes. Although the details of
        !            97: ** this structure are only manipulated by code in this file, opaque handles
        !            98: ** of type Fts3SegReader* are also used by code in fts3.c to iterate through
        !            99: ** terms when querying the full-text index. See functions:
        !           100: **
        !           101: **   sqlite3Fts3SegReaderNew()
        !           102: **   sqlite3Fts3SegReaderFree()
        !           103: **   sqlite3Fts3SegReaderIterate()
        !           104: **
        !           105: ** Methods used to manipulate Fts3SegReader structures:
        !           106: **
        !           107: **   fts3SegReaderNext()
        !           108: **   fts3SegReaderFirstDocid()
        !           109: **   fts3SegReaderNextDocid()
        !           110: */
        !           111: struct Fts3SegReader {
        !           112:   int iIdx;                       /* Index within level, or 0x7FFFFFFF for PT */
        !           113: 
        !           114:   sqlite3_int64 iStartBlock;      /* Rowid of first leaf block to traverse */
        !           115:   sqlite3_int64 iLeafEndBlock;    /* Rowid of final leaf block to traverse */
        !           116:   sqlite3_int64 iEndBlock;        /* Rowid of final block in segment (or 0) */
        !           117:   sqlite3_int64 iCurrentBlock;    /* Current leaf block (or 0) */
        !           118: 
        !           119:   char *aNode;                    /* Pointer to node data (or NULL) */
        !           120:   int nNode;                      /* Size of buffer at aNode (or 0) */
        !           121:   int nPopulate;                  /* If >0, bytes of buffer aNode[] loaded */
        !           122:   sqlite3_blob *pBlob;            /* If not NULL, blob handle to read node */
        !           123: 
        !           124:   Fts3HashElem **ppNextElem;
        !           125: 
        !           126:   /* Variables set by fts3SegReaderNext(). These may be read directly
        !           127:   ** by the caller. They are valid from the time SegmentReaderNew() returns
        !           128:   ** until SegmentReaderNext() returns something other than SQLITE_OK
        !           129:   ** (i.e. SQLITE_DONE).
        !           130:   */
        !           131:   int nTerm;                      /* Number of bytes in current term */
        !           132:   char *zTerm;                    /* Pointer to current term */
        !           133:   int nTermAlloc;                 /* Allocated size of zTerm buffer */
        !           134:   char *aDoclist;                 /* Pointer to doclist of current entry */
        !           135:   int nDoclist;                   /* Size of doclist in current entry */
        !           136: 
        !           137:   /* The following variables are used by fts3SegReaderNextDocid() to iterate 
        !           138:   ** through the current doclist (aDoclist/nDoclist).
        !           139:   */
        !           140:   char *pOffsetList;
        !           141:   int nOffsetList;                /* For descending pending seg-readers only */
        !           142:   sqlite3_int64 iDocid;
        !           143: };
        !           144: 
        !           145: #define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0)
        !           146: #define fts3SegReaderIsRootOnly(p) ((p)->aNode==(char *)&(p)[1])
        !           147: 
        !           148: /*
        !           149: ** An instance of this structure is used to create a segment b-tree in the
        !           150: ** database. The internal details of this type are only accessed by the
        !           151: ** following functions:
        !           152: **
        !           153: **   fts3SegWriterAdd()
        !           154: **   fts3SegWriterFlush()
        !           155: **   fts3SegWriterFree()
        !           156: */
        !           157: struct SegmentWriter {
        !           158:   SegmentNode *pTree;             /* Pointer to interior tree structure */
        !           159:   sqlite3_int64 iFirst;           /* First slot in %_segments written */
        !           160:   sqlite3_int64 iFree;            /* Next free slot in %_segments */
        !           161:   char *zTerm;                    /* Pointer to previous term buffer */
        !           162:   int nTerm;                      /* Number of bytes in zTerm */
        !           163:   int nMalloc;                    /* Size of malloc'd buffer at zMalloc */
        !           164:   char *zMalloc;                  /* Malloc'd space (possibly) used for zTerm */
        !           165:   int nSize;                      /* Size of allocation at aData */
        !           166:   int nData;                      /* Bytes of data in aData */
        !           167:   char *aData;                    /* Pointer to block from malloc() */
        !           168: };
        !           169: 
        !           170: /*
        !           171: ** Type SegmentNode is used by the following three functions to create
        !           172: ** the interior part of the segment b+-tree structures (everything except
        !           173: ** the leaf nodes). These functions and type are only ever used by code
        !           174: ** within the fts3SegWriterXXX() family of functions described above.
        !           175: **
        !           176: **   fts3NodeAddTerm()
        !           177: **   fts3NodeWrite()
        !           178: **   fts3NodeFree()
        !           179: **
        !           180: ** When a b+tree is written to the database (either as a result of a merge
        !           181: ** or the pending-terms table being flushed), leaves are written into the 
        !           182: ** database file as soon as they are completely populated. The interior of
        !           183: ** the tree is assembled in memory and written out only once all leaves have
        !           184: ** been populated and stored. This is Ok, as the b+-tree fanout is usually
        !           185: ** very large, meaning that the interior of the tree consumes relatively 
        !           186: ** little memory.
        !           187: */
        !           188: struct SegmentNode {
        !           189:   SegmentNode *pParent;           /* Parent node (or NULL for root node) */
        !           190:   SegmentNode *pRight;            /* Pointer to right-sibling */
        !           191:   SegmentNode *pLeftmost;         /* Pointer to left-most node of this depth */
        !           192:   int nEntry;                     /* Number of terms written to node so far */
        !           193:   char *zTerm;                    /* Pointer to previous term buffer */
        !           194:   int nTerm;                      /* Number of bytes in zTerm */
        !           195:   int nMalloc;                    /* Size of malloc'd buffer at zMalloc */
        !           196:   char *zMalloc;                  /* Malloc'd space (possibly) used for zTerm */
        !           197:   int nData;                      /* Bytes of valid data so far */
        !           198:   char *aData;                    /* Node data */
        !           199: };
        !           200: 
        !           201: /*
        !           202: ** Valid values for the second argument to fts3SqlStmt().
        !           203: */
        !           204: #define SQL_DELETE_CONTENT             0
        !           205: #define SQL_IS_EMPTY                   1
        !           206: #define SQL_DELETE_ALL_CONTENT         2 
        !           207: #define SQL_DELETE_ALL_SEGMENTS        3
        !           208: #define SQL_DELETE_ALL_SEGDIR          4
        !           209: #define SQL_DELETE_ALL_DOCSIZE         5
        !           210: #define SQL_DELETE_ALL_STAT            6
        !           211: #define SQL_SELECT_CONTENT_BY_ROWID    7
        !           212: #define SQL_NEXT_SEGMENT_INDEX         8
        !           213: #define SQL_INSERT_SEGMENTS            9
        !           214: #define SQL_NEXT_SEGMENTS_ID          10
        !           215: #define SQL_INSERT_SEGDIR             11
        !           216: #define SQL_SELECT_LEVEL              12
        !           217: #define SQL_SELECT_LEVEL_RANGE        13
        !           218: #define SQL_SELECT_LEVEL_COUNT        14
        !           219: #define SQL_SELECT_SEGDIR_MAX_LEVEL   15
        !           220: #define SQL_DELETE_SEGDIR_LEVEL       16
        !           221: #define SQL_DELETE_SEGMENTS_RANGE     17
        !           222: #define SQL_CONTENT_INSERT            18
        !           223: #define SQL_DELETE_DOCSIZE            19
        !           224: #define SQL_REPLACE_DOCSIZE           20
        !           225: #define SQL_SELECT_DOCSIZE            21
        !           226: #define SQL_SELECT_DOCTOTAL           22
        !           227: #define SQL_REPLACE_DOCTOTAL          23
        !           228: 
        !           229: #define SQL_SELECT_ALL_PREFIX_LEVEL   24
        !           230: #define SQL_DELETE_ALL_TERMS_SEGDIR   25
        !           231: 
        !           232: #define SQL_DELETE_SEGDIR_RANGE       26
        !           233: 
        !           234: /*
        !           235: ** This function is used to obtain an SQLite prepared statement handle
        !           236: ** for the statement identified by the second argument. If successful,
        !           237: ** *pp is set to the requested statement handle and SQLITE_OK returned.
        !           238: ** Otherwise, an SQLite error code is returned and *pp is set to 0.
        !           239: **
        !           240: ** If argument apVal is not NULL, then it must point to an array with
        !           241: ** at least as many entries as the requested statement has bound 
        !           242: ** parameters. The values are bound to the statements parameters before
        !           243: ** returning.
        !           244: */
        !           245: static int fts3SqlStmt(
        !           246:   Fts3Table *p,                   /* Virtual table handle */
        !           247:   int eStmt,                      /* One of the SQL_XXX constants above */
        !           248:   sqlite3_stmt **pp,              /* OUT: Statement handle */
        !           249:   sqlite3_value **apVal           /* Values to bind to statement */
        !           250: ){
        !           251:   const char *azSql[] = {
        !           252: /* 0  */  "DELETE FROM %Q.'%q_content' WHERE rowid = ?",
        !           253: /* 1  */  "SELECT NOT EXISTS(SELECT docid FROM %Q.'%q_content' WHERE rowid!=?)",
        !           254: /* 2  */  "DELETE FROM %Q.'%q_content'",
        !           255: /* 3  */  "DELETE FROM %Q.'%q_segments'",
        !           256: /* 4  */  "DELETE FROM %Q.'%q_segdir'",
        !           257: /* 5  */  "DELETE FROM %Q.'%q_docsize'",
        !           258: /* 6  */  "DELETE FROM %Q.'%q_stat'",
        !           259: /* 7  */  "SELECT %s WHERE rowid=?",
        !           260: /* 8  */  "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1",
        !           261: /* 9  */  "INSERT INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)",
        !           262: /* 10 */  "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)",
        !           263: /* 11 */  "INSERT INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)",
        !           264: 
        !           265:           /* Return segments in order from oldest to newest.*/ 
        !           266: /* 12 */  "SELECT idx, start_block, leaves_end_block, end_block, root "
        !           267:             "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC",
        !           268: /* 13 */  "SELECT idx, start_block, leaves_end_block, end_block, root "
        !           269:             "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?"
        !           270:             "ORDER BY level DESC, idx ASC",
        !           271: 
        !           272: /* 14 */  "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?",
        !           273: /* 15 */  "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
        !           274: 
        !           275: /* 16 */  "DELETE FROM %Q.'%q_segdir' WHERE level = ?",
        !           276: /* 17 */  "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?",
        !           277: /* 18 */  "INSERT INTO %Q.'%q_content' VALUES(%s)",
        !           278: /* 19 */  "DELETE FROM %Q.'%q_docsize' WHERE docid = ?",
        !           279: /* 20 */  "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)",
        !           280: /* 21 */  "SELECT size FROM %Q.'%q_docsize' WHERE docid=?",
        !           281: /* 22 */  "SELECT value FROM %Q.'%q_stat' WHERE id=0",
        !           282: /* 23 */  "REPLACE INTO %Q.'%q_stat' VALUES(0,?)",
        !           283: /* 24 */  "",
        !           284: /* 25 */  "",
        !           285: 
        !           286: /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
        !           287: 
        !           288:   };
        !           289:   int rc = SQLITE_OK;
        !           290:   sqlite3_stmt *pStmt;
        !           291: 
        !           292:   assert( SizeofArray(azSql)==SizeofArray(p->aStmt) );
        !           293:   assert( eStmt<SizeofArray(azSql) && eStmt>=0 );
        !           294:   
        !           295:   pStmt = p->aStmt[eStmt];
        !           296:   if( !pStmt ){
        !           297:     char *zSql;
        !           298:     if( eStmt==SQL_CONTENT_INSERT ){
        !           299:       zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
        !           300:     }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
        !           301:       zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
        !           302:     }else{
        !           303:       zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
        !           304:     }
        !           305:     if( !zSql ){
        !           306:       rc = SQLITE_NOMEM;
        !           307:     }else{
        !           308:       rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, NULL);
        !           309:       sqlite3_free(zSql);
        !           310:       assert( rc==SQLITE_OK || pStmt==0 );
        !           311:       p->aStmt[eStmt] = pStmt;
        !           312:     }
        !           313:   }
        !           314:   if( apVal ){
        !           315:     int i;
        !           316:     int nParam = sqlite3_bind_parameter_count(pStmt);
        !           317:     for(i=0; rc==SQLITE_OK && i<nParam; i++){
        !           318:       rc = sqlite3_bind_value(pStmt, i+1, apVal[i]);
        !           319:     }
        !           320:   }
        !           321:   *pp = pStmt;
        !           322:   return rc;
        !           323: }
        !           324: 
        !           325: static int fts3SelectDocsize(
        !           326:   Fts3Table *pTab,                /* FTS3 table handle */
        !           327:   int eStmt,                      /* Either SQL_SELECT_DOCSIZE or DOCTOTAL */
        !           328:   sqlite3_int64 iDocid,           /* Docid to bind for SQL_SELECT_DOCSIZE */
        !           329:   sqlite3_stmt **ppStmt           /* OUT: Statement handle */
        !           330: ){
        !           331:   sqlite3_stmt *pStmt = 0;        /* Statement requested from fts3SqlStmt() */
        !           332:   int rc;                         /* Return code */
        !           333: 
        !           334:   assert( eStmt==SQL_SELECT_DOCSIZE || eStmt==SQL_SELECT_DOCTOTAL );
        !           335: 
        !           336:   rc = fts3SqlStmt(pTab, eStmt, &pStmt, 0);
        !           337:   if( rc==SQLITE_OK ){
        !           338:     if( eStmt==SQL_SELECT_DOCSIZE ){
        !           339:       sqlite3_bind_int64(pStmt, 1, iDocid);
        !           340:     }
        !           341:     rc = sqlite3_step(pStmt);
        !           342:     if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
        !           343:       rc = sqlite3_reset(pStmt);
        !           344:       if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB;
        !           345:       pStmt = 0;
        !           346:     }else{
        !           347:       rc = SQLITE_OK;
        !           348:     }
        !           349:   }
        !           350: 
        !           351:   *ppStmt = pStmt;
        !           352:   return rc;
        !           353: }
        !           354: 
        !           355: int sqlite3Fts3SelectDoctotal(
        !           356:   Fts3Table *pTab,                /* Fts3 table handle */
        !           357:   sqlite3_stmt **ppStmt           /* OUT: Statement handle */
        !           358: ){
        !           359:   return fts3SelectDocsize(pTab, SQL_SELECT_DOCTOTAL, 0, ppStmt);
        !           360: }
        !           361: 
        !           362: int sqlite3Fts3SelectDocsize(
        !           363:   Fts3Table *pTab,                /* Fts3 table handle */
        !           364:   sqlite3_int64 iDocid,           /* Docid to read size data for */
        !           365:   sqlite3_stmt **ppStmt           /* OUT: Statement handle */
        !           366: ){
        !           367:   return fts3SelectDocsize(pTab, SQL_SELECT_DOCSIZE, iDocid, ppStmt);
        !           368: }
        !           369: 
        !           370: /*
        !           371: ** Similar to fts3SqlStmt(). Except, after binding the parameters in
        !           372: ** array apVal[] to the SQL statement identified by eStmt, the statement
        !           373: ** is executed.
        !           374: **
        !           375: ** Returns SQLITE_OK if the statement is successfully executed, or an
        !           376: ** SQLite error code otherwise.
        !           377: */
        !           378: static void fts3SqlExec(
        !           379:   int *pRC,                /* Result code */
        !           380:   Fts3Table *p,            /* The FTS3 table */
        !           381:   int eStmt,               /* Index of statement to evaluate */
        !           382:   sqlite3_value **apVal    /* Parameters to bind */
        !           383: ){
        !           384:   sqlite3_stmt *pStmt;
        !           385:   int rc;
        !           386:   if( *pRC ) return;
        !           387:   rc = fts3SqlStmt(p, eStmt, &pStmt, apVal); 
        !           388:   if( rc==SQLITE_OK ){
        !           389:     sqlite3_step(pStmt);
        !           390:     rc = sqlite3_reset(pStmt);
        !           391:   }
        !           392:   *pRC = rc;
        !           393: }
        !           394: 
        !           395: 
        !           396: /*
        !           397: ** This function ensures that the caller has obtained a shared-cache
        !           398: ** table-lock on the %_content table. This is required before reading
        !           399: ** data from the fts3 table. If this lock is not acquired first, then
        !           400: ** the caller may end up holding read-locks on the %_segments and %_segdir
        !           401: ** tables, but no read-lock on the %_content table. If this happens 
        !           402: ** a second connection will be able to write to the fts3 table, but
        !           403: ** attempting to commit those writes might return SQLITE_LOCKED or
        !           404: ** SQLITE_LOCKED_SHAREDCACHE (because the commit attempts to obtain 
        !           405: ** write-locks on the %_segments and %_segdir ** tables). 
        !           406: **
        !           407: ** We try to avoid this because if FTS3 returns any error when committing
        !           408: ** a transaction, the whole transaction will be rolled back. And this is
        !           409: ** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
        !           410: ** still happen if the user reads data directly from the %_segments or
        !           411: ** %_segdir tables instead of going through FTS3 though.
        !           412: **
        !           413: ** This reasoning does not apply to a content=xxx table.
        !           414: */
        !           415: int sqlite3Fts3ReadLock(Fts3Table *p){
        !           416:   int rc;                         /* Return code */
        !           417:   sqlite3_stmt *pStmt;            /* Statement used to obtain lock */
        !           418: 
        !           419:   if( p->zContentTbl==0 ){
        !           420:     rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
        !           421:     if( rc==SQLITE_OK ){
        !           422:       sqlite3_bind_null(pStmt, 1);
        !           423:       sqlite3_step(pStmt);
        !           424:       rc = sqlite3_reset(pStmt);
        !           425:     }
        !           426:   }else{
        !           427:     rc = SQLITE_OK;
        !           428:   }
        !           429: 
        !           430:   return rc;
        !           431: }
        !           432: 
        !           433: /*
        !           434: ** Set *ppStmt to a statement handle that may be used to iterate through
        !           435: ** all rows in the %_segdir table, from oldest to newest. If successful,
        !           436: ** return SQLITE_OK. If an error occurs while preparing the statement, 
        !           437: ** return an SQLite error code.
        !           438: **
        !           439: ** There is only ever one instance of this SQL statement compiled for
        !           440: ** each FTS3 table.
        !           441: **
        !           442: ** The statement returns the following columns from the %_segdir table:
        !           443: **
        !           444: **   0: idx
        !           445: **   1: start_block
        !           446: **   2: leaves_end_block
        !           447: **   3: end_block
        !           448: **   4: root
        !           449: */
        !           450: int sqlite3Fts3AllSegdirs(
        !           451:   Fts3Table *p,                   /* FTS3 table */
        !           452:   int iIndex,                     /* Index for p->aIndex[] */
        !           453:   int iLevel,                     /* Level to select */
        !           454:   sqlite3_stmt **ppStmt           /* OUT: Compiled statement */
        !           455: ){
        !           456:   int rc;
        !           457:   sqlite3_stmt *pStmt = 0;
        !           458: 
        !           459:   assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 );
        !           460:   assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
        !           461:   assert( iIndex>=0 && iIndex<p->nIndex );
        !           462: 
        !           463:   if( iLevel<0 ){
        !           464:     /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */
        !           465:     rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0);
        !           466:     if( rc==SQLITE_OK ){ 
        !           467:       sqlite3_bind_int(pStmt, 1, iIndex*FTS3_SEGDIR_MAXLEVEL);
        !           468:       sqlite3_bind_int(pStmt, 2, (iIndex+1)*FTS3_SEGDIR_MAXLEVEL-1);
        !           469:     }
        !           470:   }else{
        !           471:     /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */
        !           472:     rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0);
        !           473:     if( rc==SQLITE_OK ){ 
        !           474:       sqlite3_bind_int(pStmt, 1, iLevel+iIndex*FTS3_SEGDIR_MAXLEVEL);
        !           475:     }
        !           476:   }
        !           477:   *ppStmt = pStmt;
        !           478:   return rc;
        !           479: }
        !           480: 
        !           481: 
        !           482: /*
        !           483: ** Append a single varint to a PendingList buffer. SQLITE_OK is returned
        !           484: ** if successful, or an SQLite error code otherwise.
        !           485: **
        !           486: ** This function also serves to allocate the PendingList structure itself.
        !           487: ** For example, to create a new PendingList structure containing two
        !           488: ** varints:
        !           489: **
        !           490: **   PendingList *p = 0;
        !           491: **   fts3PendingListAppendVarint(&p, 1);
        !           492: **   fts3PendingListAppendVarint(&p, 2);
        !           493: */
        !           494: static int fts3PendingListAppendVarint(
        !           495:   PendingList **pp,               /* IN/OUT: Pointer to PendingList struct */
        !           496:   sqlite3_int64 i                 /* Value to append to data */
        !           497: ){
        !           498:   PendingList *p = *pp;
        !           499: 
        !           500:   /* Allocate or grow the PendingList as required. */
        !           501:   if( !p ){
        !           502:     p = sqlite3_malloc(sizeof(*p) + 100);
        !           503:     if( !p ){
        !           504:       return SQLITE_NOMEM;
        !           505:     }
        !           506:     p->nSpace = 100;
        !           507:     p->aData = (char *)&p[1];
        !           508:     p->nData = 0;
        !           509:   }
        !           510:   else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
        !           511:     int nNew = p->nSpace * 2;
        !           512:     p = sqlite3_realloc(p, sizeof(*p) + nNew);
        !           513:     if( !p ){
        !           514:       sqlite3_free(*pp);
        !           515:       *pp = 0;
        !           516:       return SQLITE_NOMEM;
        !           517:     }
        !           518:     p->nSpace = nNew;
        !           519:     p->aData = (char *)&p[1];
        !           520:   }
        !           521: 
        !           522:   /* Append the new serialized varint to the end of the list. */
        !           523:   p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i);
        !           524:   p->aData[p->nData] = '\0';
        !           525:   *pp = p;
        !           526:   return SQLITE_OK;
        !           527: }
        !           528: 
        !           529: /*
        !           530: ** Add a docid/column/position entry to a PendingList structure. Non-zero
        !           531: ** is returned if the structure is sqlite3_realloced as part of adding
        !           532: ** the entry. Otherwise, zero.
        !           533: **
        !           534: ** If an OOM error occurs, *pRc is set to SQLITE_NOMEM before returning.
        !           535: ** Zero is always returned in this case. Otherwise, if no OOM error occurs,
        !           536: ** it is set to SQLITE_OK.
        !           537: */
        !           538: static int fts3PendingListAppend(
        !           539:   PendingList **pp,               /* IN/OUT: PendingList structure */
        !           540:   sqlite3_int64 iDocid,           /* Docid for entry to add */
        !           541:   sqlite3_int64 iCol,             /* Column for entry to add */
        !           542:   sqlite3_int64 iPos,             /* Position of term for entry to add */
        !           543:   int *pRc                        /* OUT: Return code */
        !           544: ){
        !           545:   PendingList *p = *pp;
        !           546:   int rc = SQLITE_OK;
        !           547: 
        !           548:   assert( !p || p->iLastDocid<=iDocid );
        !           549: 
        !           550:   if( !p || p->iLastDocid!=iDocid ){
        !           551:     sqlite3_int64 iDelta = iDocid - (p ? p->iLastDocid : 0);
        !           552:     if( p ){
        !           553:       assert( p->nData<p->nSpace );
        !           554:       assert( p->aData[p->nData]==0 );
        !           555:       p->nData++;
        !           556:     }
        !           557:     if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iDelta)) ){
        !           558:       goto pendinglistappend_out;
        !           559:     }
        !           560:     p->iLastCol = -1;
        !           561:     p->iLastPos = 0;
        !           562:     p->iLastDocid = iDocid;
        !           563:   }
        !           564:   if( iCol>0 && p->iLastCol!=iCol ){
        !           565:     if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, 1))
        !           566:      || SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iCol))
        !           567:     ){
        !           568:       goto pendinglistappend_out;
        !           569:     }
        !           570:     p->iLastCol = iCol;
        !           571:     p->iLastPos = 0;
        !           572:   }
        !           573:   if( iCol>=0 ){
        !           574:     assert( iPos>p->iLastPos || (iPos==0 && p->iLastPos==0) );
        !           575:     rc = fts3PendingListAppendVarint(&p, 2+iPos-p->iLastPos);
        !           576:     if( rc==SQLITE_OK ){
        !           577:       p->iLastPos = iPos;
        !           578:     }
        !           579:   }
        !           580: 
        !           581:  pendinglistappend_out:
        !           582:   *pRc = rc;
        !           583:   if( p!=*pp ){
        !           584:     *pp = p;
        !           585:     return 1;
        !           586:   }
        !           587:   return 0;
        !           588: }
        !           589: 
        !           590: /*
        !           591: ** Free a PendingList object allocated by fts3PendingListAppend().
        !           592: */
        !           593: static void fts3PendingListDelete(PendingList *pList){
        !           594:   sqlite3_free(pList);
        !           595: }
        !           596: 
        !           597: /*
        !           598: ** Add an entry to one of the pending-terms hash tables.
        !           599: */
        !           600: static int fts3PendingTermsAddOne(
        !           601:   Fts3Table *p,
        !           602:   int iCol,
        !           603:   int iPos,
        !           604:   Fts3Hash *pHash,                /* Pending terms hash table to add entry to */
        !           605:   const char *zToken,
        !           606:   int nToken
        !           607: ){
        !           608:   PendingList *pList;
        !           609:   int rc = SQLITE_OK;
        !           610: 
        !           611:   pList = (PendingList *)fts3HashFind(pHash, zToken, nToken);
        !           612:   if( pList ){
        !           613:     p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem));
        !           614:   }
        !           615:   if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){
        !           616:     if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){
        !           617:       /* Malloc failed while inserting the new entry. This can only 
        !           618:       ** happen if there was no previous entry for this token.
        !           619:       */
        !           620:       assert( 0==fts3HashFind(pHash, zToken, nToken) );
        !           621:       sqlite3_free(pList);
        !           622:       rc = SQLITE_NOMEM;
        !           623:     }
        !           624:   }
        !           625:   if( rc==SQLITE_OK ){
        !           626:     p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem));
        !           627:   }
        !           628:   return rc;
        !           629: }
        !           630: 
        !           631: /*
        !           632: ** Tokenize the nul-terminated string zText and add all tokens to the
        !           633: ** pending-terms hash-table. The docid used is that currently stored in
        !           634: ** p->iPrevDocid, and the column is specified by argument iCol.
        !           635: **
        !           636: ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
        !           637: */
        !           638: static int fts3PendingTermsAdd(
        !           639:   Fts3Table *p,                   /* Table into which text will be inserted */
        !           640:   const char *zText,              /* Text of document to be inserted */
        !           641:   int iCol,                       /* Column into which text is being inserted */
        !           642:   u32 *pnWord                     /* OUT: Number of tokens inserted */
        !           643: ){
        !           644:   int rc;
        !           645:   int iStart;
        !           646:   int iEnd;
        !           647:   int iPos;
        !           648:   int nWord = 0;
        !           649: 
        !           650:   char const *zToken;
        !           651:   int nToken;
        !           652: 
        !           653:   sqlite3_tokenizer *pTokenizer = p->pTokenizer;
        !           654:   sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
        !           655:   sqlite3_tokenizer_cursor *pCsr;
        !           656:   int (*xNext)(sqlite3_tokenizer_cursor *pCursor,
        !           657:       const char**,int*,int*,int*,int*);
        !           658: 
        !           659:   assert( pTokenizer && pModule );
        !           660: 
        !           661:   /* If the user has inserted a NULL value, this function may be called with
        !           662:   ** zText==0. In this case, add zero token entries to the hash table and 
        !           663:   ** return early. */
        !           664:   if( zText==0 ){
        !           665:     *pnWord = 0;
        !           666:     return SQLITE_OK;
        !           667:   }
        !           668: 
        !           669:   rc = pModule->xOpen(pTokenizer, zText, -1, &pCsr);
        !           670:   if( rc!=SQLITE_OK ){
        !           671:     return rc;
        !           672:   }
        !           673:   pCsr->pTokenizer = pTokenizer;
        !           674: 
        !           675:   xNext = pModule->xNext;
        !           676:   while( SQLITE_OK==rc
        !           677:       && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos))
        !           678:   ){
        !           679:     int i;
        !           680:     if( iPos>=nWord ) nWord = iPos+1;
        !           681: 
        !           682:     /* Positions cannot be negative; we use -1 as a terminator internally.
        !           683:     ** Tokens must have a non-zero length.
        !           684:     */
        !           685:     if( iPos<0 || !zToken || nToken<=0 ){
        !           686:       rc = SQLITE_ERROR;
        !           687:       break;
        !           688:     }
        !           689: 
        !           690:     /* Add the term to the terms index */
        !           691:     rc = fts3PendingTermsAddOne(
        !           692:         p, iCol, iPos, &p->aIndex[0].hPending, zToken, nToken
        !           693:     );
        !           694:     
        !           695:     /* Add the term to each of the prefix indexes that it is not too 
        !           696:     ** short for. */
        !           697:     for(i=1; rc==SQLITE_OK && i<p->nIndex; i++){
        !           698:       struct Fts3Index *pIndex = &p->aIndex[i];
        !           699:       if( nToken<pIndex->nPrefix ) continue;
        !           700:       rc = fts3PendingTermsAddOne(
        !           701:           p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix
        !           702:       );
        !           703:     }
        !           704:   }
        !           705: 
        !           706:   pModule->xClose(pCsr);
        !           707:   *pnWord = nWord;
        !           708:   return (rc==SQLITE_DONE ? SQLITE_OK : rc);
        !           709: }
        !           710: 
        !           711: /* 
        !           712: ** Calling this function indicates that subsequent calls to 
        !           713: ** fts3PendingTermsAdd() are to add term/position-list pairs for the
        !           714: ** contents of the document with docid iDocid.
        !           715: */
        !           716: static int fts3PendingTermsDocid(Fts3Table *p, sqlite_int64 iDocid){
        !           717:   /* TODO(shess) Explore whether partially flushing the buffer on
        !           718:   ** forced-flush would provide better performance.  I suspect that if
        !           719:   ** we ordered the doclists by size and flushed the largest until the
        !           720:   ** buffer was half empty, that would let the less frequent terms
        !           721:   ** generate longer doclists.
        !           722:   */
        !           723:   if( iDocid<=p->iPrevDocid || p->nPendingData>p->nMaxPendingData ){
        !           724:     int rc = sqlite3Fts3PendingTermsFlush(p);
        !           725:     if( rc!=SQLITE_OK ) return rc;
        !           726:   }
        !           727:   p->iPrevDocid = iDocid;
        !           728:   return SQLITE_OK;
        !           729: }
        !           730: 
        !           731: /*
        !           732: ** Discard the contents of the pending-terms hash tables. 
        !           733: */
        !           734: void sqlite3Fts3PendingTermsClear(Fts3Table *p){
        !           735:   int i;
        !           736:   for(i=0; i<p->nIndex; i++){
        !           737:     Fts3HashElem *pElem;
        !           738:     Fts3Hash *pHash = &p->aIndex[i].hPending;
        !           739:     for(pElem=fts3HashFirst(pHash); pElem; pElem=fts3HashNext(pElem)){
        !           740:       PendingList *pList = (PendingList *)fts3HashData(pElem);
        !           741:       fts3PendingListDelete(pList);
        !           742:     }
        !           743:     fts3HashClear(pHash);
        !           744:   }
        !           745:   p->nPendingData = 0;
        !           746: }
        !           747: 
        !           748: /*
        !           749: ** This function is called by the xUpdate() method as part of an INSERT
        !           750: ** operation. It adds entries for each term in the new record to the
        !           751: ** pendingTerms hash table.
        !           752: **
        !           753: ** Argument apVal is the same as the similarly named argument passed to
        !           754: ** fts3InsertData(). Parameter iDocid is the docid of the new row.
        !           755: */
        !           756: static int fts3InsertTerms(Fts3Table *p, sqlite3_value **apVal, u32 *aSz){
        !           757:   int i;                          /* Iterator variable */
        !           758:   for(i=2; i<p->nColumn+2; i++){
        !           759:     const char *zText = (const char *)sqlite3_value_text(apVal[i]);
        !           760:     int rc = fts3PendingTermsAdd(p, zText, i-2, &aSz[i-2]);
        !           761:     if( rc!=SQLITE_OK ){
        !           762:       return rc;
        !           763:     }
        !           764:     aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
        !           765:   }
        !           766:   return SQLITE_OK;
        !           767: }
        !           768: 
        !           769: /*
        !           770: ** This function is called by the xUpdate() method for an INSERT operation.
        !           771: ** The apVal parameter is passed a copy of the apVal argument passed by
        !           772: ** SQLite to the xUpdate() method. i.e:
        !           773: **
        !           774: **   apVal[0]                Not used for INSERT.
        !           775: **   apVal[1]                rowid
        !           776: **   apVal[2]                Left-most user-defined column
        !           777: **   ...
        !           778: **   apVal[p->nColumn+1]     Right-most user-defined column
        !           779: **   apVal[p->nColumn+2]     Hidden column with same name as table
        !           780: **   apVal[p->nColumn+3]     Hidden "docid" column (alias for rowid)
        !           781: */
        !           782: static int fts3InsertData(
        !           783:   Fts3Table *p,                   /* Full-text table */
        !           784:   sqlite3_value **apVal,          /* Array of values to insert */
        !           785:   sqlite3_int64 *piDocid          /* OUT: Docid for row just inserted */
        !           786: ){
        !           787:   int rc;                         /* Return code */
        !           788:   sqlite3_stmt *pContentInsert;   /* INSERT INTO %_content VALUES(...) */
        !           789: 
        !           790:   if( p->zContentTbl ){
        !           791:     sqlite3_value *pRowid = apVal[p->nColumn+3];
        !           792:     if( sqlite3_value_type(pRowid)==SQLITE_NULL ){
        !           793:       pRowid = apVal[1];
        !           794:     }
        !           795:     if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){
        !           796:       return SQLITE_CONSTRAINT;
        !           797:     }
        !           798:     *piDocid = sqlite3_value_int64(pRowid);
        !           799:     return SQLITE_OK;
        !           800:   }
        !           801: 
        !           802:   /* Locate the statement handle used to insert data into the %_content
        !           803:   ** table. The SQL for this statement is:
        !           804:   **
        !           805:   **   INSERT INTO %_content VALUES(?, ?, ?, ...)
        !           806:   **
        !           807:   ** The statement features N '?' variables, where N is the number of user
        !           808:   ** defined columns in the FTS3 table, plus one for the docid field.
        !           809:   */
        !           810:   rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]);
        !           811:   if( rc!=SQLITE_OK ){
        !           812:     return rc;
        !           813:   }
        !           814: 
        !           815:   /* There is a quirk here. The users INSERT statement may have specified
        !           816:   ** a value for the "rowid" field, for the "docid" field, or for both.
        !           817:   ** Which is a problem, since "rowid" and "docid" are aliases for the
        !           818:   ** same value. For example:
        !           819:   **
        !           820:   **   INSERT INTO fts3tbl(rowid, docid) VALUES(1, 2);
        !           821:   **
        !           822:   ** In FTS3, this is an error. It is an error to specify non-NULL values
        !           823:   ** for both docid and some other rowid alias.
        !           824:   */
        !           825:   if( SQLITE_NULL!=sqlite3_value_type(apVal[3+p->nColumn]) ){
        !           826:     if( SQLITE_NULL==sqlite3_value_type(apVal[0])
        !           827:      && SQLITE_NULL!=sqlite3_value_type(apVal[1])
        !           828:     ){
        !           829:       /* A rowid/docid conflict. */
        !           830:       return SQLITE_ERROR;
        !           831:     }
        !           832:     rc = sqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]);
        !           833:     if( rc!=SQLITE_OK ) return rc;
        !           834:   }
        !           835: 
        !           836:   /* Execute the statement to insert the record. Set *piDocid to the 
        !           837:   ** new docid value. 
        !           838:   */
        !           839:   sqlite3_step(pContentInsert);
        !           840:   rc = sqlite3_reset(pContentInsert);
        !           841: 
        !           842:   *piDocid = sqlite3_last_insert_rowid(p->db);
        !           843:   return rc;
        !           844: }
        !           845: 
        !           846: 
        !           847: 
        !           848: /*
        !           849: ** Remove all data from the FTS3 table. Clear the hash table containing
        !           850: ** pending terms.
        !           851: */
        !           852: static int fts3DeleteAll(Fts3Table *p, int bContent){
        !           853:   int rc = SQLITE_OK;             /* Return code */
        !           854: 
        !           855:   /* Discard the contents of the pending-terms hash table. */
        !           856:   sqlite3Fts3PendingTermsClear(p);
        !           857: 
        !           858:   /* Delete everything from the shadow tables. Except, leave %_content as
        !           859:   ** is if bContent is false.  */
        !           860:   assert( p->zContentTbl==0 || bContent==0 );
        !           861:   if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
        !           862:   fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0);
        !           863:   fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0);
        !           864:   if( p->bHasDocsize ){
        !           865:     fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0);
        !           866:   }
        !           867:   if( p->bHasStat ){
        !           868:     fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0);
        !           869:   }
        !           870:   return rc;
        !           871: }
        !           872: 
        !           873: /*
        !           874: ** The first element in the apVal[] array is assumed to contain the docid
        !           875: ** (an integer) of a row about to be deleted. Remove all terms from the
        !           876: ** full-text index.
        !           877: */
        !           878: static void fts3DeleteTerms( 
        !           879:   int *pRC,               /* Result code */
        !           880:   Fts3Table *p,           /* The FTS table to delete from */
        !           881:   sqlite3_value *pRowid,  /* The docid to be deleted */
        !           882:   u32 *aSz                /* Sizes of deleted document written here */
        !           883: ){
        !           884:   int rc;
        !           885:   sqlite3_stmt *pSelect;
        !           886: 
        !           887:   if( *pRC ) return;
        !           888:   rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
        !           889:   if( rc==SQLITE_OK ){
        !           890:     if( SQLITE_ROW==sqlite3_step(pSelect) ){
        !           891:       int i;
        !           892:       for(i=1; i<=p->nColumn; i++){
        !           893:         const char *zText = (const char *)sqlite3_column_text(pSelect, i);
        !           894:         rc = fts3PendingTermsAdd(p, zText, -1, &aSz[i-1]);
        !           895:         if( rc!=SQLITE_OK ){
        !           896:           sqlite3_reset(pSelect);
        !           897:           *pRC = rc;
        !           898:           return;
        !           899:         }
        !           900:         aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
        !           901:       }
        !           902:     }
        !           903:     rc = sqlite3_reset(pSelect);
        !           904:   }else{
        !           905:     sqlite3_reset(pSelect);
        !           906:   }
        !           907:   *pRC = rc;
        !           908: }
        !           909: 
        !           910: /*
        !           911: ** Forward declaration to account for the circular dependency between
        !           912: ** functions fts3SegmentMerge() and fts3AllocateSegdirIdx().
        !           913: */
        !           914: static int fts3SegmentMerge(Fts3Table *, int, int);
        !           915: 
        !           916: /* 
        !           917: ** This function allocates a new level iLevel index in the segdir table.
        !           918: ** Usually, indexes are allocated within a level sequentially starting
        !           919: ** with 0, so the allocated index is one greater than the value returned
        !           920: ** by:
        !           921: **
        !           922: **   SELECT max(idx) FROM %_segdir WHERE level = :iLevel
        !           923: **
        !           924: ** However, if there are already FTS3_MERGE_COUNT indexes at the requested
        !           925: ** level, they are merged into a single level (iLevel+1) segment and the 
        !           926: ** allocated index is 0.
        !           927: **
        !           928: ** If successful, *piIdx is set to the allocated index slot and SQLITE_OK
        !           929: ** returned. Otherwise, an SQLite error code is returned.
        !           930: */
        !           931: static int fts3AllocateSegdirIdx(
        !           932:   Fts3Table *p, 
        !           933:   int iIndex,                     /* Index for p->aIndex */
        !           934:   int iLevel, 
        !           935:   int *piIdx
        !           936: ){
        !           937:   int rc;                         /* Return Code */
        !           938:   sqlite3_stmt *pNextIdx;         /* Query for next idx at level iLevel */
        !           939:   int iNext = 0;                  /* Result of query pNextIdx */
        !           940: 
        !           941:   /* Set variable iNext to the next available segdir index at level iLevel. */
        !           942:   rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0);
        !           943:   if( rc==SQLITE_OK ){
        !           944:     sqlite3_bind_int(pNextIdx, 1, iIndex*FTS3_SEGDIR_MAXLEVEL + iLevel);
        !           945:     if( SQLITE_ROW==sqlite3_step(pNextIdx) ){
        !           946:       iNext = sqlite3_column_int(pNextIdx, 0);
        !           947:     }
        !           948:     rc = sqlite3_reset(pNextIdx);
        !           949:   }
        !           950: 
        !           951:   if( rc==SQLITE_OK ){
        !           952:     /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already
        !           953:     ** full, merge all segments in level iLevel into a single iLevel+1
        !           954:     ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise,
        !           955:     ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext.
        !           956:     */
        !           957:     if( iNext>=FTS3_MERGE_COUNT ){
        !           958:       rc = fts3SegmentMerge(p, iIndex, iLevel);
        !           959:       *piIdx = 0;
        !           960:     }else{
        !           961:       *piIdx = iNext;
        !           962:     }
        !           963:   }
        !           964: 
        !           965:   return rc;
        !           966: }
        !           967: 
        !           968: /*
        !           969: ** The %_segments table is declared as follows:
        !           970: **
        !           971: **   CREATE TABLE %_segments(blockid INTEGER PRIMARY KEY, block BLOB)
        !           972: **
        !           973: ** This function reads data from a single row of the %_segments table. The
        !           974: ** specific row is identified by the iBlockid parameter. If paBlob is not
        !           975: ** NULL, then a buffer is allocated using sqlite3_malloc() and populated
        !           976: ** with the contents of the blob stored in the "block" column of the 
        !           977: ** identified table row is. Whether or not paBlob is NULL, *pnBlob is set
        !           978: ** to the size of the blob in bytes before returning.
        !           979: **
        !           980: ** If an error occurs, or the table does not contain the specified row,
        !           981: ** an SQLite error code is returned. Otherwise, SQLITE_OK is returned. If
        !           982: ** paBlob is non-NULL, then it is the responsibility of the caller to
        !           983: ** eventually free the returned buffer.
        !           984: **
        !           985: ** This function may leave an open sqlite3_blob* handle in the
        !           986: ** Fts3Table.pSegments variable. This handle is reused by subsequent calls
        !           987: ** to this function. The handle may be closed by calling the
        !           988: ** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy
        !           989: ** performance improvement, but the blob handle should always be closed
        !           990: ** before control is returned to the user (to prevent a lock being held
        !           991: ** on the database file for longer than necessary). Thus, any virtual table
        !           992: ** method (xFilter etc.) that may directly or indirectly call this function
        !           993: ** must call sqlite3Fts3SegmentsClose() before returning.
        !           994: */
        !           995: int sqlite3Fts3ReadBlock(
        !           996:   Fts3Table *p,                   /* FTS3 table handle */
        !           997:   sqlite3_int64 iBlockid,         /* Access the row with blockid=$iBlockid */
        !           998:   char **paBlob,                  /* OUT: Blob data in malloc'd buffer */
        !           999:   int *pnBlob,                    /* OUT: Size of blob data */
        !          1000:   int *pnLoad                     /* OUT: Bytes actually loaded */
        !          1001: ){
        !          1002:   int rc;                         /* Return code */
        !          1003: 
        !          1004:   /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */
        !          1005:   assert( pnBlob);
        !          1006: 
        !          1007:   if( p->pSegments ){
        !          1008:     rc = sqlite3_blob_reopen(p->pSegments, iBlockid);
        !          1009:   }else{
        !          1010:     if( 0==p->zSegmentsTbl ){
        !          1011:       p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName);
        !          1012:       if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM;
        !          1013:     }
        !          1014:     rc = sqlite3_blob_open(
        !          1015:        p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments
        !          1016:     );
        !          1017:   }
        !          1018: 
        !          1019:   if( rc==SQLITE_OK ){
        !          1020:     int nByte = sqlite3_blob_bytes(p->pSegments);
        !          1021:     *pnBlob = nByte;
        !          1022:     if( paBlob ){
        !          1023:       char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
        !          1024:       if( !aByte ){
        !          1025:         rc = SQLITE_NOMEM;
        !          1026:       }else{
        !          1027:         if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){
        !          1028:           nByte = FTS3_NODE_CHUNKSIZE;
        !          1029:           *pnLoad = nByte;
        !          1030:         }
        !          1031:         rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0);
        !          1032:         memset(&aByte[nByte], 0, FTS3_NODE_PADDING);
        !          1033:         if( rc!=SQLITE_OK ){
        !          1034:           sqlite3_free(aByte);
        !          1035:           aByte = 0;
        !          1036:         }
        !          1037:       }
        !          1038:       *paBlob = aByte;
        !          1039:     }
        !          1040:   }
        !          1041: 
        !          1042:   return rc;
        !          1043: }
        !          1044: 
        !          1045: /*
        !          1046: ** Close the blob handle at p->pSegments, if it is open. See comments above
        !          1047: ** the sqlite3Fts3ReadBlock() function for details.
        !          1048: */
        !          1049: void sqlite3Fts3SegmentsClose(Fts3Table *p){
        !          1050:   sqlite3_blob_close(p->pSegments);
        !          1051:   p->pSegments = 0;
        !          1052: }
        !          1053:     
        !          1054: static int fts3SegReaderIncrRead(Fts3SegReader *pReader){
        !          1055:   int nRead;                      /* Number of bytes to read */
        !          1056:   int rc;                         /* Return code */
        !          1057: 
        !          1058:   nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE);
        !          1059:   rc = sqlite3_blob_read(
        !          1060:       pReader->pBlob, 
        !          1061:       &pReader->aNode[pReader->nPopulate],
        !          1062:       nRead,
        !          1063:       pReader->nPopulate
        !          1064:   );
        !          1065: 
        !          1066:   if( rc==SQLITE_OK ){
        !          1067:     pReader->nPopulate += nRead;
        !          1068:     memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING);
        !          1069:     if( pReader->nPopulate==pReader->nNode ){
        !          1070:       sqlite3_blob_close(pReader->pBlob);
        !          1071:       pReader->pBlob = 0;
        !          1072:       pReader->nPopulate = 0;
        !          1073:     }
        !          1074:   }
        !          1075:   return rc;
        !          1076: }
        !          1077: 
        !          1078: static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){
        !          1079:   int rc = SQLITE_OK;
        !          1080:   assert( !pReader->pBlob 
        !          1081:        || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode])
        !          1082:   );
        !          1083:   while( pReader->pBlob && rc==SQLITE_OK 
        !          1084:      &&  (pFrom - pReader->aNode + nByte)>pReader->nPopulate
        !          1085:   ){
        !          1086:     rc = fts3SegReaderIncrRead(pReader);
        !          1087:   }
        !          1088:   return rc;
        !          1089: }
        !          1090: 
        !          1091: /*
        !          1092: ** Move the iterator passed as the first argument to the next term in the
        !          1093: ** segment. If successful, SQLITE_OK is returned. If there is no next term,
        !          1094: ** SQLITE_DONE. Otherwise, an SQLite error code.
        !          1095: */
        !          1096: static int fts3SegReaderNext(
        !          1097:   Fts3Table *p, 
        !          1098:   Fts3SegReader *pReader,
        !          1099:   int bIncr
        !          1100: ){
        !          1101:   int rc;                         /* Return code of various sub-routines */
        !          1102:   char *pNext;                    /* Cursor variable */
        !          1103:   int nPrefix;                    /* Number of bytes in term prefix */
        !          1104:   int nSuffix;                    /* Number of bytes in term suffix */
        !          1105: 
        !          1106:   if( !pReader->aDoclist ){
        !          1107:     pNext = pReader->aNode;
        !          1108:   }else{
        !          1109:     pNext = &pReader->aDoclist[pReader->nDoclist];
        !          1110:   }
        !          1111: 
        !          1112:   if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){
        !          1113: 
        !          1114:     if( fts3SegReaderIsPending(pReader) ){
        !          1115:       Fts3HashElem *pElem = *(pReader->ppNextElem);
        !          1116:       if( pElem==0 ){
        !          1117:         pReader->aNode = 0;
        !          1118:       }else{
        !          1119:         PendingList *pList = (PendingList *)fts3HashData(pElem);
        !          1120:         pReader->zTerm = (char *)fts3HashKey(pElem);
        !          1121:         pReader->nTerm = fts3HashKeysize(pElem);
        !          1122:         pReader->nNode = pReader->nDoclist = pList->nData + 1;
        !          1123:         pReader->aNode = pReader->aDoclist = pList->aData;
        !          1124:         pReader->ppNextElem++;
        !          1125:         assert( pReader->aNode );
        !          1126:       }
        !          1127:       return SQLITE_OK;
        !          1128:     }
        !          1129: 
        !          1130:     if( !fts3SegReaderIsRootOnly(pReader) ){
        !          1131:       sqlite3_free(pReader->aNode);
        !          1132:       sqlite3_blob_close(pReader->pBlob);
        !          1133:       pReader->pBlob = 0;
        !          1134:     }
        !          1135:     pReader->aNode = 0;
        !          1136: 
        !          1137:     /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf 
        !          1138:     ** blocks have already been traversed.  */
        !          1139:     assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock );
        !          1140:     if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){
        !          1141:       return SQLITE_OK;
        !          1142:     }
        !          1143: 
        !          1144:     rc = sqlite3Fts3ReadBlock(
        !          1145:         p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, 
        !          1146:         (bIncr ? &pReader->nPopulate : 0)
        !          1147:     );
        !          1148:     if( rc!=SQLITE_OK ) return rc;
        !          1149:     assert( pReader->pBlob==0 );
        !          1150:     if( bIncr && pReader->nPopulate<pReader->nNode ){
        !          1151:       pReader->pBlob = p->pSegments;
        !          1152:       p->pSegments = 0;
        !          1153:     }
        !          1154:     pNext = pReader->aNode;
        !          1155:   }
        !          1156: 
        !          1157:   assert( !fts3SegReaderIsPending(pReader) );
        !          1158: 
        !          1159:   rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2);
        !          1160:   if( rc!=SQLITE_OK ) return rc;
        !          1161:   
        !          1162:   /* Because of the FTS3_NODE_PADDING bytes of padding, the following is 
        !          1163:   ** safe (no risk of overread) even if the node data is corrupted. */
        !          1164:   pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
        !          1165:   pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
        !          1166:   if( nPrefix<0 || nSuffix<=0 
        !          1167:    || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] 
        !          1168:   ){
        !          1169:     return FTS_CORRUPT_VTAB;
        !          1170:   }
        !          1171: 
        !          1172:   if( nPrefix+nSuffix>pReader->nTermAlloc ){
        !          1173:     int nNew = (nPrefix+nSuffix)*2;
        !          1174:     char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
        !          1175:     if( !zNew ){
        !          1176:       return SQLITE_NOMEM;
        !          1177:     }
        !          1178:     pReader->zTerm = zNew;
        !          1179:     pReader->nTermAlloc = nNew;
        !          1180:   }
        !          1181: 
        !          1182:   rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX);
        !          1183:   if( rc!=SQLITE_OK ) return rc;
        !          1184: 
        !          1185:   memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix);
        !          1186:   pReader->nTerm = nPrefix+nSuffix;
        !          1187:   pNext += nSuffix;
        !          1188:   pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist);
        !          1189:   pReader->aDoclist = pNext;
        !          1190:   pReader->pOffsetList = 0;
        !          1191: 
        !          1192:   /* Check that the doclist does not appear to extend past the end of the
        !          1193:   ** b-tree node. And that the final byte of the doclist is 0x00. If either 
        !          1194:   ** of these statements is untrue, then the data structure is corrupt.
        !          1195:   */
        !          1196:   if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] 
        !          1197:    || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
        !          1198:   ){
        !          1199:     return FTS_CORRUPT_VTAB;
        !          1200:   }
        !          1201:   return SQLITE_OK;
        !          1202: }
        !          1203: 
        !          1204: /*
        !          1205: ** Set the SegReader to point to the first docid in the doclist associated
        !          1206: ** with the current term.
        !          1207: */
        !          1208: static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){
        !          1209:   int rc = SQLITE_OK;
        !          1210:   assert( pReader->aDoclist );
        !          1211:   assert( !pReader->pOffsetList );
        !          1212:   if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){
        !          1213:     u8 bEof = 0;
        !          1214:     pReader->iDocid = 0;
        !          1215:     pReader->nOffsetList = 0;
        !          1216:     sqlite3Fts3DoclistPrev(0,
        !          1217:         pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList, 
        !          1218:         &pReader->iDocid, &pReader->nOffsetList, &bEof
        !          1219:     );
        !          1220:   }else{
        !          1221:     rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX);
        !          1222:     if( rc==SQLITE_OK ){
        !          1223:       int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid);
        !          1224:       pReader->pOffsetList = &pReader->aDoclist[n];
        !          1225:     }
        !          1226:   }
        !          1227:   return rc;
        !          1228: }
        !          1229: 
        !          1230: /*
        !          1231: ** Advance the SegReader to point to the next docid in the doclist
        !          1232: ** associated with the current term.
        !          1233: ** 
        !          1234: ** If arguments ppOffsetList and pnOffsetList are not NULL, then 
        !          1235: ** *ppOffsetList is set to point to the first column-offset list
        !          1236: ** in the doclist entry (i.e. immediately past the docid varint).
        !          1237: ** *pnOffsetList is set to the length of the set of column-offset
        !          1238: ** lists, not including the nul-terminator byte. For example:
        !          1239: */
        !          1240: static int fts3SegReaderNextDocid(
        !          1241:   Fts3Table *pTab,
        !          1242:   Fts3SegReader *pReader,         /* Reader to advance to next docid */
        !          1243:   char **ppOffsetList,            /* OUT: Pointer to current position-list */
        !          1244:   int *pnOffsetList               /* OUT: Length of *ppOffsetList in bytes */
        !          1245: ){
        !          1246:   int rc = SQLITE_OK;
        !          1247:   char *p = pReader->pOffsetList;
        !          1248:   char c = 0;
        !          1249: 
        !          1250:   assert( p );
        !          1251: 
        !          1252:   if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){
        !          1253:     /* A pending-terms seg-reader for an FTS4 table that uses order=desc.
        !          1254:     ** Pending-terms doclists are always built up in ascending order, so
        !          1255:     ** we have to iterate through them backwards here. */
        !          1256:     u8 bEof = 0;
        !          1257:     if( ppOffsetList ){
        !          1258:       *ppOffsetList = pReader->pOffsetList;
        !          1259:       *pnOffsetList = pReader->nOffsetList - 1;
        !          1260:     }
        !          1261:     sqlite3Fts3DoclistPrev(0,
        !          1262:         pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid,
        !          1263:         &pReader->nOffsetList, &bEof
        !          1264:     );
        !          1265:     if( bEof ){
        !          1266:       pReader->pOffsetList = 0;
        !          1267:     }else{
        !          1268:       pReader->pOffsetList = p;
        !          1269:     }
        !          1270:   }else{
        !          1271:     char *pEnd = &pReader->aDoclist[pReader->nDoclist];
        !          1272: 
        !          1273:     /* Pointer p currently points at the first byte of an offset list. The
        !          1274:     ** following block advances it to point one byte past the end of
        !          1275:     ** the same offset list. */
        !          1276:     while( 1 ){
        !          1277:   
        !          1278:       /* The following line of code (and the "p++" below the while() loop) is
        !          1279:       ** normally all that is required to move pointer p to the desired 
        !          1280:       ** position. The exception is if this node is being loaded from disk
        !          1281:       ** incrementally and pointer "p" now points to the first byte passed
        !          1282:       ** the populated part of pReader->aNode[].
        !          1283:       */
        !          1284:       while( *p | c ) c = *p++ & 0x80;
        !          1285:       assert( *p==0 );
        !          1286:   
        !          1287:       if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break;
        !          1288:       rc = fts3SegReaderIncrRead(pReader);
        !          1289:       if( rc!=SQLITE_OK ) return rc;
        !          1290:     }
        !          1291:     p++;
        !          1292:   
        !          1293:     /* If required, populate the output variables with a pointer to and the
        !          1294:     ** size of the previous offset-list.
        !          1295:     */
        !          1296:     if( ppOffsetList ){
        !          1297:       *ppOffsetList = pReader->pOffsetList;
        !          1298:       *pnOffsetList = (int)(p - pReader->pOffsetList - 1);
        !          1299:     }
        !          1300: 
        !          1301:     while( p<pEnd && *p==0 ) p++;
        !          1302:   
        !          1303:     /* If there are no more entries in the doclist, set pOffsetList to
        !          1304:     ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and
        !          1305:     ** Fts3SegReader.pOffsetList to point to the next offset list before
        !          1306:     ** returning.
        !          1307:     */
        !          1308:     if( p>=pEnd ){
        !          1309:       pReader->pOffsetList = 0;
        !          1310:     }else{
        !          1311:       rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX);
        !          1312:       if( rc==SQLITE_OK ){
        !          1313:         sqlite3_int64 iDelta;
        !          1314:         pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta);
        !          1315:         if( pTab->bDescIdx ){
        !          1316:           pReader->iDocid -= iDelta;
        !          1317:         }else{
        !          1318:           pReader->iDocid += iDelta;
        !          1319:         }
        !          1320:       }
        !          1321:     }
        !          1322:   }
        !          1323: 
        !          1324:   return SQLITE_OK;
        !          1325: }
        !          1326: 
        !          1327: 
        !          1328: int sqlite3Fts3MsrOvfl(
        !          1329:   Fts3Cursor *pCsr, 
        !          1330:   Fts3MultiSegReader *pMsr,
        !          1331:   int *pnOvfl
        !          1332: ){
        !          1333:   Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
        !          1334:   int nOvfl = 0;
        !          1335:   int ii;
        !          1336:   int rc = SQLITE_OK;
        !          1337:   int pgsz = p->nPgsz;
        !          1338: 
        !          1339:   assert( p->bHasStat );
        !          1340:   assert( pgsz>0 );
        !          1341: 
        !          1342:   for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){
        !          1343:     Fts3SegReader *pReader = pMsr->apSegment[ii];
        !          1344:     if( !fts3SegReaderIsPending(pReader) 
        !          1345:      && !fts3SegReaderIsRootOnly(pReader) 
        !          1346:     ){
        !          1347:       sqlite3_int64 jj;
        !          1348:       for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){
        !          1349:         int nBlob;
        !          1350:         rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0);
        !          1351:         if( rc!=SQLITE_OK ) break;
        !          1352:         if( (nBlob+35)>pgsz ){
        !          1353:           nOvfl += (nBlob + 34)/pgsz;
        !          1354:         }
        !          1355:       }
        !          1356:     }
        !          1357:   }
        !          1358:   *pnOvfl = nOvfl;
        !          1359:   return rc;
        !          1360: }
        !          1361: 
        !          1362: /*
        !          1363: ** Free all allocations associated with the iterator passed as the 
        !          1364: ** second argument.
        !          1365: */
        !          1366: void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
        !          1367:   if( pReader && !fts3SegReaderIsPending(pReader) ){
        !          1368:     sqlite3_free(pReader->zTerm);
        !          1369:     if( !fts3SegReaderIsRootOnly(pReader) ){
        !          1370:       sqlite3_free(pReader->aNode);
        !          1371:       sqlite3_blob_close(pReader->pBlob);
        !          1372:     }
        !          1373:   }
        !          1374:   sqlite3_free(pReader);
        !          1375: }
        !          1376: 
        !          1377: /*
        !          1378: ** Allocate a new SegReader object.
        !          1379: */
        !          1380: int sqlite3Fts3SegReaderNew(
        !          1381:   int iAge,                       /* Segment "age". */
        !          1382:   sqlite3_int64 iStartLeaf,       /* First leaf to traverse */
        !          1383:   sqlite3_int64 iEndLeaf,         /* Final leaf to traverse */
        !          1384:   sqlite3_int64 iEndBlock,        /* Final block of segment */
        !          1385:   const char *zRoot,              /* Buffer containing root node */
        !          1386:   int nRoot,                      /* Size of buffer containing root node */
        !          1387:   Fts3SegReader **ppReader        /* OUT: Allocated Fts3SegReader */
        !          1388: ){
        !          1389:   Fts3SegReader *pReader;         /* Newly allocated SegReader object */
        !          1390:   int nExtra = 0;                 /* Bytes to allocate segment root node */
        !          1391: 
        !          1392:   assert( iStartLeaf<=iEndLeaf );
        !          1393:   if( iStartLeaf==0 ){
        !          1394:     nExtra = nRoot + FTS3_NODE_PADDING;
        !          1395:   }
        !          1396: 
        !          1397:   pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
        !          1398:   if( !pReader ){
        !          1399:     return SQLITE_NOMEM;
        !          1400:   }
        !          1401:   memset(pReader, 0, sizeof(Fts3SegReader));
        !          1402:   pReader->iIdx = iAge;
        !          1403:   pReader->iStartBlock = iStartLeaf;
        !          1404:   pReader->iLeafEndBlock = iEndLeaf;
        !          1405:   pReader->iEndBlock = iEndBlock;
        !          1406: 
        !          1407:   if( nExtra ){
        !          1408:     /* The entire segment is stored in the root node. */
        !          1409:     pReader->aNode = (char *)&pReader[1];
        !          1410:     pReader->nNode = nRoot;
        !          1411:     memcpy(pReader->aNode, zRoot, nRoot);
        !          1412:     memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
        !          1413:   }else{
        !          1414:     pReader->iCurrentBlock = iStartLeaf-1;
        !          1415:   }
        !          1416:   *ppReader = pReader;
        !          1417:   return SQLITE_OK;
        !          1418: }
        !          1419: 
        !          1420: /*
        !          1421: ** This is a comparison function used as a qsort() callback when sorting
        !          1422: ** an array of pending terms by term. This occurs as part of flushing
        !          1423: ** the contents of the pending-terms hash table to the database.
        !          1424: */
        !          1425: static int fts3CompareElemByTerm(const void *lhs, const void *rhs){
        !          1426:   char *z1 = fts3HashKey(*(Fts3HashElem **)lhs);
        !          1427:   char *z2 = fts3HashKey(*(Fts3HashElem **)rhs);
        !          1428:   int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs);
        !          1429:   int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs);
        !          1430: 
        !          1431:   int n = (n1<n2 ? n1 : n2);
        !          1432:   int c = memcmp(z1, z2, n);
        !          1433:   if( c==0 ){
        !          1434:     c = n1 - n2;
        !          1435:   }
        !          1436:   return c;
        !          1437: }
        !          1438: 
        !          1439: /*
        !          1440: ** This function is used to allocate an Fts3SegReader that iterates through
        !          1441: ** a subset of the terms stored in the Fts3Table.pendingTerms array.
        !          1442: **
        !          1443: ** If the isPrefixIter parameter is zero, then the returned SegReader iterates
        !          1444: ** through each term in the pending-terms table. Or, if isPrefixIter is
        !          1445: ** non-zero, it iterates through each term and its prefixes. For example, if
        !          1446: ** the pending terms hash table contains the terms "sqlite", "mysql" and
        !          1447: ** "firebird", then the iterator visits the following 'terms' (in the order
        !          1448: ** shown):
        !          1449: **
        !          1450: **   f fi fir fire fireb firebi firebir firebird
        !          1451: **   m my mys mysq mysql
        !          1452: **   s sq sql sqli sqlit sqlite
        !          1453: **
        !          1454: ** Whereas if isPrefixIter is zero, the terms visited are:
        !          1455: **
        !          1456: **   firebird mysql sqlite
        !          1457: */
        !          1458: int sqlite3Fts3SegReaderPending(
        !          1459:   Fts3Table *p,                   /* Virtual table handle */
        !          1460:   int iIndex,                     /* Index for p->aIndex */
        !          1461:   const char *zTerm,              /* Term to search for */
        !          1462:   int nTerm,                      /* Size of buffer zTerm */
        !          1463:   int bPrefix,                    /* True for a prefix iterator */
        !          1464:   Fts3SegReader **ppReader        /* OUT: SegReader for pending-terms */
        !          1465: ){
        !          1466:   Fts3SegReader *pReader = 0;     /* Fts3SegReader object to return */
        !          1467:   Fts3HashElem *pE;               /* Iterator variable */
        !          1468:   Fts3HashElem **aElem = 0;       /* Array of term hash entries to scan */
        !          1469:   int nElem = 0;                  /* Size of array at aElem */
        !          1470:   int rc = SQLITE_OK;             /* Return Code */
        !          1471:   Fts3Hash *pHash;
        !          1472: 
        !          1473:   pHash = &p->aIndex[iIndex].hPending;
        !          1474:   if( bPrefix ){
        !          1475:     int nAlloc = 0;               /* Size of allocated array at aElem */
        !          1476: 
        !          1477:     for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){
        !          1478:       char *zKey = (char *)fts3HashKey(pE);
        !          1479:       int nKey = fts3HashKeysize(pE);
        !          1480:       if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){
        !          1481:         if( nElem==nAlloc ){
        !          1482:           Fts3HashElem **aElem2;
        !          1483:           nAlloc += 16;
        !          1484:           aElem2 = (Fts3HashElem **)sqlite3_realloc(
        !          1485:               aElem, nAlloc*sizeof(Fts3HashElem *)
        !          1486:           );
        !          1487:           if( !aElem2 ){
        !          1488:             rc = SQLITE_NOMEM;
        !          1489:             nElem = 0;
        !          1490:             break;
        !          1491:           }
        !          1492:           aElem = aElem2;
        !          1493:         }
        !          1494: 
        !          1495:         aElem[nElem++] = pE;
        !          1496:       }
        !          1497:     }
        !          1498: 
        !          1499:     /* If more than one term matches the prefix, sort the Fts3HashElem
        !          1500:     ** objects in term order using qsort(). This uses the same comparison
        !          1501:     ** callback as is used when flushing terms to disk.
        !          1502:     */
        !          1503:     if( nElem>1 ){
        !          1504:       qsort(aElem, nElem, sizeof(Fts3HashElem *), fts3CompareElemByTerm);
        !          1505:     }
        !          1506: 
        !          1507:   }else{
        !          1508:     /* The query is a simple term lookup that matches at most one term in
        !          1509:     ** the index. All that is required is a straight hash-lookup. 
        !          1510:     **
        !          1511:     ** Because the stack address of pE may be accessed via the aElem pointer
        !          1512:     ** below, the "Fts3HashElem *pE" must be declared so that it is valid
        !          1513:     ** within this entire function, not just this "else{...}" block.
        !          1514:     */
        !          1515:     pE = fts3HashFindElem(pHash, zTerm, nTerm);
        !          1516:     if( pE ){
        !          1517:       aElem = &pE;
        !          1518:       nElem = 1;
        !          1519:     }
        !          1520:   }
        !          1521: 
        !          1522:   if( nElem>0 ){
        !          1523:     int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
        !          1524:     pReader = (Fts3SegReader *)sqlite3_malloc(nByte);
        !          1525:     if( !pReader ){
        !          1526:       rc = SQLITE_NOMEM;
        !          1527:     }else{
        !          1528:       memset(pReader, 0, nByte);
        !          1529:       pReader->iIdx = 0x7FFFFFFF;
        !          1530:       pReader->ppNextElem = (Fts3HashElem **)&pReader[1];
        !          1531:       memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *));
        !          1532:     }
        !          1533:   }
        !          1534: 
        !          1535:   if( bPrefix ){
        !          1536:     sqlite3_free(aElem);
        !          1537:   }
        !          1538:   *ppReader = pReader;
        !          1539:   return rc;
        !          1540: }
        !          1541: 
        !          1542: /*
        !          1543: ** Compare the entries pointed to by two Fts3SegReader structures. 
        !          1544: ** Comparison is as follows:
        !          1545: **
        !          1546: **   1) EOF is greater than not EOF.
        !          1547: **
        !          1548: **   2) The current terms (if any) are compared using memcmp(). If one
        !          1549: **      term is a prefix of another, the longer term is considered the
        !          1550: **      larger.
        !          1551: **
        !          1552: **   3) By segment age. An older segment is considered larger.
        !          1553: */
        !          1554: static int fts3SegReaderCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){
        !          1555:   int rc;
        !          1556:   if( pLhs->aNode && pRhs->aNode ){
        !          1557:     int rc2 = pLhs->nTerm - pRhs->nTerm;
        !          1558:     if( rc2<0 ){
        !          1559:       rc = memcmp(pLhs->zTerm, pRhs->zTerm, pLhs->nTerm);
        !          1560:     }else{
        !          1561:       rc = memcmp(pLhs->zTerm, pRhs->zTerm, pRhs->nTerm);
        !          1562:     }
        !          1563:     if( rc==0 ){
        !          1564:       rc = rc2;
        !          1565:     }
        !          1566:   }else{
        !          1567:     rc = (pLhs->aNode==0) - (pRhs->aNode==0);
        !          1568:   }
        !          1569:   if( rc==0 ){
        !          1570:     rc = pRhs->iIdx - pLhs->iIdx;
        !          1571:   }
        !          1572:   assert( rc!=0 );
        !          1573:   return rc;
        !          1574: }
        !          1575: 
        !          1576: /*
        !          1577: ** A different comparison function for SegReader structures. In this
        !          1578: ** version, it is assumed that each SegReader points to an entry in
        !          1579: ** a doclist for identical terms. Comparison is made as follows:
        !          1580: **
        !          1581: **   1) EOF (end of doclist in this case) is greater than not EOF.
        !          1582: **
        !          1583: **   2) By current docid.
        !          1584: **
        !          1585: **   3) By segment age. An older segment is considered larger.
        !          1586: */
        !          1587: static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){
        !          1588:   int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0);
        !          1589:   if( rc==0 ){
        !          1590:     if( pLhs->iDocid==pRhs->iDocid ){
        !          1591:       rc = pRhs->iIdx - pLhs->iIdx;
        !          1592:     }else{
        !          1593:       rc = (pLhs->iDocid > pRhs->iDocid) ? 1 : -1;
        !          1594:     }
        !          1595:   }
        !          1596:   assert( pLhs->aNode && pRhs->aNode );
        !          1597:   return rc;
        !          1598: }
        !          1599: static int fts3SegReaderDoclistCmpRev(Fts3SegReader *pLhs, Fts3SegReader *pRhs){
        !          1600:   int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0);
        !          1601:   if( rc==0 ){
        !          1602:     if( pLhs->iDocid==pRhs->iDocid ){
        !          1603:       rc = pRhs->iIdx - pLhs->iIdx;
        !          1604:     }else{
        !          1605:       rc = (pLhs->iDocid < pRhs->iDocid) ? 1 : -1;
        !          1606:     }
        !          1607:   }
        !          1608:   assert( pLhs->aNode && pRhs->aNode );
        !          1609:   return rc;
        !          1610: }
        !          1611: 
        !          1612: /*
        !          1613: ** Compare the term that the Fts3SegReader object passed as the first argument
        !          1614: ** points to with the term specified by arguments zTerm and nTerm. 
        !          1615: **
        !          1616: ** If the pSeg iterator is already at EOF, return 0. Otherwise, return
        !          1617: ** -ve if the pSeg term is less than zTerm/nTerm, 0 if the two terms are
        !          1618: ** equal, or +ve if the pSeg term is greater than zTerm/nTerm.
        !          1619: */
        !          1620: static int fts3SegReaderTermCmp(
        !          1621:   Fts3SegReader *pSeg,            /* Segment reader object */
        !          1622:   const char *zTerm,              /* Term to compare to */
        !          1623:   int nTerm                       /* Size of term zTerm in bytes */
        !          1624: ){
        !          1625:   int res = 0;
        !          1626:   if( pSeg->aNode ){
        !          1627:     if( pSeg->nTerm>nTerm ){
        !          1628:       res = memcmp(pSeg->zTerm, zTerm, nTerm);
        !          1629:     }else{
        !          1630:       res = memcmp(pSeg->zTerm, zTerm, pSeg->nTerm);
        !          1631:     }
        !          1632:     if( res==0 ){
        !          1633:       res = pSeg->nTerm-nTerm;
        !          1634:     }
        !          1635:   }
        !          1636:   return res;
        !          1637: }
        !          1638: 
        !          1639: /*
        !          1640: ** Argument apSegment is an array of nSegment elements. It is known that
        !          1641: ** the final (nSegment-nSuspect) members are already in sorted order
        !          1642: ** (according to the comparison function provided). This function shuffles
        !          1643: ** the array around until all entries are in sorted order.
        !          1644: */
        !          1645: static void fts3SegReaderSort(
        !          1646:   Fts3SegReader **apSegment,                     /* Array to sort entries of */
        !          1647:   int nSegment,                                  /* Size of apSegment array */
        !          1648:   int nSuspect,                                  /* Unsorted entry count */
        !          1649:   int (*xCmp)(Fts3SegReader *, Fts3SegReader *)  /* Comparison function */
        !          1650: ){
        !          1651:   int i;                          /* Iterator variable */
        !          1652: 
        !          1653:   assert( nSuspect<=nSegment );
        !          1654: 
        !          1655:   if( nSuspect==nSegment ) nSuspect--;
        !          1656:   for(i=nSuspect-1; i>=0; i--){
        !          1657:     int j;
        !          1658:     for(j=i; j<(nSegment-1); j++){
        !          1659:       Fts3SegReader *pTmp;
        !          1660:       if( xCmp(apSegment[j], apSegment[j+1])<0 ) break;
        !          1661:       pTmp = apSegment[j+1];
        !          1662:       apSegment[j+1] = apSegment[j];
        !          1663:       apSegment[j] = pTmp;
        !          1664:     }
        !          1665:   }
        !          1666: 
        !          1667: #ifndef NDEBUG
        !          1668:   /* Check that the list really is sorted now. */
        !          1669:   for(i=0; i<(nSuspect-1); i++){
        !          1670:     assert( xCmp(apSegment[i], apSegment[i+1])<0 );
        !          1671:   }
        !          1672: #endif
        !          1673: }
        !          1674: 
        !          1675: /* 
        !          1676: ** Insert a record into the %_segments table.
        !          1677: */
        !          1678: static int fts3WriteSegment(
        !          1679:   Fts3Table *p,                   /* Virtual table handle */
        !          1680:   sqlite3_int64 iBlock,           /* Block id for new block */
        !          1681:   char *z,                        /* Pointer to buffer containing block data */
        !          1682:   int n                           /* Size of buffer z in bytes */
        !          1683: ){
        !          1684:   sqlite3_stmt *pStmt;
        !          1685:   int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0);
        !          1686:   if( rc==SQLITE_OK ){
        !          1687:     sqlite3_bind_int64(pStmt, 1, iBlock);
        !          1688:     sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC);
        !          1689:     sqlite3_step(pStmt);
        !          1690:     rc = sqlite3_reset(pStmt);
        !          1691:   }
        !          1692:   return rc;
        !          1693: }
        !          1694: 
        !          1695: /* 
        !          1696: ** Insert a record into the %_segdir table.
        !          1697: */
        !          1698: static int fts3WriteSegdir(
        !          1699:   Fts3Table *p,                   /* Virtual table handle */
        !          1700:   int iLevel,                     /* Value for "level" field */
        !          1701:   int iIdx,                       /* Value for "idx" field */
        !          1702:   sqlite3_int64 iStartBlock,      /* Value for "start_block" field */
        !          1703:   sqlite3_int64 iLeafEndBlock,    /* Value for "leaves_end_block" field */
        !          1704:   sqlite3_int64 iEndBlock,        /* Value for "end_block" field */
        !          1705:   char *zRoot,                    /* Blob value for "root" field */
        !          1706:   int nRoot                       /* Number of bytes in buffer zRoot */
        !          1707: ){
        !          1708:   sqlite3_stmt *pStmt;
        !          1709:   int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0);
        !          1710:   if( rc==SQLITE_OK ){
        !          1711:     sqlite3_bind_int(pStmt, 1, iLevel);
        !          1712:     sqlite3_bind_int(pStmt, 2, iIdx);
        !          1713:     sqlite3_bind_int64(pStmt, 3, iStartBlock);
        !          1714:     sqlite3_bind_int64(pStmt, 4, iLeafEndBlock);
        !          1715:     sqlite3_bind_int64(pStmt, 5, iEndBlock);
        !          1716:     sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC);
        !          1717:     sqlite3_step(pStmt);
        !          1718:     rc = sqlite3_reset(pStmt);
        !          1719:   }
        !          1720:   return rc;
        !          1721: }
        !          1722: 
        !          1723: /*
        !          1724: ** Return the size of the common prefix (if any) shared by zPrev and
        !          1725: ** zNext, in bytes. For example, 
        !          1726: **
        !          1727: **   fts3PrefixCompress("abc", 3, "abcdef", 6)   // returns 3
        !          1728: **   fts3PrefixCompress("abX", 3, "abcdef", 6)   // returns 2
        !          1729: **   fts3PrefixCompress("abX", 3, "Xbcdef", 6)   // returns 0
        !          1730: */
        !          1731: static int fts3PrefixCompress(
        !          1732:   const char *zPrev,              /* Buffer containing previous term */
        !          1733:   int nPrev,                      /* Size of buffer zPrev in bytes */
        !          1734:   const char *zNext,              /* Buffer containing next term */
        !          1735:   int nNext                       /* Size of buffer zNext in bytes */
        !          1736: ){
        !          1737:   int n;
        !          1738:   UNUSED_PARAMETER(nNext);
        !          1739:   for(n=0; n<nPrev && zPrev[n]==zNext[n]; n++);
        !          1740:   return n;
        !          1741: }
        !          1742: 
        !          1743: /*
        !          1744: ** Add term zTerm to the SegmentNode. It is guaranteed that zTerm is larger
        !          1745: ** (according to memcmp) than the previous term.
        !          1746: */
        !          1747: static int fts3NodeAddTerm(
        !          1748:   Fts3Table *p,                   /* Virtual table handle */
        !          1749:   SegmentNode **ppTree,           /* IN/OUT: SegmentNode handle */ 
        !          1750:   int isCopyTerm,                 /* True if zTerm/nTerm is transient */
        !          1751:   const char *zTerm,              /* Pointer to buffer containing term */
        !          1752:   int nTerm                       /* Size of term in bytes */
        !          1753: ){
        !          1754:   SegmentNode *pTree = *ppTree;
        !          1755:   int rc;
        !          1756:   SegmentNode *pNew;
        !          1757: 
        !          1758:   /* First try to append the term to the current node. Return early if 
        !          1759:   ** this is possible.
        !          1760:   */
        !          1761:   if( pTree ){
        !          1762:     int nData = pTree->nData;     /* Current size of node in bytes */
        !          1763:     int nReq = nData;             /* Required space after adding zTerm */
        !          1764:     int nPrefix;                  /* Number of bytes of prefix compression */
        !          1765:     int nSuffix;                  /* Suffix length */
        !          1766: 
        !          1767:     nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm);
        !          1768:     nSuffix = nTerm-nPrefix;
        !          1769: 
        !          1770:     nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix;
        !          1771:     if( nReq<=p->nNodeSize || !pTree->zTerm ){
        !          1772: 
        !          1773:       if( nReq>p->nNodeSize ){
        !          1774:         /* An unusual case: this is the first term to be added to the node
        !          1775:         ** and the static node buffer (p->nNodeSize bytes) is not large
        !          1776:         ** enough. Use a separately malloced buffer instead This wastes
        !          1777:         ** p->nNodeSize bytes, but since this scenario only comes about when
        !          1778:         ** the database contain two terms that share a prefix of almost 2KB, 
        !          1779:         ** this is not expected to be a serious problem. 
        !          1780:         */
        !          1781:         assert( pTree->aData==(char *)&pTree[1] );
        !          1782:         pTree->aData = (char *)sqlite3_malloc(nReq);
        !          1783:         if( !pTree->aData ){
        !          1784:           return SQLITE_NOMEM;
        !          1785:         }
        !          1786:       }
        !          1787: 
        !          1788:       if( pTree->zTerm ){
        !          1789:         /* There is no prefix-length field for first term in a node */
        !          1790:         nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix);
        !          1791:       }
        !          1792: 
        !          1793:       nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix);
        !          1794:       memcpy(&pTree->aData[nData], &zTerm[nPrefix], nSuffix);
        !          1795:       pTree->nData = nData + nSuffix;
        !          1796:       pTree->nEntry++;
        !          1797: 
        !          1798:       if( isCopyTerm ){
        !          1799:         if( pTree->nMalloc<nTerm ){
        !          1800:           char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2);
        !          1801:           if( !zNew ){
        !          1802:             return SQLITE_NOMEM;
        !          1803:           }
        !          1804:           pTree->nMalloc = nTerm*2;
        !          1805:           pTree->zMalloc = zNew;
        !          1806:         }
        !          1807:         pTree->zTerm = pTree->zMalloc;
        !          1808:         memcpy(pTree->zTerm, zTerm, nTerm);
        !          1809:         pTree->nTerm = nTerm;
        !          1810:       }else{
        !          1811:         pTree->zTerm = (char *)zTerm;
        !          1812:         pTree->nTerm = nTerm;
        !          1813:       }
        !          1814:       return SQLITE_OK;
        !          1815:     }
        !          1816:   }
        !          1817: 
        !          1818:   /* If control flows to here, it was not possible to append zTerm to the
        !          1819:   ** current node. Create a new node (a right-sibling of the current node).
        !          1820:   ** If this is the first node in the tree, the term is added to it.
        !          1821:   **
        !          1822:   ** Otherwise, the term is not added to the new node, it is left empty for
        !          1823:   ** now. Instead, the term is inserted into the parent of pTree. If pTree 
        !          1824:   ** has no parent, one is created here.
        !          1825:   */
        !          1826:   pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize);
        !          1827:   if( !pNew ){
        !          1828:     return SQLITE_NOMEM;
        !          1829:   }
        !          1830:   memset(pNew, 0, sizeof(SegmentNode));
        !          1831:   pNew->nData = 1 + FTS3_VARINT_MAX;
        !          1832:   pNew->aData = (char *)&pNew[1];
        !          1833: 
        !          1834:   if( pTree ){
        !          1835:     SegmentNode *pParent = pTree->pParent;
        !          1836:     rc = fts3NodeAddTerm(p, &pParent, isCopyTerm, zTerm, nTerm);
        !          1837:     if( pTree->pParent==0 ){
        !          1838:       pTree->pParent = pParent;
        !          1839:     }
        !          1840:     pTree->pRight = pNew;
        !          1841:     pNew->pLeftmost = pTree->pLeftmost;
        !          1842:     pNew->pParent = pParent;
        !          1843:     pNew->zMalloc = pTree->zMalloc;
        !          1844:     pNew->nMalloc = pTree->nMalloc;
        !          1845:     pTree->zMalloc = 0;
        !          1846:   }else{
        !          1847:     pNew->pLeftmost = pNew;
        !          1848:     rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm); 
        !          1849:   }
        !          1850: 
        !          1851:   *ppTree = pNew;
        !          1852:   return rc;
        !          1853: }
        !          1854: 
        !          1855: /*
        !          1856: ** Helper function for fts3NodeWrite().
        !          1857: */
        !          1858: static int fts3TreeFinishNode(
        !          1859:   SegmentNode *pTree, 
        !          1860:   int iHeight, 
        !          1861:   sqlite3_int64 iLeftChild
        !          1862: ){
        !          1863:   int nStart;
        !          1864:   assert( iHeight>=1 && iHeight<128 );
        !          1865:   nStart = FTS3_VARINT_MAX - sqlite3Fts3VarintLen(iLeftChild);
        !          1866:   pTree->aData[nStart] = (char)iHeight;
        !          1867:   sqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild);
        !          1868:   return nStart;
        !          1869: }
        !          1870: 
        !          1871: /*
        !          1872: ** Write the buffer for the segment node pTree and all of its peers to the
        !          1873: ** database. Then call this function recursively to write the parent of 
        !          1874: ** pTree and its peers to the database. 
        !          1875: **
        !          1876: ** Except, if pTree is a root node, do not write it to the database. Instead,
        !          1877: ** set output variables *paRoot and *pnRoot to contain the root node.
        !          1878: **
        !          1879: ** If successful, SQLITE_OK is returned and output variable *piLast is
        !          1880: ** set to the largest blockid written to the database (or zero if no
        !          1881: ** blocks were written to the db). Otherwise, an SQLite error code is 
        !          1882: ** returned.
        !          1883: */
        !          1884: static int fts3NodeWrite(
        !          1885:   Fts3Table *p,                   /* Virtual table handle */
        !          1886:   SegmentNode *pTree,             /* SegmentNode handle */
        !          1887:   int iHeight,                    /* Height of this node in tree */
        !          1888:   sqlite3_int64 iLeaf,            /* Block id of first leaf node */
        !          1889:   sqlite3_int64 iFree,            /* Block id of next free slot in %_segments */
        !          1890:   sqlite3_int64 *piLast,          /* OUT: Block id of last entry written */
        !          1891:   char **paRoot,                  /* OUT: Data for root node */
        !          1892:   int *pnRoot                     /* OUT: Size of root node in bytes */
        !          1893: ){
        !          1894:   int rc = SQLITE_OK;
        !          1895: 
        !          1896:   if( !pTree->pParent ){
        !          1897:     /* Root node of the tree. */
        !          1898:     int nStart = fts3TreeFinishNode(pTree, iHeight, iLeaf);
        !          1899:     *piLast = iFree-1;
        !          1900:     *pnRoot = pTree->nData - nStart;
        !          1901:     *paRoot = &pTree->aData[nStart];
        !          1902:   }else{
        !          1903:     SegmentNode *pIter;
        !          1904:     sqlite3_int64 iNextFree = iFree;
        !          1905:     sqlite3_int64 iNextLeaf = iLeaf;
        !          1906:     for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){
        !          1907:       int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf);
        !          1908:       int nWrite = pIter->nData - nStart;
        !          1909:   
        !          1910:       rc = fts3WriteSegment(p, iNextFree, &pIter->aData[nStart], nWrite);
        !          1911:       iNextFree++;
        !          1912:       iNextLeaf += (pIter->nEntry+1);
        !          1913:     }
        !          1914:     if( rc==SQLITE_OK ){
        !          1915:       assert( iNextLeaf==iFree );
        !          1916:       rc = fts3NodeWrite(
        !          1917:           p, pTree->pParent, iHeight+1, iFree, iNextFree, piLast, paRoot, pnRoot
        !          1918:       );
        !          1919:     }
        !          1920:   }
        !          1921: 
        !          1922:   return rc;
        !          1923: }
        !          1924: 
        !          1925: /*
        !          1926: ** Free all memory allocations associated with the tree pTree.
        !          1927: */
        !          1928: static void fts3NodeFree(SegmentNode *pTree){
        !          1929:   if( pTree ){
        !          1930:     SegmentNode *p = pTree->pLeftmost;
        !          1931:     fts3NodeFree(p->pParent);
        !          1932:     while( p ){
        !          1933:       SegmentNode *pRight = p->pRight;
        !          1934:       if( p->aData!=(char *)&p[1] ){
        !          1935:         sqlite3_free(p->aData);
        !          1936:       }
        !          1937:       assert( pRight==0 || p->zMalloc==0 );
        !          1938:       sqlite3_free(p->zMalloc);
        !          1939:       sqlite3_free(p);
        !          1940:       p = pRight;
        !          1941:     }
        !          1942:   }
        !          1943: }
        !          1944: 
        !          1945: /*
        !          1946: ** Add a term to the segment being constructed by the SegmentWriter object
        !          1947: ** *ppWriter. When adding the first term to a segment, *ppWriter should
        !          1948: ** be passed NULL. This function will allocate a new SegmentWriter object
        !          1949: ** and return it via the input/output variable *ppWriter in this case.
        !          1950: **
        !          1951: ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
        !          1952: */
        !          1953: static int fts3SegWriterAdd(
        !          1954:   Fts3Table *p,                   /* Virtual table handle */
        !          1955:   SegmentWriter **ppWriter,       /* IN/OUT: SegmentWriter handle */ 
        !          1956:   int isCopyTerm,                 /* True if buffer zTerm must be copied */
        !          1957:   const char *zTerm,              /* Pointer to buffer containing term */
        !          1958:   int nTerm,                      /* Size of term in bytes */
        !          1959:   const char *aDoclist,           /* Pointer to buffer containing doclist */
        !          1960:   int nDoclist                    /* Size of doclist in bytes */
        !          1961: ){
        !          1962:   int nPrefix;                    /* Size of term prefix in bytes */
        !          1963:   int nSuffix;                    /* Size of term suffix in bytes */
        !          1964:   int nReq;                       /* Number of bytes required on leaf page */
        !          1965:   int nData;
        !          1966:   SegmentWriter *pWriter = *ppWriter;
        !          1967: 
        !          1968:   if( !pWriter ){
        !          1969:     int rc;
        !          1970:     sqlite3_stmt *pStmt;
        !          1971: 
        !          1972:     /* Allocate the SegmentWriter structure */
        !          1973:     pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter));
        !          1974:     if( !pWriter ) return SQLITE_NOMEM;
        !          1975:     memset(pWriter, 0, sizeof(SegmentWriter));
        !          1976:     *ppWriter = pWriter;
        !          1977: 
        !          1978:     /* Allocate a buffer in which to accumulate data */
        !          1979:     pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize);
        !          1980:     if( !pWriter->aData ) return SQLITE_NOMEM;
        !          1981:     pWriter->nSize = p->nNodeSize;
        !          1982: 
        !          1983:     /* Find the next free blockid in the %_segments table */
        !          1984:     rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0);
        !          1985:     if( rc!=SQLITE_OK ) return rc;
        !          1986:     if( SQLITE_ROW==sqlite3_step(pStmt) ){
        !          1987:       pWriter->iFree = sqlite3_column_int64(pStmt, 0);
        !          1988:       pWriter->iFirst = pWriter->iFree;
        !          1989:     }
        !          1990:     rc = sqlite3_reset(pStmt);
        !          1991:     if( rc!=SQLITE_OK ) return rc;
        !          1992:   }
        !          1993:   nData = pWriter->nData;
        !          1994: 
        !          1995:   nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm);
        !          1996:   nSuffix = nTerm-nPrefix;
        !          1997: 
        !          1998:   /* Figure out how many bytes are required by this new entry */
        !          1999:   nReq = sqlite3Fts3VarintLen(nPrefix) +    /* varint containing prefix size */
        !          2000:     sqlite3Fts3VarintLen(nSuffix) +         /* varint containing suffix size */
        !          2001:     nSuffix +                               /* Term suffix */
        !          2002:     sqlite3Fts3VarintLen(nDoclist) +        /* Size of doclist */
        !          2003:     nDoclist;                               /* Doclist data */
        !          2004: 
        !          2005:   if( nData>0 && nData+nReq>p->nNodeSize ){
        !          2006:     int rc;
        !          2007: 
        !          2008:     /* The current leaf node is full. Write it out to the database. */
        !          2009:     rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData);
        !          2010:     if( rc!=SQLITE_OK ) return rc;
        !          2011: 
        !          2012:     /* Add the current term to the interior node tree. The term added to
        !          2013:     ** the interior tree must:
        !          2014:     **
        !          2015:     **   a) be greater than the largest term on the leaf node just written
        !          2016:     **      to the database (still available in pWriter->zTerm), and
        !          2017:     **
        !          2018:     **   b) be less than or equal to the term about to be added to the new
        !          2019:     **      leaf node (zTerm/nTerm).
        !          2020:     **
        !          2021:     ** In other words, it must be the prefix of zTerm 1 byte longer than
        !          2022:     ** the common prefix (if any) of zTerm and pWriter->zTerm.
        !          2023:     */
        !          2024:     assert( nPrefix<nTerm );
        !          2025:     rc = fts3NodeAddTerm(p, &pWriter->pTree, isCopyTerm, zTerm, nPrefix+1);
        !          2026:     if( rc!=SQLITE_OK ) return rc;
        !          2027: 
        !          2028:     nData = 0;
        !          2029:     pWriter->nTerm = 0;
        !          2030: 
        !          2031:     nPrefix = 0;
        !          2032:     nSuffix = nTerm;
        !          2033:     nReq = 1 +                              /* varint containing prefix size */
        !          2034:       sqlite3Fts3VarintLen(nTerm) +         /* varint containing suffix size */
        !          2035:       nTerm +                               /* Term suffix */
        !          2036:       sqlite3Fts3VarintLen(nDoclist) +      /* Size of doclist */
        !          2037:       nDoclist;                             /* Doclist data */
        !          2038:   }
        !          2039: 
        !          2040:   /* If the buffer currently allocated is too small for this entry, realloc
        !          2041:   ** the buffer to make it large enough.
        !          2042:   */
        !          2043:   if( nReq>pWriter->nSize ){
        !          2044:     char *aNew = sqlite3_realloc(pWriter->aData, nReq);
        !          2045:     if( !aNew ) return SQLITE_NOMEM;
        !          2046:     pWriter->aData = aNew;
        !          2047:     pWriter->nSize = nReq;
        !          2048:   }
        !          2049:   assert( nData+nReq<=pWriter->nSize );
        !          2050: 
        !          2051:   /* Append the prefix-compressed term and doclist to the buffer. */
        !          2052:   nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix);
        !          2053:   nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix);
        !          2054:   memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix);
        !          2055:   nData += nSuffix;
        !          2056:   nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist);
        !          2057:   memcpy(&pWriter->aData[nData], aDoclist, nDoclist);
        !          2058:   pWriter->nData = nData + nDoclist;
        !          2059: 
        !          2060:   /* Save the current term so that it can be used to prefix-compress the next.
        !          2061:   ** If the isCopyTerm parameter is true, then the buffer pointed to by
        !          2062:   ** zTerm is transient, so take a copy of the term data. Otherwise, just
        !          2063:   ** store a copy of the pointer.
        !          2064:   */
        !          2065:   if( isCopyTerm ){
        !          2066:     if( nTerm>pWriter->nMalloc ){
        !          2067:       char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
        !          2068:       if( !zNew ){
        !          2069:         return SQLITE_NOMEM;
        !          2070:       }
        !          2071:       pWriter->nMalloc = nTerm*2;
        !          2072:       pWriter->zMalloc = zNew;
        !          2073:       pWriter->zTerm = zNew;
        !          2074:     }
        !          2075:     assert( pWriter->zTerm==pWriter->zMalloc );
        !          2076:     memcpy(pWriter->zTerm, zTerm, nTerm);
        !          2077:   }else{
        !          2078:     pWriter->zTerm = (char *)zTerm;
        !          2079:   }
        !          2080:   pWriter->nTerm = nTerm;
        !          2081: 
        !          2082:   return SQLITE_OK;
        !          2083: }
        !          2084: 
        !          2085: /*
        !          2086: ** Flush all data associated with the SegmentWriter object pWriter to the
        !          2087: ** database. This function must be called after all terms have been added
        !          2088: ** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is
        !          2089: ** returned. Otherwise, an SQLite error code.
        !          2090: */
        !          2091: static int fts3SegWriterFlush(
        !          2092:   Fts3Table *p,                   /* Virtual table handle */
        !          2093:   SegmentWriter *pWriter,         /* SegmentWriter to flush to the db */
        !          2094:   int iLevel,                     /* Value for 'level' column of %_segdir */
        !          2095:   int iIdx                        /* Value for 'idx' column of %_segdir */
        !          2096: ){
        !          2097:   int rc;                         /* Return code */
        !          2098:   if( pWriter->pTree ){
        !          2099:     sqlite3_int64 iLast = 0;      /* Largest block id written to database */
        !          2100:     sqlite3_int64 iLastLeaf;      /* Largest leaf block id written to db */
        !          2101:     char *zRoot = NULL;           /* Pointer to buffer containing root node */
        !          2102:     int nRoot = 0;                /* Size of buffer zRoot */
        !          2103: 
        !          2104:     iLastLeaf = pWriter->iFree;
        !          2105:     rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, pWriter->nData);
        !          2106:     if( rc==SQLITE_OK ){
        !          2107:       rc = fts3NodeWrite(p, pWriter->pTree, 1,
        !          2108:           pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot);
        !          2109:     }
        !          2110:     if( rc==SQLITE_OK ){
        !          2111:       rc = fts3WriteSegdir(
        !          2112:           p, iLevel, iIdx, pWriter->iFirst, iLastLeaf, iLast, zRoot, nRoot);
        !          2113:     }
        !          2114:   }else{
        !          2115:     /* The entire tree fits on the root node. Write it to the segdir table. */
        !          2116:     rc = fts3WriteSegdir(
        !          2117:         p, iLevel, iIdx, 0, 0, 0, pWriter->aData, pWriter->nData);
        !          2118:   }
        !          2119:   return rc;
        !          2120: }
        !          2121: 
        !          2122: /*
        !          2123: ** Release all memory held by the SegmentWriter object passed as the 
        !          2124: ** first argument.
        !          2125: */
        !          2126: static void fts3SegWriterFree(SegmentWriter *pWriter){
        !          2127:   if( pWriter ){
        !          2128:     sqlite3_free(pWriter->aData);
        !          2129:     sqlite3_free(pWriter->zMalloc);
        !          2130:     fts3NodeFree(pWriter->pTree);
        !          2131:     sqlite3_free(pWriter);
        !          2132:   }
        !          2133: }
        !          2134: 
        !          2135: /*
        !          2136: ** The first value in the apVal[] array is assumed to contain an integer.
        !          2137: ** This function tests if there exist any documents with docid values that
        !          2138: ** are different from that integer. i.e. if deleting the document with docid
        !          2139: ** pRowid would mean the FTS3 table were empty.
        !          2140: **
        !          2141: ** If successful, *pisEmpty is set to true if the table is empty except for
        !          2142: ** document pRowid, or false otherwise, and SQLITE_OK is returned. If an
        !          2143: ** error occurs, an SQLite error code is returned.
        !          2144: */
        !          2145: static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){
        !          2146:   sqlite3_stmt *pStmt;
        !          2147:   int rc;
        !          2148:   if( p->zContentTbl ){
        !          2149:     /* If using the content=xxx option, assume the table is never empty */
        !          2150:     *pisEmpty = 0;
        !          2151:     rc = SQLITE_OK;
        !          2152:   }else{
        !          2153:     rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
        !          2154:     if( rc==SQLITE_OK ){
        !          2155:       if( SQLITE_ROW==sqlite3_step(pStmt) ){
        !          2156:         *pisEmpty = sqlite3_column_int(pStmt, 0);
        !          2157:       }
        !          2158:       rc = sqlite3_reset(pStmt);
        !          2159:     }
        !          2160:   }
        !          2161:   return rc;
        !          2162: }
        !          2163: 
        !          2164: /*
        !          2165: ** Set *pnMax to the largest segment level in the database for the index
        !          2166: ** iIndex.
        !          2167: **
        !          2168: ** Segment levels are stored in the 'level' column of the %_segdir table.
        !          2169: **
        !          2170: ** Return SQLITE_OK if successful, or an SQLite error code if not.
        !          2171: */
        !          2172: static int fts3SegmentMaxLevel(Fts3Table *p, int iIndex, int *pnMax){
        !          2173:   sqlite3_stmt *pStmt;
        !          2174:   int rc;
        !          2175:   assert( iIndex>=0 && iIndex<p->nIndex );
        !          2176: 
        !          2177:   /* Set pStmt to the compiled version of:
        !          2178:   **
        !          2179:   **   SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?
        !          2180:   **
        !          2181:   ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR).
        !          2182:   */
        !          2183:   rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0);
        !          2184:   if( rc!=SQLITE_OK ) return rc;
        !          2185:   sqlite3_bind_int(pStmt, 1, iIndex*FTS3_SEGDIR_MAXLEVEL);
        !          2186:   sqlite3_bind_int(pStmt, 2, (iIndex+1)*FTS3_SEGDIR_MAXLEVEL - 1);
        !          2187:   if( SQLITE_ROW==sqlite3_step(pStmt) ){
        !          2188:     *pnMax = sqlite3_column_int(pStmt, 0);
        !          2189:   }
        !          2190:   return sqlite3_reset(pStmt);
        !          2191: }
        !          2192: 
        !          2193: /*
        !          2194: ** This function is used after merging multiple segments into a single large
        !          2195: ** segment to delete the old, now redundant, segment b-trees. Specifically,
        !          2196: ** it:
        !          2197: ** 
        !          2198: **   1) Deletes all %_segments entries for the segments associated with 
        !          2199: **      each of the SegReader objects in the array passed as the third 
        !          2200: **      argument, and
        !          2201: **
        !          2202: **   2) deletes all %_segdir entries with level iLevel, or all %_segdir
        !          2203: **      entries regardless of level if (iLevel<0).
        !          2204: **
        !          2205: ** SQLITE_OK is returned if successful, otherwise an SQLite error code.
        !          2206: */
        !          2207: static int fts3DeleteSegdir(
        !          2208:   Fts3Table *p,                   /* Virtual table handle */
        !          2209:   int iIndex,                     /* Index for p->aIndex */
        !          2210:   int iLevel,                     /* Level of %_segdir entries to delete */
        !          2211:   Fts3SegReader **apSegment,      /* Array of SegReader objects */
        !          2212:   int nReader                     /* Size of array apSegment */
        !          2213: ){
        !          2214:   int rc;                         /* Return Code */
        !          2215:   int i;                          /* Iterator variable */
        !          2216:   sqlite3_stmt *pDelete;          /* SQL statement to delete rows */
        !          2217: 
        !          2218:   rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0);
        !          2219:   for(i=0; rc==SQLITE_OK && i<nReader; i++){
        !          2220:     Fts3SegReader *pSegment = apSegment[i];
        !          2221:     if( pSegment->iStartBlock ){
        !          2222:       sqlite3_bind_int64(pDelete, 1, pSegment->iStartBlock);
        !          2223:       sqlite3_bind_int64(pDelete, 2, pSegment->iEndBlock);
        !          2224:       sqlite3_step(pDelete);
        !          2225:       rc = sqlite3_reset(pDelete);
        !          2226:     }
        !          2227:   }
        !          2228:   if( rc!=SQLITE_OK ){
        !          2229:     return rc;
        !          2230:   }
        !          2231: 
        !          2232:   assert( iLevel>=0 || iLevel==FTS3_SEGCURSOR_ALL );
        !          2233:   if( iLevel==FTS3_SEGCURSOR_ALL ){
        !          2234:     rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0);
        !          2235:     if( rc==SQLITE_OK ){
        !          2236:       sqlite3_bind_int(pDelete, 1, iIndex*FTS3_SEGDIR_MAXLEVEL);
        !          2237:       sqlite3_bind_int(pDelete, 2, (iIndex+1) * FTS3_SEGDIR_MAXLEVEL - 1);
        !          2238:     }
        !          2239:   }else{
        !          2240:     rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0);
        !          2241:     if( rc==SQLITE_OK ){
        !          2242:       sqlite3_bind_int(pDelete, 1, iIndex*FTS3_SEGDIR_MAXLEVEL + iLevel);
        !          2243:     }
        !          2244:   }
        !          2245: 
        !          2246:   if( rc==SQLITE_OK ){
        !          2247:     sqlite3_step(pDelete);
        !          2248:     rc = sqlite3_reset(pDelete);
        !          2249:   }
        !          2250: 
        !          2251:   return rc;
        !          2252: }
        !          2253: 
        !          2254: /*
        !          2255: ** When this function is called, buffer *ppList (size *pnList bytes) contains 
        !          2256: ** a position list that may (or may not) feature multiple columns. This
        !          2257: ** function adjusts the pointer *ppList and the length *pnList so that they
        !          2258: ** identify the subset of the position list that corresponds to column iCol.
        !          2259: **
        !          2260: ** If there are no entries in the input position list for column iCol, then
        !          2261: ** *pnList is set to zero before returning.
        !          2262: */
        !          2263: static void fts3ColumnFilter(
        !          2264:   int iCol,                       /* Column to filter on */
        !          2265:   char **ppList,                  /* IN/OUT: Pointer to position list */
        !          2266:   int *pnList                     /* IN/OUT: Size of buffer *ppList in bytes */
        !          2267: ){
        !          2268:   char *pList = *ppList;
        !          2269:   int nList = *pnList;
        !          2270:   char *pEnd = &pList[nList];
        !          2271:   int iCurrent = 0;
        !          2272:   char *p = pList;
        !          2273: 
        !          2274:   assert( iCol>=0 );
        !          2275:   while( 1 ){
        !          2276:     char c = 0;
        !          2277:     while( p<pEnd && (c | *p)&0xFE ) c = *p++ & 0x80;
        !          2278:   
        !          2279:     if( iCol==iCurrent ){
        !          2280:       nList = (int)(p - pList);
        !          2281:       break;
        !          2282:     }
        !          2283: 
        !          2284:     nList -= (int)(p - pList);
        !          2285:     pList = p;
        !          2286:     if( nList==0 ){
        !          2287:       break;
        !          2288:     }
        !          2289:     p = &pList[1];
        !          2290:     p += sqlite3Fts3GetVarint32(p, &iCurrent);
        !          2291:   }
        !          2292: 
        !          2293:   *ppList = pList;
        !          2294:   *pnList = nList;
        !          2295: }
        !          2296: 
        !          2297: /*
        !          2298: ** Cache data in the Fts3MultiSegReader.aBuffer[] buffer (overwriting any
        !          2299: ** existing data). Grow the buffer if required.
        !          2300: **
        !          2301: ** If successful, return SQLITE_OK. Otherwise, if an OOM error is encountered
        !          2302: ** trying to resize the buffer, return SQLITE_NOMEM.
        !          2303: */
        !          2304: static int fts3MsrBufferData(
        !          2305:   Fts3MultiSegReader *pMsr,       /* Multi-segment-reader handle */
        !          2306:   char *pList,
        !          2307:   int nList
        !          2308: ){
        !          2309:   if( nList>pMsr->nBuffer ){
        !          2310:     char *pNew;
        !          2311:     pMsr->nBuffer = nList*2;
        !          2312:     pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
        !          2313:     if( !pNew ) return SQLITE_NOMEM;
        !          2314:     pMsr->aBuffer = pNew;
        !          2315:   }
        !          2316: 
        !          2317:   memcpy(pMsr->aBuffer, pList, nList);
        !          2318:   return SQLITE_OK;
        !          2319: }
        !          2320: 
        !          2321: int sqlite3Fts3MsrIncrNext(
        !          2322:   Fts3Table *p,                   /* Virtual table handle */
        !          2323:   Fts3MultiSegReader *pMsr,       /* Multi-segment-reader handle */
        !          2324:   sqlite3_int64 *piDocid,         /* OUT: Docid value */
        !          2325:   char **paPoslist,               /* OUT: Pointer to position list */
        !          2326:   int *pnPoslist                  /* OUT: Size of position list in bytes */
        !          2327: ){
        !          2328:   int nMerge = pMsr->nAdvance;
        !          2329:   Fts3SegReader **apSegment = pMsr->apSegment;
        !          2330:   int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
        !          2331:     p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp
        !          2332:   );
        !          2333: 
        !          2334:   if( nMerge==0 ){
        !          2335:     *paPoslist = 0;
        !          2336:     return SQLITE_OK;
        !          2337:   }
        !          2338: 
        !          2339:   while( 1 ){
        !          2340:     Fts3SegReader *pSeg;
        !          2341:     pSeg = pMsr->apSegment[0];
        !          2342: 
        !          2343:     if( pSeg->pOffsetList==0 ){
        !          2344:       *paPoslist = 0;
        !          2345:       break;
        !          2346:     }else{
        !          2347:       int rc;
        !          2348:       char *pList;
        !          2349:       int nList;
        !          2350:       int j;
        !          2351:       sqlite3_int64 iDocid = apSegment[0]->iDocid;
        !          2352: 
        !          2353:       rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
        !          2354:       j = 1;
        !          2355:       while( rc==SQLITE_OK 
        !          2356:         && j<nMerge
        !          2357:         && apSegment[j]->pOffsetList
        !          2358:         && apSegment[j]->iDocid==iDocid
        !          2359:       ){
        !          2360:         rc = fts3SegReaderNextDocid(p, apSegment[j], 0, 0);
        !          2361:         j++;
        !          2362:       }
        !          2363:       if( rc!=SQLITE_OK ) return rc;
        !          2364:       fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
        !          2365: 
        !          2366:       if( pMsr->iColFilter>=0 ){
        !          2367:         fts3ColumnFilter(pMsr->iColFilter, &pList, &nList);
        !          2368:       }
        !          2369: 
        !          2370:       if( nList>0 ){
        !          2371:         if( fts3SegReaderIsPending(apSegment[0]) ){
        !          2372:           rc = fts3MsrBufferData(pMsr, pList, nList+1);
        !          2373:           if( rc!=SQLITE_OK ) return rc;
        !          2374:           *paPoslist = pMsr->aBuffer;
        !          2375:           assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
        !          2376:         }else{
        !          2377:           *paPoslist = pList;
        !          2378:         }
        !          2379:         *piDocid = iDocid;
        !          2380:         *pnPoslist = nList;
        !          2381:         break;
        !          2382:       }
        !          2383:     }
        !          2384:   }
        !          2385: 
        !          2386:   return SQLITE_OK;
        !          2387: }
        !          2388: 
        !          2389: static int fts3SegReaderStart(
        !          2390:   Fts3Table *p,                   /* Virtual table handle */
        !          2391:   Fts3MultiSegReader *pCsr,       /* Cursor object */
        !          2392:   const char *zTerm,              /* Term searched for (or NULL) */
        !          2393:   int nTerm                       /* Length of zTerm in bytes */
        !          2394: ){
        !          2395:   int i;
        !          2396:   int nSeg = pCsr->nSegment;
        !          2397: 
        !          2398:   /* If the Fts3SegFilter defines a specific term (or term prefix) to search 
        !          2399:   ** for, then advance each segment iterator until it points to a term of
        !          2400:   ** equal or greater value than the specified term. This prevents many
        !          2401:   ** unnecessary merge/sort operations for the case where single segment
        !          2402:   ** b-tree leaf nodes contain more than one term.
        !          2403:   */
        !          2404:   for(i=0; pCsr->bRestart==0 && i<pCsr->nSegment; i++){
        !          2405:     Fts3SegReader *pSeg = pCsr->apSegment[i];
        !          2406:     do {
        !          2407:       int rc = fts3SegReaderNext(p, pSeg, 0);
        !          2408:       if( rc!=SQLITE_OK ) return rc;
        !          2409:     }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 );
        !          2410:   }
        !          2411:   fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp);
        !          2412: 
        !          2413:   return SQLITE_OK;
        !          2414: }
        !          2415: 
        !          2416: int sqlite3Fts3SegReaderStart(
        !          2417:   Fts3Table *p,                   /* Virtual table handle */
        !          2418:   Fts3MultiSegReader *pCsr,       /* Cursor object */
        !          2419:   Fts3SegFilter *pFilter          /* Restrictions on range of iteration */
        !          2420: ){
        !          2421:   pCsr->pFilter = pFilter;
        !          2422:   return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm);
        !          2423: }
        !          2424: 
        !          2425: int sqlite3Fts3MsrIncrStart(
        !          2426:   Fts3Table *p,                   /* Virtual table handle */
        !          2427:   Fts3MultiSegReader *pCsr,       /* Cursor object */
        !          2428:   int iCol,                       /* Column to match on. */
        !          2429:   const char *zTerm,              /* Term to iterate through a doclist for */
        !          2430:   int nTerm                       /* Number of bytes in zTerm */
        !          2431: ){
        !          2432:   int i;
        !          2433:   int rc;
        !          2434:   int nSegment = pCsr->nSegment;
        !          2435:   int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
        !          2436:     p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp
        !          2437:   );
        !          2438: 
        !          2439:   assert( pCsr->pFilter==0 );
        !          2440:   assert( zTerm && nTerm>0 );
        !          2441: 
        !          2442:   /* Advance each segment iterator until it points to the term zTerm/nTerm. */
        !          2443:   rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm);
        !          2444:   if( rc!=SQLITE_OK ) return rc;
        !          2445: 
        !          2446:   /* Determine how many of the segments actually point to zTerm/nTerm. */
        !          2447:   for(i=0; i<nSegment; i++){
        !          2448:     Fts3SegReader *pSeg = pCsr->apSegment[i];
        !          2449:     if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){
        !          2450:       break;
        !          2451:     }
        !          2452:   }
        !          2453:   pCsr->nAdvance = i;
        !          2454: 
        !          2455:   /* Advance each of the segments to point to the first docid. */
        !          2456:   for(i=0; i<pCsr->nAdvance; i++){
        !          2457:     rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]);
        !          2458:     if( rc!=SQLITE_OK ) return rc;
        !          2459:   }
        !          2460:   fts3SegReaderSort(pCsr->apSegment, i, i, xCmp);
        !          2461: 
        !          2462:   assert( iCol<0 || iCol<p->nColumn );
        !          2463:   pCsr->iColFilter = iCol;
        !          2464: 
        !          2465:   return SQLITE_OK;
        !          2466: }
        !          2467: 
        !          2468: /*
        !          2469: ** This function is called on a MultiSegReader that has been started using
        !          2470: ** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also
        !          2471: ** have been made. Calling this function puts the MultiSegReader in such
        !          2472: ** a state that if the next two calls are:
        !          2473: **
        !          2474: **   sqlite3Fts3SegReaderStart()
        !          2475: **   sqlite3Fts3SegReaderStep()
        !          2476: **
        !          2477: ** then the entire doclist for the term is available in 
        !          2478: ** MultiSegReader.aDoclist/nDoclist.
        !          2479: */
        !          2480: int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){
        !          2481:   int i;                          /* Used to iterate through segment-readers */
        !          2482: 
        !          2483:   assert( pCsr->zTerm==0 );
        !          2484:   assert( pCsr->nTerm==0 );
        !          2485:   assert( pCsr->aDoclist==0 );
        !          2486:   assert( pCsr->nDoclist==0 );
        !          2487: 
        !          2488:   pCsr->nAdvance = 0;
        !          2489:   pCsr->bRestart = 1;
        !          2490:   for(i=0; i<pCsr->nSegment; i++){
        !          2491:     pCsr->apSegment[i]->pOffsetList = 0;
        !          2492:     pCsr->apSegment[i]->nOffsetList = 0;
        !          2493:     pCsr->apSegment[i]->iDocid = 0;
        !          2494:   }
        !          2495: 
        !          2496:   return SQLITE_OK;
        !          2497: }
        !          2498: 
        !          2499: 
        !          2500: int sqlite3Fts3SegReaderStep(
        !          2501:   Fts3Table *p,                   /* Virtual table handle */
        !          2502:   Fts3MultiSegReader *pCsr        /* Cursor object */
        !          2503: ){
        !          2504:   int rc = SQLITE_OK;
        !          2505: 
        !          2506:   int isIgnoreEmpty =  (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY);
        !          2507:   int isRequirePos =   (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS);
        !          2508:   int isColFilter =    (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER);
        !          2509:   int isPrefix =       (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX);
        !          2510:   int isScan =         (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN);
        !          2511:   int isFirst =        (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST);
        !          2512: 
        !          2513:   Fts3SegReader **apSegment = pCsr->apSegment;
        !          2514:   int nSegment = pCsr->nSegment;
        !          2515:   Fts3SegFilter *pFilter = pCsr->pFilter;
        !          2516:   int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
        !          2517:     p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp
        !          2518:   );
        !          2519: 
        !          2520:   if( pCsr->nSegment==0 ) return SQLITE_OK;
        !          2521: 
        !          2522:   do {
        !          2523:     int nMerge;
        !          2524:     int i;
        !          2525:   
        !          2526:     /* Advance the first pCsr->nAdvance entries in the apSegment[] array
        !          2527:     ** forward. Then sort the list in order of current term again.  
        !          2528:     */
        !          2529:     for(i=0; i<pCsr->nAdvance; i++){
        !          2530:       rc = fts3SegReaderNext(p, apSegment[i], 0);
        !          2531:       if( rc!=SQLITE_OK ) return rc;
        !          2532:     }
        !          2533:     fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp);
        !          2534:     pCsr->nAdvance = 0;
        !          2535: 
        !          2536:     /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */
        !          2537:     assert( rc==SQLITE_OK );
        !          2538:     if( apSegment[0]->aNode==0 ) break;
        !          2539: 
        !          2540:     pCsr->nTerm = apSegment[0]->nTerm;
        !          2541:     pCsr->zTerm = apSegment[0]->zTerm;
        !          2542: 
        !          2543:     /* If this is a prefix-search, and if the term that apSegment[0] points
        !          2544:     ** to does not share a suffix with pFilter->zTerm/nTerm, then all 
        !          2545:     ** required callbacks have been made. In this case exit early.
        !          2546:     **
        !          2547:     ** Similarly, if this is a search for an exact match, and the first term
        !          2548:     ** of segment apSegment[0] is not a match, exit early.
        !          2549:     */
        !          2550:     if( pFilter->zTerm && !isScan ){
        !          2551:       if( pCsr->nTerm<pFilter->nTerm 
        !          2552:        || (!isPrefix && pCsr->nTerm>pFilter->nTerm)
        !          2553:        || memcmp(pCsr->zTerm, pFilter->zTerm, pFilter->nTerm) 
        !          2554:       ){
        !          2555:         break;
        !          2556:       }
        !          2557:     }
        !          2558: 
        !          2559:     nMerge = 1;
        !          2560:     while( nMerge<nSegment 
        !          2561:         && apSegment[nMerge]->aNode
        !          2562:         && apSegment[nMerge]->nTerm==pCsr->nTerm 
        !          2563:         && 0==memcmp(pCsr->zTerm, apSegment[nMerge]->zTerm, pCsr->nTerm)
        !          2564:     ){
        !          2565:       nMerge++;
        !          2566:     }
        !          2567: 
        !          2568:     assert( isIgnoreEmpty || (isRequirePos && !isColFilter) );
        !          2569:     if( nMerge==1 
        !          2570:      && !isIgnoreEmpty 
        !          2571:      && !isFirst 
        !          2572:      && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
        !          2573:     ){
        !          2574:       pCsr->nDoclist = apSegment[0]->nDoclist;
        !          2575:       if( fts3SegReaderIsPending(apSegment[0]) ){
        !          2576:         rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
        !          2577:         pCsr->aDoclist = pCsr->aBuffer;
        !          2578:       }else{
        !          2579:         pCsr->aDoclist = apSegment[0]->aDoclist;
        !          2580:       }
        !          2581:       if( rc==SQLITE_OK ) rc = SQLITE_ROW;
        !          2582:     }else{
        !          2583:       int nDoclist = 0;           /* Size of doclist */
        !          2584:       sqlite3_int64 iPrev = 0;    /* Previous docid stored in doclist */
        !          2585: 
        !          2586:       /* The current term of the first nMerge entries in the array
        !          2587:       ** of Fts3SegReader objects is the same. The doclists must be merged
        !          2588:       ** and a single term returned with the merged doclist.
        !          2589:       */
        !          2590:       for(i=0; i<nMerge; i++){
        !          2591:         fts3SegReaderFirstDocid(p, apSegment[i]);
        !          2592:       }
        !          2593:       fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
        !          2594:       while( apSegment[0]->pOffsetList ){
        !          2595:         int j;                    /* Number of segments that share a docid */
        !          2596:         char *pList;
        !          2597:         int nList;
        !          2598:         int nByte;
        !          2599:         sqlite3_int64 iDocid = apSegment[0]->iDocid;
        !          2600:         fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
        !          2601:         j = 1;
        !          2602:         while( j<nMerge
        !          2603:             && apSegment[j]->pOffsetList
        !          2604:             && apSegment[j]->iDocid==iDocid
        !          2605:         ){
        !          2606:           fts3SegReaderNextDocid(p, apSegment[j], 0, 0);
        !          2607:           j++;
        !          2608:         }
        !          2609: 
        !          2610:         if( isColFilter ){
        !          2611:           fts3ColumnFilter(pFilter->iCol, &pList, &nList);
        !          2612:         }
        !          2613: 
        !          2614:         if( !isIgnoreEmpty || nList>0 ){
        !          2615: 
        !          2616:           /* Calculate the 'docid' delta value to write into the merged 
        !          2617:           ** doclist. */
        !          2618:           sqlite3_int64 iDelta;
        !          2619:           if( p->bDescIdx && nDoclist>0 ){
        !          2620:             iDelta = iPrev - iDocid;
        !          2621:           }else{
        !          2622:             iDelta = iDocid - iPrev;
        !          2623:           }
        !          2624:           assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) );
        !          2625:           assert( nDoclist>0 || iDelta==iDocid );
        !          2626: 
        !          2627:           nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
        !          2628:           if( nDoclist+nByte>pCsr->nBuffer ){
        !          2629:             char *aNew;
        !          2630:             pCsr->nBuffer = (nDoclist+nByte)*2;
        !          2631:             aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
        !          2632:             if( !aNew ){
        !          2633:               return SQLITE_NOMEM;
        !          2634:             }
        !          2635:             pCsr->aBuffer = aNew;
        !          2636:           }
        !          2637: 
        !          2638:           if( isFirst ){
        !          2639:             char *a = &pCsr->aBuffer[nDoclist];
        !          2640:             int nWrite;
        !          2641:            
        !          2642:             nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a);
        !          2643:             if( nWrite ){
        !          2644:               iPrev = iDocid;
        !          2645:               nDoclist += nWrite;
        !          2646:             }
        !          2647:           }else{
        !          2648:             nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
        !          2649:             iPrev = iDocid;
        !          2650:             if( isRequirePos ){
        !          2651:               memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
        !          2652:               nDoclist += nList;
        !          2653:               pCsr->aBuffer[nDoclist++] = '\0';
        !          2654:             }
        !          2655:           }
        !          2656:         }
        !          2657: 
        !          2658:         fts3SegReaderSort(apSegment, nMerge, j, xCmp);
        !          2659:       }
        !          2660:       if( nDoclist>0 ){
        !          2661:         pCsr->aDoclist = pCsr->aBuffer;
        !          2662:         pCsr->nDoclist = nDoclist;
        !          2663:         rc = SQLITE_ROW;
        !          2664:       }
        !          2665:     }
        !          2666:     pCsr->nAdvance = nMerge;
        !          2667:   }while( rc==SQLITE_OK );
        !          2668: 
        !          2669:   return rc;
        !          2670: }
        !          2671: 
        !          2672: 
        !          2673: void sqlite3Fts3SegReaderFinish(
        !          2674:   Fts3MultiSegReader *pCsr       /* Cursor object */
        !          2675: ){
        !          2676:   if( pCsr ){
        !          2677:     int i;
        !          2678:     for(i=0; i<pCsr->nSegment; i++){
        !          2679:       sqlite3Fts3SegReaderFree(pCsr->apSegment[i]);
        !          2680:     }
        !          2681:     sqlite3_free(pCsr->apSegment);
        !          2682:     sqlite3_free(pCsr->aBuffer);
        !          2683: 
        !          2684:     pCsr->nSegment = 0;
        !          2685:     pCsr->apSegment = 0;
        !          2686:     pCsr->aBuffer = 0;
        !          2687:   }
        !          2688: }
        !          2689: 
        !          2690: /*
        !          2691: ** Merge all level iLevel segments in the database into a single 
        !          2692: ** iLevel+1 segment. Or, if iLevel<0, merge all segments into a
        !          2693: ** single segment with a level equal to the numerically largest level 
        !          2694: ** currently present in the database.
        !          2695: **
        !          2696: ** If this function is called with iLevel<0, but there is only one
        !          2697: ** segment in the database, SQLITE_DONE is returned immediately. 
        !          2698: ** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, 
        !          2699: ** an SQLite error code is returned.
        !          2700: */
        !          2701: static int fts3SegmentMerge(Fts3Table *p, int iIndex, int iLevel){
        !          2702:   int rc;                         /* Return code */
        !          2703:   int iIdx = 0;                   /* Index of new segment */
        !          2704:   int iNewLevel = 0;              /* Level/index to create new segment at */
        !          2705:   SegmentWriter *pWriter = 0;     /* Used to write the new, merged, segment */
        !          2706:   Fts3SegFilter filter;           /* Segment term filter condition */
        !          2707:   Fts3MultiSegReader csr;        /* Cursor to iterate through level(s) */
        !          2708:   int bIgnoreEmpty = 0;           /* True to ignore empty segments */
        !          2709: 
        !          2710:   assert( iLevel==FTS3_SEGCURSOR_ALL
        !          2711:        || iLevel==FTS3_SEGCURSOR_PENDING
        !          2712:        || iLevel>=0
        !          2713:   );
        !          2714:   assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
        !          2715:   assert( iIndex>=0 && iIndex<p->nIndex );
        !          2716: 
        !          2717:   rc = sqlite3Fts3SegReaderCursor(p, iIndex, iLevel, 0, 0, 1, 0, &csr);
        !          2718:   if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished;
        !          2719: 
        !          2720:   if( iLevel==FTS3_SEGCURSOR_ALL ){
        !          2721:     /* This call is to merge all segments in the database to a single
        !          2722:     ** segment. The level of the new segment is equal to the the numerically 
        !          2723:     ** greatest segment level currently present in the database for this
        !          2724:     ** index. The idx of the new segment is always 0.  */
        !          2725:     if( csr.nSegment==1 ){
        !          2726:       rc = SQLITE_DONE;
        !          2727:       goto finished;
        !          2728:     }
        !          2729:     rc = fts3SegmentMaxLevel(p, iIndex, &iNewLevel);
        !          2730:     bIgnoreEmpty = 1;
        !          2731: 
        !          2732:   }else if( iLevel==FTS3_SEGCURSOR_PENDING ){
        !          2733:     iNewLevel = iIndex * FTS3_SEGDIR_MAXLEVEL; 
        !          2734:     rc = fts3AllocateSegdirIdx(p, iIndex, 0, &iIdx);
        !          2735:   }else{
        !          2736:     /* This call is to merge all segments at level iLevel. find the next
        !          2737:     ** available segment index at level iLevel+1. The call to
        !          2738:     ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to 
        !          2739:     ** a single iLevel+2 segment if necessary.  */
        !          2740:     rc = fts3AllocateSegdirIdx(p, iIndex, iLevel+1, &iIdx);
        !          2741:     iNewLevel = iIndex * FTS3_SEGDIR_MAXLEVEL + iLevel+1;
        !          2742:   }
        !          2743:   if( rc!=SQLITE_OK ) goto finished;
        !          2744:   assert( csr.nSegment>0 );
        !          2745:   assert( iNewLevel>=(iIndex*FTS3_SEGDIR_MAXLEVEL) );
        !          2746:   assert( iNewLevel<((iIndex+1)*FTS3_SEGDIR_MAXLEVEL) );
        !          2747: 
        !          2748:   memset(&filter, 0, sizeof(Fts3SegFilter));
        !          2749:   filter.flags = FTS3_SEGMENT_REQUIRE_POS;
        !          2750:   filter.flags |= (bIgnoreEmpty ? FTS3_SEGMENT_IGNORE_EMPTY : 0);
        !          2751: 
        !          2752:   rc = sqlite3Fts3SegReaderStart(p, &csr, &filter);
        !          2753:   while( SQLITE_OK==rc ){
        !          2754:     rc = sqlite3Fts3SegReaderStep(p, &csr);
        !          2755:     if( rc!=SQLITE_ROW ) break;
        !          2756:     rc = fts3SegWriterAdd(p, &pWriter, 1, 
        !          2757:         csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist);
        !          2758:   }
        !          2759:   if( rc!=SQLITE_OK ) goto finished;
        !          2760:   assert( pWriter );
        !          2761: 
        !          2762:   if( iLevel!=FTS3_SEGCURSOR_PENDING ){
        !          2763:     rc = fts3DeleteSegdir(p, iIndex, iLevel, csr.apSegment, csr.nSegment);
        !          2764:     if( rc!=SQLITE_OK ) goto finished;
        !          2765:   }
        !          2766:   rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx);
        !          2767: 
        !          2768:  finished:
        !          2769:   fts3SegWriterFree(pWriter);
        !          2770:   sqlite3Fts3SegReaderFinish(&csr);
        !          2771:   return rc;
        !          2772: }
        !          2773: 
        !          2774: 
        !          2775: /* 
        !          2776: ** Flush the contents of pendingTerms to level 0 segments.
        !          2777: */
        !          2778: int sqlite3Fts3PendingTermsFlush(Fts3Table *p){
        !          2779:   int rc = SQLITE_OK;
        !          2780:   int i;
        !          2781:   for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
        !          2782:     rc = fts3SegmentMerge(p, i, FTS3_SEGCURSOR_PENDING);
        !          2783:     if( rc==SQLITE_DONE ) rc = SQLITE_OK;
        !          2784:   }
        !          2785:   sqlite3Fts3PendingTermsClear(p);
        !          2786:   return rc;
        !          2787: }
        !          2788: 
        !          2789: /*
        !          2790: ** Encode N integers as varints into a blob.
        !          2791: */
        !          2792: static void fts3EncodeIntArray(
        !          2793:   int N,             /* The number of integers to encode */
        !          2794:   u32 *a,            /* The integer values */
        !          2795:   char *zBuf,        /* Write the BLOB here */
        !          2796:   int *pNBuf         /* Write number of bytes if zBuf[] used here */
        !          2797: ){
        !          2798:   int i, j;
        !          2799:   for(i=j=0; i<N; i++){
        !          2800:     j += sqlite3Fts3PutVarint(&zBuf[j], (sqlite3_int64)a[i]);
        !          2801:   }
        !          2802:   *pNBuf = j;
        !          2803: }
        !          2804: 
        !          2805: /*
        !          2806: ** Decode a blob of varints into N integers
        !          2807: */
        !          2808: static void fts3DecodeIntArray(
        !          2809:   int N,             /* The number of integers to decode */
        !          2810:   u32 *a,            /* Write the integer values */
        !          2811:   const char *zBuf,  /* The BLOB containing the varints */
        !          2812:   int nBuf           /* size of the BLOB */
        !          2813: ){
        !          2814:   int i, j;
        !          2815:   UNUSED_PARAMETER(nBuf);
        !          2816:   for(i=j=0; i<N; i++){
        !          2817:     sqlite3_int64 x;
        !          2818:     j += sqlite3Fts3GetVarint(&zBuf[j], &x);
        !          2819:     assert(j<=nBuf);
        !          2820:     a[i] = (u32)(x & 0xffffffff);
        !          2821:   }
        !          2822: }
        !          2823: 
        !          2824: /*
        !          2825: ** Insert the sizes (in tokens) for each column of the document
        !          2826: ** with docid equal to p->iPrevDocid.  The sizes are encoded as
        !          2827: ** a blob of varints.
        !          2828: */
        !          2829: static void fts3InsertDocsize(
        !          2830:   int *pRC,                       /* Result code */
        !          2831:   Fts3Table *p,                   /* Table into which to insert */
        !          2832:   u32 *aSz                        /* Sizes of each column, in tokens */
        !          2833: ){
        !          2834:   char *pBlob;             /* The BLOB encoding of the document size */
        !          2835:   int nBlob;               /* Number of bytes in the BLOB */
        !          2836:   sqlite3_stmt *pStmt;     /* Statement used to insert the encoding */
        !          2837:   int rc;                  /* Result code from subfunctions */
        !          2838: 
        !          2839:   if( *pRC ) return;
        !          2840:   pBlob = sqlite3_malloc( 10*p->nColumn );
        !          2841:   if( pBlob==0 ){
        !          2842:     *pRC = SQLITE_NOMEM;
        !          2843:     return;
        !          2844:   }
        !          2845:   fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob);
        !          2846:   rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0);
        !          2847:   if( rc ){
        !          2848:     sqlite3_free(pBlob);
        !          2849:     *pRC = rc;
        !          2850:     return;
        !          2851:   }
        !          2852:   sqlite3_bind_int64(pStmt, 1, p->iPrevDocid);
        !          2853:   sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, sqlite3_free);
        !          2854:   sqlite3_step(pStmt);
        !          2855:   *pRC = sqlite3_reset(pStmt);
        !          2856: }
        !          2857: 
        !          2858: /*
        !          2859: ** Record 0 of the %_stat table contains a blob consisting of N varints,
        !          2860: ** where N is the number of user defined columns in the fts3 table plus
        !          2861: ** two. If nCol is the number of user defined columns, then values of the 
        !          2862: ** varints are set as follows:
        !          2863: **
        !          2864: **   Varint 0:       Total number of rows in the table.
        !          2865: **
        !          2866: **   Varint 1..nCol: For each column, the total number of tokens stored in
        !          2867: **                   the column for all rows of the table.
        !          2868: **
        !          2869: **   Varint 1+nCol:  The total size, in bytes, of all text values in all
        !          2870: **                   columns of all rows of the table.
        !          2871: **
        !          2872: */
        !          2873: static void fts3UpdateDocTotals(
        !          2874:   int *pRC,                       /* The result code */
        !          2875:   Fts3Table *p,                   /* Table being updated */
        !          2876:   u32 *aSzIns,                    /* Size increases */
        !          2877:   u32 *aSzDel,                    /* Size decreases */
        !          2878:   int nChng                       /* Change in the number of documents */
        !          2879: ){
        !          2880:   char *pBlob;             /* Storage for BLOB written into %_stat */
        !          2881:   int nBlob;               /* Size of BLOB written into %_stat */
        !          2882:   u32 *a;                  /* Array of integers that becomes the BLOB */
        !          2883:   sqlite3_stmt *pStmt;     /* Statement for reading and writing */
        !          2884:   int i;                   /* Loop counter */
        !          2885:   int rc;                  /* Result code from subfunctions */
        !          2886: 
        !          2887:   const int nStat = p->nColumn+2;
        !          2888: 
        !          2889:   if( *pRC ) return;
        !          2890:   a = sqlite3_malloc( (sizeof(u32)+10)*nStat );
        !          2891:   if( a==0 ){
        !          2892:     *pRC = SQLITE_NOMEM;
        !          2893:     return;
        !          2894:   }
        !          2895:   pBlob = (char*)&a[nStat];
        !          2896:   rc = fts3SqlStmt(p, SQL_SELECT_DOCTOTAL, &pStmt, 0);
        !          2897:   if( rc ){
        !          2898:     sqlite3_free(a);
        !          2899:     *pRC = rc;
        !          2900:     return;
        !          2901:   }
        !          2902:   if( sqlite3_step(pStmt)==SQLITE_ROW ){
        !          2903:     fts3DecodeIntArray(nStat, a,
        !          2904:          sqlite3_column_blob(pStmt, 0),
        !          2905:          sqlite3_column_bytes(pStmt, 0));
        !          2906:   }else{
        !          2907:     memset(a, 0, sizeof(u32)*(nStat) );
        !          2908:   }
        !          2909:   sqlite3_reset(pStmt);
        !          2910:   if( nChng<0 && a[0]<(u32)(-nChng) ){
        !          2911:     a[0] = 0;
        !          2912:   }else{
        !          2913:     a[0] += nChng;
        !          2914:   }
        !          2915:   for(i=0; i<p->nColumn+1; i++){
        !          2916:     u32 x = a[i+1];
        !          2917:     if( x+aSzIns[i] < aSzDel[i] ){
        !          2918:       x = 0;
        !          2919:     }else{
        !          2920:       x = x + aSzIns[i] - aSzDel[i];
        !          2921:     }
        !          2922:     a[i+1] = x;
        !          2923:   }
        !          2924:   fts3EncodeIntArray(nStat, a, pBlob, &nBlob);
        !          2925:   rc = fts3SqlStmt(p, SQL_REPLACE_DOCTOTAL, &pStmt, 0);
        !          2926:   if( rc ){
        !          2927:     sqlite3_free(a);
        !          2928:     *pRC = rc;
        !          2929:     return;
        !          2930:   }
        !          2931:   sqlite3_bind_blob(pStmt, 1, pBlob, nBlob, SQLITE_STATIC);
        !          2932:   sqlite3_step(pStmt);
        !          2933:   *pRC = sqlite3_reset(pStmt);
        !          2934:   sqlite3_free(a);
        !          2935: }
        !          2936: 
        !          2937: static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
        !          2938:   int i;
        !          2939:   int bSeenDone = 0;
        !          2940:   int rc = SQLITE_OK;
        !          2941:   for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
        !          2942:     rc = fts3SegmentMerge(p, i, FTS3_SEGCURSOR_ALL);
        !          2943:     if( rc==SQLITE_DONE ){
        !          2944:       bSeenDone = 1;
        !          2945:       rc = SQLITE_OK;
        !          2946:     }
        !          2947:   }
        !          2948:   sqlite3Fts3SegmentsClose(p);
        !          2949:   sqlite3Fts3PendingTermsClear(p);
        !          2950: 
        !          2951:   return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc;
        !          2952: }
        !          2953: 
        !          2954: /*
        !          2955: ** This function is called when the user executes the following statement:
        !          2956: **
        !          2957: **     INSERT INTO <tbl>(<tbl>) VALUES('rebuild');
        !          2958: **
        !          2959: ** The entire FTS index is discarded and rebuilt. If the table is one 
        !          2960: ** created using the content=xxx option, then the new index is based on
        !          2961: ** the current contents of the xxx table. Otherwise, it is rebuilt based
        !          2962: ** on the contents of the %_content table.
        !          2963: */
        !          2964: static int fts3DoRebuild(Fts3Table *p){
        !          2965:   int rc;                         /* Return Code */
        !          2966: 
        !          2967:   rc = fts3DeleteAll(p, 0);
        !          2968:   if( rc==SQLITE_OK ){
        !          2969:     u32 *aSz = 0;
        !          2970:     u32 *aSzIns = 0;
        !          2971:     u32 *aSzDel = 0;
        !          2972:     sqlite3_stmt *pStmt = 0;
        !          2973:     int nEntry = 0;
        !          2974: 
        !          2975:     /* Compose and prepare an SQL statement to loop through the content table */
        !          2976:     char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
        !          2977:     if( !zSql ){
        !          2978:       rc = SQLITE_NOMEM;
        !          2979:     }else{
        !          2980:       rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
        !          2981:       sqlite3_free(zSql);
        !          2982:     }
        !          2983: 
        !          2984:     if( rc==SQLITE_OK ){
        !          2985:       int nByte = sizeof(u32) * (p->nColumn+1)*3;
        !          2986:       aSz = (u32 *)sqlite3_malloc(nByte);
        !          2987:       if( aSz==0 ){
        !          2988:         rc = SQLITE_NOMEM;
        !          2989:       }else{
        !          2990:         memset(aSz, 0, nByte);
        !          2991:         aSzIns = &aSz[p->nColumn+1];
        !          2992:         aSzDel = &aSzIns[p->nColumn+1];
        !          2993:       }
        !          2994:     }
        !          2995: 
        !          2996:     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
        !          2997:       int iCol;
        !          2998:       rc = fts3PendingTermsDocid(p, sqlite3_column_int64(pStmt, 0));
        !          2999:       aSz[p->nColumn] = 0;
        !          3000:       for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
        !          3001:         const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
        !          3002:         rc = fts3PendingTermsAdd(p, z, iCol, &aSz[iCol]);
        !          3003:         aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
        !          3004:       }
        !          3005:       if( p->bHasDocsize ){
        !          3006:         fts3InsertDocsize(&rc, p, aSz);
        !          3007:       }
        !          3008:       if( rc!=SQLITE_OK ){
        !          3009:         sqlite3_finalize(pStmt);
        !          3010:         pStmt = 0;
        !          3011:       }else{
        !          3012:         nEntry++;
        !          3013:         for(iCol=0; iCol<=p->nColumn; iCol++){
        !          3014:           aSzIns[iCol] += aSz[iCol];
        !          3015:         }
        !          3016:       }
        !          3017:     }
        !          3018:     if( p->bHasStat ){
        !          3019:       fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry);
        !          3020:     }
        !          3021:     sqlite3_free(aSz);
        !          3022: 
        !          3023:     if( pStmt ){
        !          3024:       int rc2 = sqlite3_finalize(pStmt);
        !          3025:       if( rc==SQLITE_OK ){
        !          3026:         rc = rc2;
        !          3027:       }
        !          3028:     }
        !          3029:   }
        !          3030: 
        !          3031:   return rc;
        !          3032: }
        !          3033: 
        !          3034: /*
        !          3035: ** Handle a 'special' INSERT of the form:
        !          3036: **
        !          3037: **   "INSERT INTO tbl(tbl) VALUES(<expr>)"
        !          3038: **
        !          3039: ** Argument pVal contains the result of <expr>. Currently the only 
        !          3040: ** meaningful value to insert is the text 'optimize'.
        !          3041: */
        !          3042: static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
        !          3043:   int rc;                         /* Return Code */
        !          3044:   const char *zVal = (const char *)sqlite3_value_text(pVal);
        !          3045:   int nVal = sqlite3_value_bytes(pVal);
        !          3046: 
        !          3047:   if( !zVal ){
        !          3048:     return SQLITE_NOMEM;
        !          3049:   }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){
        !          3050:     rc = fts3DoOptimize(p, 0);
        !          3051:   }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){
        !          3052:     rc = fts3DoRebuild(p);
        !          3053: #ifdef SQLITE_TEST
        !          3054:   }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
        !          3055:     p->nNodeSize = atoi(&zVal[9]);
        !          3056:     rc = SQLITE_OK;
        !          3057:   }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
        !          3058:     p->nMaxPendingData = atoi(&zVal[11]);
        !          3059:     rc = SQLITE_OK;
        !          3060: #endif
        !          3061:   }else{
        !          3062:     rc = SQLITE_ERROR;
        !          3063:   }
        !          3064: 
        !          3065:   return rc;
        !          3066: }
        !          3067: 
        !          3068: /*
        !          3069: ** Delete all cached deferred doclists. Deferred doclists are cached
        !          3070: ** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.
        !          3071: */
        !          3072: void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){
        !          3073:   Fts3DeferredToken *pDef;
        !          3074:   for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){
        !          3075:     fts3PendingListDelete(pDef->pList);
        !          3076:     pDef->pList = 0;
        !          3077:   }
        !          3078: }
        !          3079: 
        !          3080: /*
        !          3081: ** Free all entries in the pCsr->pDeffered list. Entries are added to 
        !          3082: ** this list using sqlite3Fts3DeferToken().
        !          3083: */
        !          3084: void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){
        !          3085:   Fts3DeferredToken *pDef;
        !          3086:   Fts3DeferredToken *pNext;
        !          3087:   for(pDef=pCsr->pDeferred; pDef; pDef=pNext){
        !          3088:     pNext = pDef->pNext;
        !          3089:     fts3PendingListDelete(pDef->pList);
        !          3090:     sqlite3_free(pDef);
        !          3091:   }
        !          3092:   pCsr->pDeferred = 0;
        !          3093: }
        !          3094: 
        !          3095: /*
        !          3096: ** Generate deferred-doclists for all tokens in the pCsr->pDeferred list
        !          3097: ** based on the row that pCsr currently points to.
        !          3098: **
        !          3099: ** A deferred-doclist is like any other doclist with position information
        !          3100: ** included, except that it only contains entries for a single row of the
        !          3101: ** table, not for all rows.
        !          3102: */
        !          3103: int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
        !          3104:   int rc = SQLITE_OK;             /* Return code */
        !          3105:   if( pCsr->pDeferred ){
        !          3106:     int i;                        /* Used to iterate through table columns */
        !          3107:     sqlite3_int64 iDocid;         /* Docid of the row pCsr points to */
        !          3108:     Fts3DeferredToken *pDef;      /* Used to iterate through deferred tokens */
        !          3109:   
        !          3110:     Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
        !          3111:     sqlite3_tokenizer *pT = p->pTokenizer;
        !          3112:     sqlite3_tokenizer_module const *pModule = pT->pModule;
        !          3113:    
        !          3114:     assert( pCsr->isRequireSeek==0 );
        !          3115:     iDocid = sqlite3_column_int64(pCsr->pStmt, 0);
        !          3116:   
        !          3117:     for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){
        !          3118:       const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
        !          3119:       sqlite3_tokenizer_cursor *pTC = 0;
        !          3120:   
        !          3121:       rc = pModule->xOpen(pT, zText, -1, &pTC);
        !          3122:       while( rc==SQLITE_OK ){
        !          3123:         char const *zToken;       /* Buffer containing token */
        !          3124:         int nToken;               /* Number of bytes in token */
        !          3125:         int iDum1, iDum2;         /* Dummy variables */
        !          3126:         int iPos;                 /* Position of token in zText */
        !          3127:   
        !          3128:         pTC->pTokenizer = pT;
        !          3129:         rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
        !          3130:         for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
        !          3131:           Fts3PhraseToken *pPT = pDef->pToken;
        !          3132:           if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
        !          3133:            && (pPT->bFirst==0 || iPos==0)
        !          3134:            && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
        !          3135:            && (0==memcmp(zToken, pPT->z, pPT->n))
        !          3136:           ){
        !          3137:             fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
        !          3138:           }
        !          3139:         }
        !          3140:       }
        !          3141:       if( pTC ) pModule->xClose(pTC);
        !          3142:       if( rc==SQLITE_DONE ) rc = SQLITE_OK;
        !          3143:     }
        !          3144:   
        !          3145:     for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
        !          3146:       if( pDef->pList ){
        !          3147:         rc = fts3PendingListAppendVarint(&pDef->pList, 0);
        !          3148:       }
        !          3149:     }
        !          3150:   }
        !          3151: 
        !          3152:   return rc;
        !          3153: }
        !          3154: 
        !          3155: int sqlite3Fts3DeferredTokenList(
        !          3156:   Fts3DeferredToken *p, 
        !          3157:   char **ppData, 
        !          3158:   int *pnData
        !          3159: ){
        !          3160:   char *pRet;
        !          3161:   int nSkip;
        !          3162:   sqlite3_int64 dummy;
        !          3163: 
        !          3164:   *ppData = 0;
        !          3165:   *pnData = 0;
        !          3166: 
        !          3167:   if( p->pList==0 ){
        !          3168:     return SQLITE_OK;
        !          3169:   }
        !          3170: 
        !          3171:   pRet = (char *)sqlite3_malloc(p->pList->nData);
        !          3172:   if( !pRet ) return SQLITE_NOMEM;
        !          3173: 
        !          3174:   nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
        !          3175:   *pnData = p->pList->nData - nSkip;
        !          3176:   *ppData = pRet;
        !          3177:   
        !          3178:   memcpy(pRet, &p->pList->aData[nSkip], *pnData);
        !          3179:   return SQLITE_OK;
        !          3180: }
        !          3181: 
        !          3182: /*
        !          3183: ** Add an entry for token pToken to the pCsr->pDeferred list.
        !          3184: */
        !          3185: int sqlite3Fts3DeferToken(
        !          3186:   Fts3Cursor *pCsr,               /* Fts3 table cursor */
        !          3187:   Fts3PhraseToken *pToken,        /* Token to defer */
        !          3188:   int iCol                        /* Column that token must appear in (or -1) */
        !          3189: ){
        !          3190:   Fts3DeferredToken *pDeferred;
        !          3191:   pDeferred = sqlite3_malloc(sizeof(*pDeferred));
        !          3192:   if( !pDeferred ){
        !          3193:     return SQLITE_NOMEM;
        !          3194:   }
        !          3195:   memset(pDeferred, 0, sizeof(*pDeferred));
        !          3196:   pDeferred->pToken = pToken;
        !          3197:   pDeferred->pNext = pCsr->pDeferred; 
        !          3198:   pDeferred->iCol = iCol;
        !          3199:   pCsr->pDeferred = pDeferred;
        !          3200: 
        !          3201:   assert( pToken->pDeferred==0 );
        !          3202:   pToken->pDeferred = pDeferred;
        !          3203: 
        !          3204:   return SQLITE_OK;
        !          3205: }
        !          3206: 
        !          3207: /*
        !          3208: ** SQLite value pRowid contains the rowid of a row that may or may not be
        !          3209: ** present in the FTS3 table. If it is, delete it and adjust the contents
        !          3210: ** of subsiduary data structures accordingly.
        !          3211: */
        !          3212: static int fts3DeleteByRowid(
        !          3213:   Fts3Table *p, 
        !          3214:   sqlite3_value *pRowid, 
        !          3215:   int *pnDoc,
        !          3216:   u32 *aSzDel
        !          3217: ){
        !          3218:   int isEmpty = 0;
        !          3219:   int rc = fts3IsEmpty(p, pRowid, &isEmpty);
        !          3220:   if( rc==SQLITE_OK ){
        !          3221:     if( isEmpty ){
        !          3222:       /* Deleting this row means the whole table is empty. In this case
        !          3223:       ** delete the contents of all three tables and throw away any
        !          3224:       ** data in the pendingTerms hash table.  */
        !          3225:       rc = fts3DeleteAll(p, 1);
        !          3226:       *pnDoc = *pnDoc - 1;
        !          3227:     }else{
        !          3228:       sqlite3_int64 iRemove = sqlite3_value_int64(pRowid);
        !          3229:       rc = fts3PendingTermsDocid(p, iRemove);
        !          3230:       fts3DeleteTerms(&rc, p, pRowid, aSzDel);
        !          3231:       if( p->zContentTbl==0 ){
        !          3232:         fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
        !          3233:         if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
        !          3234:       }else{
        !          3235:         *pnDoc = *pnDoc - 1;
        !          3236:       }
        !          3237:       if( p->bHasDocsize ){
        !          3238:         fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
        !          3239:       }
        !          3240:     }
        !          3241:   }
        !          3242: 
        !          3243:   return rc;
        !          3244: }
        !          3245: 
        !          3246: /*
        !          3247: ** This function does the work for the xUpdate method of FTS3 virtual
        !          3248: ** tables.
        !          3249: */
        !          3250: int sqlite3Fts3UpdateMethod(
        !          3251:   sqlite3_vtab *pVtab,            /* FTS3 vtab object */
        !          3252:   int nArg,                       /* Size of argument array */
        !          3253:   sqlite3_value **apVal,          /* Array of arguments */
        !          3254:   sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
        !          3255: ){
        !          3256:   Fts3Table *p = (Fts3Table *)pVtab;
        !          3257:   int rc = SQLITE_OK;             /* Return Code */
        !          3258:   int isRemove = 0;               /* True for an UPDATE or DELETE */
        !          3259:   u32 *aSzIns = 0;                /* Sizes of inserted documents */
        !          3260:   u32 *aSzDel;                    /* Sizes of deleted documents */
        !          3261:   int nChng = 0;                  /* Net change in number of documents */
        !          3262:   int bInsertDone = 0;
        !          3263: 
        !          3264:   assert( p->pSegments==0 );
        !          3265: 
        !          3266:   /* Check for a "special" INSERT operation. One of the form:
        !          3267:   **
        !          3268:   **   INSERT INTO xyz(xyz) VALUES('command');
        !          3269:   */
        !          3270:   if( nArg>1 
        !          3271:    && sqlite3_value_type(apVal[0])==SQLITE_NULL 
        !          3272:    && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL 
        !          3273:   ){
        !          3274:     rc = fts3SpecialInsert(p, apVal[p->nColumn+2]);
        !          3275:     goto update_out;
        !          3276:   }
        !          3277: 
        !          3278:   /* Allocate space to hold the change in document sizes */
        !          3279:   aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 );
        !          3280:   if( aSzIns==0 ){
        !          3281:     rc = SQLITE_NOMEM;
        !          3282:     goto update_out;
        !          3283:   }
        !          3284:   aSzDel = &aSzIns[p->nColumn+1];
        !          3285:   memset(aSzIns, 0, sizeof(aSzIns[0])*(p->nColumn+1)*2);
        !          3286: 
        !          3287:   /* If this is an INSERT operation, or an UPDATE that modifies the rowid
        !          3288:   ** value, then this operation requires constraint handling.
        !          3289:   **
        !          3290:   ** If the on-conflict mode is REPLACE, this means that the existing row
        !          3291:   ** should be deleted from the database before inserting the new row. Or,
        !          3292:   ** if the on-conflict mode is other than REPLACE, then this method must
        !          3293:   ** detect the conflict and return SQLITE_CONSTRAINT before beginning to
        !          3294:   ** modify the database file.
        !          3295:   */
        !          3296:   if( nArg>1 && p->zContentTbl==0 ){
        !          3297:     /* Find the value object that holds the new rowid value. */
        !          3298:     sqlite3_value *pNewRowid = apVal[3+p->nColumn];
        !          3299:     if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){
        !          3300:       pNewRowid = apVal[1];
        !          3301:     }
        !          3302: 
        !          3303:     if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( 
        !          3304:         sqlite3_value_type(apVal[0])==SQLITE_NULL
        !          3305:      || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid)
        !          3306:     )){
        !          3307:       /* The new rowid is not NULL (in this case the rowid will be
        !          3308:       ** automatically assigned and there is no chance of a conflict), and 
        !          3309:       ** the statement is either an INSERT or an UPDATE that modifies the
        !          3310:       ** rowid column. So if the conflict mode is REPLACE, then delete any
        !          3311:       ** existing row with rowid=pNewRowid. 
        !          3312:       **
        !          3313:       ** Or, if the conflict mode is not REPLACE, insert the new record into 
        !          3314:       ** the %_content table. If we hit the duplicate rowid constraint (or any
        !          3315:       ** other error) while doing so, return immediately.
        !          3316:       **
        !          3317:       ** This branch may also run if pNewRowid contains a value that cannot
        !          3318:       ** be losslessly converted to an integer. In this case, the eventual 
        !          3319:       ** call to fts3InsertData() (either just below or further on in this
        !          3320:       ** function) will return SQLITE_MISMATCH. If fts3DeleteByRowid is 
        !          3321:       ** invoked, it will delete zero rows (since no row will have
        !          3322:       ** docid=$pNewRowid if $pNewRowid is not an integer value).
        !          3323:       */
        !          3324:       if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){
        !          3325:         rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel);
        !          3326:       }else{
        !          3327:         rc = fts3InsertData(p, apVal, pRowid);
        !          3328:         bInsertDone = 1;
        !          3329:       }
        !          3330:     }
        !          3331:   }
        !          3332:   if( rc!=SQLITE_OK ){
        !          3333:     goto update_out;
        !          3334:   }
        !          3335: 
        !          3336:   /* If this is a DELETE or UPDATE operation, remove the old record. */
        !          3337:   if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
        !          3338:     assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
        !          3339:     rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
        !          3340:     isRemove = 1;
        !          3341:   }
        !          3342:   
        !          3343:   /* If this is an INSERT or UPDATE operation, insert the new record. */
        !          3344:   if( nArg>1 && rc==SQLITE_OK ){
        !          3345:     if( bInsertDone==0 ){
        !          3346:       rc = fts3InsertData(p, apVal, pRowid);
        !          3347:       if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
        !          3348:         rc = FTS_CORRUPT_VTAB;
        !          3349:       }
        !          3350:     }
        !          3351:     if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
        !          3352:       rc = fts3PendingTermsDocid(p, *pRowid);
        !          3353:     }
        !          3354:     if( rc==SQLITE_OK ){
        !          3355:       assert( p->iPrevDocid==*pRowid );
        !          3356:       rc = fts3InsertTerms(p, apVal, aSzIns);
        !          3357:     }
        !          3358:     if( p->bHasDocsize ){
        !          3359:       fts3InsertDocsize(&rc, p, aSzIns);
        !          3360:     }
        !          3361:     nChng++;
        !          3362:   }
        !          3363: 
        !          3364:   if( p->bHasStat ){
        !          3365:     fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng);
        !          3366:   }
        !          3367: 
        !          3368:  update_out:
        !          3369:   sqlite3_free(aSzIns);
        !          3370:   sqlite3Fts3SegmentsClose(p);
        !          3371:   return rc;
        !          3372: }
        !          3373: 
        !          3374: /* 
        !          3375: ** Flush any data in the pending-terms hash table to disk. If successful,
        !          3376: ** merge all segments in the database (including the new segment, if 
        !          3377: ** there was any data to flush) into a single segment. 
        !          3378: */
        !          3379: int sqlite3Fts3Optimize(Fts3Table *p){
        !          3380:   int rc;
        !          3381:   rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0);
        !          3382:   if( rc==SQLITE_OK ){
        !          3383:     rc = fts3DoOptimize(p, 1);
        !          3384:     if( rc==SQLITE_OK || rc==SQLITE_DONE ){
        !          3385:       int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0);
        !          3386:       if( rc2!=SQLITE_OK ) rc = rc2;
        !          3387:     }else{
        !          3388:       sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0);
        !          3389:       sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0);
        !          3390:     }
        !          3391:   }
        !          3392:   sqlite3Fts3SegmentsClose(p);
        !          3393:   return rc;
        !          3394: }
        !          3395: 
        !          3396: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>