| Index: third_party/sqlite/src/ext/fts3/fts3.c
|
| diff --git a/third_party/sqlite/src/ext/fts3/fts3.c b/third_party/sqlite/src/ext/fts3/fts3.c
|
| index a8d16a9a2163a105c3d693b00223447e0e8105cb..2a24b78f37835c3a6079443598ec3ea2c246b2d3 100644
|
| --- a/third_party/sqlite/src/ext/fts3/fts3.c
|
| +++ b/third_party/sqlite/src/ext/fts3/fts3.c
|
| @@ -493,6 +493,7 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
|
| assert( p->pSegments==0 );
|
|
|
| /* Free any prepared statements held */
|
| + sqlite3_finalize(p->pSeekStmt);
|
| for(i=0; i<SizeofArray(p->aStmt); i++){
|
| sqlite3_finalize(p->aStmt[i]);
|
| }
|
| @@ -1364,9 +1365,9 @@ static int fts3InitVtab(
|
| p->pTokenizer = pTokenizer;
|
| p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
|
| p->bHasDocsize = (isFts4 && bNoDocsize==0);
|
| - p->bHasStat = isFts4;
|
| - p->bFts4 = isFts4;
|
| - p->bDescIdx = bDescIdx;
|
| + p->bHasStat = (u8)isFts4;
|
| + p->bFts4 = (u8)isFts4;
|
| + p->bDescIdx = (u8)bDescIdx;
|
| p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */
|
| p->zContentTbl = zContent;
|
| p->zLanguageid = zLanguageid;
|
| @@ -1682,13 +1683,33 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
|
| }
|
|
|
| /*
|
| +** Finalize the statement handle at pCsr->pStmt.
|
| +**
|
| +** Or, if that statement handle is one created by fts3CursorSeekStmt(),
|
| +** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
|
| +** pointer there instead of finalizing it.
|
| +*/
|
| +static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
|
| + if( pCsr->bSeekStmt ){
|
| + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
|
| + if( p->pSeekStmt==0 ){
|
| + p->pSeekStmt = pCsr->pStmt;
|
| + sqlite3_reset(pCsr->pStmt);
|
| + pCsr->pStmt = 0;
|
| + }
|
| + pCsr->bSeekStmt = 0;
|
| + }
|
| + sqlite3_finalize(pCsr->pStmt);
|
| +}
|
| +
|
| +/*
|
| ** Close the cursor. For additional information see the documentation
|
| ** on the xClose method of the virtual table interface.
|
| */
|
| static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
| Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
|
| assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
| - sqlite3_finalize(pCsr->pStmt);
|
| + fts3CursorFinalizeStmt(pCsr);
|
| sqlite3Fts3ExprFree(pCsr->pExpr);
|
| sqlite3Fts3FreeDeferredTokens(pCsr);
|
| sqlite3_free(pCsr->aDoclist);
|
| @@ -1706,20 +1727,23 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
| **
|
| ** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
|
| ** it. If an error occurs, return an SQLite error code.
|
| -**
|
| -** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
|
| */
|
| -static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
|
| +static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
|
| int rc = SQLITE_OK;
|
| if( pCsr->pStmt==0 ){
|
| Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
|
| char *zSql;
|
| - zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
|
| - if( !zSql ) return SQLITE_NOMEM;
|
| - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
|
| - sqlite3_free(zSql);
|
| + if( p->pSeekStmt ){
|
| + pCsr->pStmt = p->pSeekStmt;
|
| + p->pSeekStmt = 0;
|
| + }else{
|
| + zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
|
| + if( !zSql ) return SQLITE_NOMEM;
|
| + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
|
| + sqlite3_free(zSql);
|
| + }
|
| + if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
|
| }
|
| - *ppStmt = pCsr->pStmt;
|
| return rc;
|
| }
|
|
|
| @@ -1731,9 +1755,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
|
| static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
|
| int rc = SQLITE_OK;
|
| if( pCsr->isRequireSeek ){
|
| - sqlite3_stmt *pStmt = 0;
|
| -
|
| - rc = fts3CursorSeekStmt(pCsr, &pStmt);
|
| + rc = fts3CursorSeekStmt(pCsr);
|
| if( rc==SQLITE_OK ){
|
| sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
|
| pCsr->isRequireSeek = 0;
|
| @@ -1829,7 +1851,7 @@ static int fts3ScanInteriorNode(
|
| */
|
| if( nPrefix<0 || nSuffix<0 /* || nPrefix>nBuffer */
|
| || &zCsr[nSuffix]<zCsr || &zCsr[nSuffix]>zEnd ){
|
| - rc = SQLITE_CORRUPT;
|
| + rc = FTS_CORRUPT_VTAB;
|
| goto finish_scan;
|
| }
|
| if( nPrefix+nSuffix>nAlloc ){
|
| @@ -3197,7 +3219,7 @@ static int fts3FilterMethod(
|
| assert( iIdx==nVal );
|
|
|
| /* In case the cursor has been used before, clear it now. */
|
| - sqlite3_finalize(pCsr->pStmt);
|
| + fts3CursorFinalizeStmt(pCsr);
|
| sqlite3_free(pCsr->aDoclist);
|
| sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
| sqlite3Fts3ExprFree(pCsr->pExpr);
|
| @@ -3265,7 +3287,7 @@ static int fts3FilterMethod(
|
| rc = SQLITE_NOMEM;
|
| }
|
| }else if( eSearch==FTS3_DOCID_SEARCH ){
|
| - rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
|
| + rc = fts3CursorSeekStmt(pCsr);
|
| if( rc==SQLITE_OK ){
|
| rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
|
| }
|
| @@ -3429,7 +3451,7 @@ static int fts3SetHasStat(Fts3Table *p){
|
| if( rc==SQLITE_OK ){
|
| int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
|
| rc = sqlite3_finalize(pStmt);
|
| - if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
|
| + if( rc==SQLITE_OK ) p->bHasStat = (u8)bHasStat;
|
| }
|
| sqlite3_free(zSql);
|
| }else{
|
|
|