mirror of https://github.com/sqlite/sqlite
Convert fts2 to use sqlite3_prepare_v2() to prevent certain logic
errors around SQLITE_SCHEMA handling. This also allows sql_step_statement() and sql_step_leaf_statement() to be replaced with sqlite3_step(). Also fix a logic error in flushPendingTerms() which was clearing the term table in case of error. This was wrong in the face of SQLITE_SCHEMA. Even though the change to sqlite3_prepare_v2() should cause us not to see SQLITE_SCHEMA any longer, it was still a logic error... (CVS 4205) FossilOrigin-Name: 16730cb137eaf576b87cdc17913564c9c5c0ed82
This commit is contained in:
parent
9a47736e47
commit
9fa502205d
106
ext/fts2/fts2.c
106
ext/fts2/fts2.c
|
@ -1649,7 +1649,7 @@ static int sql_prepare(sqlite3 *db, const char *zDb, const char *zName,
|
||||||
char *zCommand = string_format(zFormat, zDb, zName);
|
char *zCommand = string_format(zFormat, zDb, zName);
|
||||||
int rc;
|
int rc;
|
||||||
TRACE(("FTS2 prepare: %s\n", zCommand));
|
TRACE(("FTS2 prepare: %s\n", zCommand));
|
||||||
rc = sqlite3_prepare(db, zCommand, -1, ppStmt, NULL);
|
rc = sqlite3_prepare_v2(db, zCommand, -1, ppStmt, NULL);
|
||||||
free(zCommand);
|
free(zCommand);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -1925,44 +1925,12 @@ static int sql_get_statement(fulltext_vtab *v, fulltext_statement iStmt,
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step the indicated statement, handling errors SQLITE_BUSY (by
|
/* Like sqlite3_step(), but convert SQLITE_DONE to SQLITE_OK and
|
||||||
** retrying) and SQLITE_SCHEMA (by re-preparing and transferring
|
** SQLITE_ROW to SQLITE_ERROR. Useful for statements like UPDATE,
|
||||||
** bindings to the new statement).
|
** where we expect no results.
|
||||||
** TODO(adam): We should extend this function so that it can work with
|
|
||||||
** statements declared locally, not only globally cached statements.
|
|
||||||
*/
|
*/
|
||||||
static int sql_step_statement(fulltext_vtab *v, fulltext_statement iStmt,
|
static int sql_single_step(sqlite3_stmt *s){
|
||||||
sqlite3_stmt **ppStmt){
|
int rc = sqlite3_step(s);
|
||||||
int rc;
|
|
||||||
sqlite3_stmt *s = *ppStmt;
|
|
||||||
assert( iStmt<MAX_STMT );
|
|
||||||
assert( s==v->pFulltextStatements[iStmt] );
|
|
||||||
|
|
||||||
while( (rc=sqlite3_step(s))!=SQLITE_DONE && rc!=SQLITE_ROW ){
|
|
||||||
|
|
||||||
if( rc==SQLITE_BUSY ) continue;
|
|
||||||
if( rc!=SQLITE_ERROR ) return rc;
|
|
||||||
|
|
||||||
/* If an SQLITE_SCHEMA error has occured, then finalizing this
|
|
||||||
* statement is going to delete the fulltext_vtab structure. If
|
|
||||||
* the statement just executed is in the pFulltextStatements[]
|
|
||||||
* array, it will be finalized twice. So remove it before
|
|
||||||
* calling sqlite3_finalize().
|
|
||||||
*/
|
|
||||||
v->pFulltextStatements[iStmt] = NULL;
|
|
||||||
rc = sqlite3_finalize(s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Like sql_step_statement(), but convert SQLITE_DONE to SQLITE_OK.
|
|
||||||
** Useful for statements like UPDATE, where we expect no results.
|
|
||||||
*/
|
|
||||||
static int sql_single_step_statement(fulltext_vtab *v,
|
|
||||||
fulltext_statement iStmt,
|
|
||||||
sqlite3_stmt **ppStmt){
|
|
||||||
int rc = sql_step_statement(v, iStmt, ppStmt);
|
|
||||||
return (rc==SQLITE_DONE) ? SQLITE_OK : rc;
|
return (rc==SQLITE_DONE) ? SQLITE_OK : rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1988,36 +1956,6 @@ static int sql_get_leaf_statement(fulltext_vtab *v, int idx,
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like sql_step_statement(), but for special replicated LEAF_SELECT
|
|
||||||
** statements.
|
|
||||||
*/
|
|
||||||
/* TODO(shess) Write version for generic statements and then share
|
|
||||||
** that between the cached-statement functions.
|
|
||||||
*/
|
|
||||||
static int sql_step_leaf_statement(fulltext_vtab *v, int idx,
|
|
||||||
sqlite3_stmt **ppStmt){
|
|
||||||
int rc;
|
|
||||||
sqlite3_stmt *s = *ppStmt;
|
|
||||||
|
|
||||||
while( (rc=sqlite3_step(s))!=SQLITE_DONE && rc!=SQLITE_ROW ){
|
|
||||||
|
|
||||||
if( rc==SQLITE_BUSY ) continue;
|
|
||||||
if( rc!=SQLITE_ERROR ) return rc;
|
|
||||||
|
|
||||||
/* If an SQLITE_SCHEMA error has occured, then finalizing this
|
|
||||||
* statement is going to delete the fulltext_vtab structure. If
|
|
||||||
* the statement just executed is in the pLeafSelectStmts[]
|
|
||||||
* array, it will be finalized twice. So remove it before
|
|
||||||
* calling sqlite3_finalize().
|
|
||||||
*/
|
|
||||||
v->pLeafSelectStmts[idx] = NULL;
|
|
||||||
rc = sqlite3_finalize(s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* insert into %_content (rowid, ...) values ([rowid], [pValues]) */
|
/* insert into %_content (rowid, ...) values ([rowid], [pValues]) */
|
||||||
static int content_insert(fulltext_vtab *v, sqlite3_value *rowid,
|
static int content_insert(fulltext_vtab *v, sqlite3_value *rowid,
|
||||||
sqlite3_value **pValues){
|
sqlite3_value **pValues){
|
||||||
|
@ -2034,7 +1972,7 @@ static int content_insert(fulltext_vtab *v, sqlite3_value *rowid,
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sql_single_step_statement(v, CONTENT_INSERT_STMT, &s);
|
return sql_single_step(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update %_content set col0 = pValues[0], col1 = pValues[1], ...
|
/* update %_content set col0 = pValues[0], col1 = pValues[1], ...
|
||||||
|
@ -2054,7 +1992,7 @@ static int content_update(fulltext_vtab *v, sqlite3_value **pValues,
|
||||||
rc = sqlite3_bind_int64(s, 1+v->nColumn, iRowid);
|
rc = sqlite3_bind_int64(s, 1+v->nColumn, iRowid);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
return sql_single_step_statement(v, CONTENT_UPDATE_STMT, &s);
|
return sql_single_step(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeStringArray(int nString, const char **pString){
|
static void freeStringArray(int nString, const char **pString){
|
||||||
|
@ -2087,7 +2025,7 @@ static int content_select(fulltext_vtab *v, sqlite_int64 iRow,
|
||||||
rc = sqlite3_bind_int64(s, 1, iRow);
|
rc = sqlite3_bind_int64(s, 1, iRow);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
rc = sql_step_statement(v, CONTENT_SELECT_STMT, &s);
|
rc = sqlite3_step(s);
|
||||||
if( rc!=SQLITE_ROW ) return rc;
|
if( rc!=SQLITE_ROW ) return rc;
|
||||||
|
|
||||||
values = (const char **) malloc(v->nColumn * sizeof(const char *));
|
values = (const char **) malloc(v->nColumn * sizeof(const char *));
|
||||||
|
@ -2120,7 +2058,7 @@ static int content_delete(fulltext_vtab *v, sqlite_int64 iRow){
|
||||||
rc = sqlite3_bind_int64(s, 1, iRow);
|
rc = sqlite3_bind_int64(s, 1, iRow);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
return sql_single_step_statement(v, CONTENT_DELETE_STMT, &s);
|
return sql_single_step(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* insert into %_segments values ([pData])
|
/* insert into %_segments values ([pData])
|
||||||
|
@ -2135,7 +2073,7 @@ static int block_insert(fulltext_vtab *v, const char *pData, int nData,
|
||||||
rc = sqlite3_bind_blob(s, 1, pData, nData, SQLITE_STATIC);
|
rc = sqlite3_bind_blob(s, 1, pData, nData, SQLITE_STATIC);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
rc = sql_step_statement(v, BLOCK_INSERT_STMT, &s);
|
rc = sqlite3_step(s);
|
||||||
if( rc==SQLITE_ROW ) return SQLITE_ERROR;
|
if( rc==SQLITE_ROW ) return SQLITE_ERROR;
|
||||||
if( rc!=SQLITE_DONE ) return rc;
|
if( rc!=SQLITE_DONE ) return rc;
|
||||||
|
|
||||||
|
@ -2161,7 +2099,7 @@ static int block_delete(fulltext_vtab *v,
|
||||||
rc = sqlite3_bind_int64(s, 2, iEndBlockid);
|
rc = sqlite3_bind_int64(s, 2, iEndBlockid);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
return sql_single_step_statement(v, BLOCK_DELETE_STMT, &s);
|
return sql_single_step(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns SQLITE_ROW with *pidx set to the maximum segment idx found
|
/* Returns SQLITE_ROW with *pidx set to the maximum segment idx found
|
||||||
|
@ -2176,7 +2114,7 @@ static int segdir_max_index(fulltext_vtab *v, int iLevel, int *pidx){
|
||||||
rc = sqlite3_bind_int(s, 1, iLevel);
|
rc = sqlite3_bind_int(s, 1, iLevel);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
rc = sql_step_statement(v, SEGDIR_MAX_INDEX_STMT, &s);
|
rc = sqlite3_step(s);
|
||||||
/* Should always get at least one row due to how max() works. */
|
/* Should always get at least one row due to how max() works. */
|
||||||
if( rc==SQLITE_DONE ) return SQLITE_DONE;
|
if( rc==SQLITE_DONE ) return SQLITE_DONE;
|
||||||
if( rc!=SQLITE_ROW ) return rc;
|
if( rc!=SQLITE_ROW ) return rc;
|
||||||
|
@ -2231,7 +2169,7 @@ static int segdir_set(fulltext_vtab *v, int iLevel, int idx,
|
||||||
rc = sqlite3_bind_blob(s, 6, pRootData, nRootData, SQLITE_STATIC);
|
rc = sqlite3_bind_blob(s, 6, pRootData, nRootData, SQLITE_STATIC);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
return sql_single_step_statement(v, SEGDIR_SET_STMT, &s);
|
return sql_single_step(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Queries %_segdir for the block span of the segments in level
|
/* Queries %_segdir for the block span of the segments in level
|
||||||
|
@ -2248,7 +2186,7 @@ static int segdir_span(fulltext_vtab *v, int iLevel,
|
||||||
rc = sqlite3_bind_int(s, 1, iLevel);
|
rc = sqlite3_bind_int(s, 1, iLevel);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
rc = sql_step_statement(v, SEGDIR_SPAN_STMT, &s);
|
rc = sqlite3_step(s);
|
||||||
if( rc==SQLITE_DONE ) return SQLITE_DONE; /* Should never happen */
|
if( rc==SQLITE_DONE ) return SQLITE_DONE; /* Should never happen */
|
||||||
if( rc!=SQLITE_ROW ) return rc;
|
if( rc!=SQLITE_ROW ) return rc;
|
||||||
|
|
||||||
|
@ -2293,7 +2231,7 @@ static int segdir_delete(fulltext_vtab *v, int iLevel){
|
||||||
rc = sqlite3_bind_int64(s, 1, iLevel);
|
rc = sqlite3_bind_int64(s, 1, iLevel);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
return sql_single_step_statement(v, SEGDIR_DELETE_STMT, &s);
|
return sql_single_step(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(shess) clearPendingTerms() is far down the file because
|
/* TODO(shess) clearPendingTerms() is far down the file because
|
||||||
|
@ -5013,7 +4951,7 @@ static int leavesReaderInit(fulltext_vtab *v,
|
||||||
rc = sqlite3_bind_int64(s, 2, iEndBlockid);
|
rc = sqlite3_bind_int64(s, 2, iEndBlockid);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
rc = sql_step_leaf_statement(v, idx, &s);
|
rc = sqlite3_step(s);
|
||||||
if( rc==SQLITE_DONE ){
|
if( rc==SQLITE_DONE ){
|
||||||
pReader->eof = 1;
|
pReader->eof = 1;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
|
@ -5041,7 +4979,7 @@ static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){
|
||||||
pReader->eof = 1;
|
pReader->eof = 1;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
rc = sql_step_leaf_statement(v, pReader->idx, &pReader->pStmt);
|
rc = sqlite3_step(pReader->pStmt);
|
||||||
if( rc!=SQLITE_ROW ){
|
if( rc!=SQLITE_ROW ){
|
||||||
pReader->eof = 1;
|
pReader->eof = 1;
|
||||||
return rc==SQLITE_DONE ? SQLITE_OK : rc;
|
return rc==SQLITE_DONE ? SQLITE_OK : rc;
|
||||||
|
@ -5105,7 +5043,7 @@ static int leavesReadersInit(fulltext_vtab *v, int iLevel,
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while( (rc = sql_step_statement(v, SEGDIR_SELECT_STMT, &s))==SQLITE_ROW ){
|
while( (rc = sqlite3_step(s))==SQLITE_ROW ){
|
||||||
sqlite_int64 iStart = sqlite3_column_int64(s, 0);
|
sqlite_int64 iStart = sqlite3_column_int64(s, 0);
|
||||||
sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
|
sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
|
||||||
const char *pRootData = sqlite3_column_blob(s, 2);
|
const char *pRootData = sqlite3_column_blob(s, 2);
|
||||||
|
@ -5400,7 +5338,7 @@ static int loadAndGetChildrenContaining(
|
||||||
rc = sqlite3_bind_int64(s, 1, iBlockid);
|
rc = sqlite3_bind_int64(s, 1, iBlockid);
|
||||||
if( rc!=SQLITE_OK ) return rc;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
rc = sql_step_statement(v, BLOCK_SELECT_STMT, &s);
|
rc = sqlite3_step(s);
|
||||||
if( rc==SQLITE_DONE ) return SQLITE_ERROR;
|
if( rc==SQLITE_DONE ) return SQLITE_ERROR;
|
||||||
if( rc!=SQLITE_ROW ) return rc;
|
if( rc!=SQLITE_ROW ) return rc;
|
||||||
|
|
||||||
|
@ -5538,7 +5476,7 @@ static int termSelect(fulltext_vtab *v, int iColumn,
|
||||||
/* Traverse the segments from oldest to newest so that newer doclist
|
/* Traverse the segments from oldest to newest so that newer doclist
|
||||||
** elements for given docids overwrite older elements.
|
** elements for given docids overwrite older elements.
|
||||||
*/
|
*/
|
||||||
while( (rc=sql_step_statement(v, SEGDIR_SELECT_ALL_STMT, &s))==SQLITE_ROW ){
|
while( (rc = sqlite3_step(s))==SQLITE_ROW ){
|
||||||
const char *pData = sqlite3_column_blob(s, 0);
|
const char *pData = sqlite3_column_blob(s, 0);
|
||||||
const int nData = sqlite3_column_bytes(s, 0);
|
const int nData = sqlite3_column_bytes(s, 0);
|
||||||
const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
|
const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
|
||||||
|
@ -5655,7 +5593,7 @@ static int clearPendingTerms(fulltext_vtab *v){
|
||||||
static int flushPendingTerms(fulltext_vtab *v){
|
static int flushPendingTerms(fulltext_vtab *v){
|
||||||
if( v->nPendingData>=0 ){
|
if( v->nPendingData>=0 ){
|
||||||
int rc = writeZeroSegment(v, &v->pendingTerms);
|
int rc = writeZeroSegment(v, &v->pendingTerms);
|
||||||
clearPendingTerms(v);
|
if( rc==SQLITE_OK ) clearPendingTerms(v);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
|
|
16
manifest
16
manifest
|
@ -1,5 +1,5 @@
|
||||||
C Add\sa\stest\scase\sto\sreproduce\sthe\sdatabase\scorruption\sproblem\sreported\nby\sticket\s#2565.\s(CVS\s4204)
|
C Convert\sfts2\sto\suse\ssqlite3_prepare_v2()\sto\sprevent\scertain\slogic\nerrors\saround\sSQLITE_SCHEMA\shandling.\s\sThis\salso\sallows\nsql_step_statement()\sand\ssql_step_leaf_statement()\sto\sbe\sreplaced\swith\nsqlite3_step().\n\nAlso\sfix\sa\slogic\serror\sin\sflushPendingTerms()\swhich\swas\sclearing\sthe\nterm\stable\sin\scase\sof\serror.\s\sThis\swas\swrong\sin\sthe\sface\sof\nSQLITE_SCHEMA.\s\sEven\sthough\sthe\schange\sto\ssqlite3_prepare_v2()\sshould\ncause\sus\snot\sto\ssee\sSQLITE_SCHEMA\sany\slonger,\sit\swas\sstill\sa\slogic\nerror...\s(CVS\s4205)
|
||||||
D 2007-08-10T19:46:44
|
D 2007-08-10T23:47:04
|
||||||
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
||||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
|
@ -37,7 +37,7 @@ F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d
|
||||||
F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
|
F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
|
||||||
F ext/fts2/README.tokenizers 2ff290e0a130f6e7611f2e608cb3b5aaea721abc
|
F ext/fts2/README.tokenizers 2ff290e0a130f6e7611f2e608cb3b5aaea721abc
|
||||||
F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||||
F ext/fts2/fts2.c 412242297d4141ef66ae06ac33fcacdb4a2a3d4e
|
F ext/fts2/fts2.c 29992419e893a919c1f5cb14615d30a05cb20abb
|
||||||
F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa
|
F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa
|
||||||
F ext/fts2/fts2_hash.c cafebb4620d19684c4c9872530012441df60f503
|
F ext/fts2/fts2_hash.c cafebb4620d19684c4c9872530012441df60f503
|
||||||
F ext/fts2/fts2_hash.h e283308156018329f042816eb09334df714e105e
|
F ext/fts2/fts2_hash.h e283308156018329f042816eb09334df714e105e
|
||||||
|
@ -256,7 +256,7 @@ F test/fts2g.test 2638452a2ea809ae30e98acc3c063fe54c381d0a
|
||||||
F test/fts2h.test 223af921323b409d4b5b18ff4e51619541b174bb
|
F test/fts2h.test 223af921323b409d4b5b18ff4e51619541b174bb
|
||||||
F test/fts2i.test 1b22451d1f13f7c509baec620dc3a4a754885dd6
|
F test/fts2i.test 1b22451d1f13f7c509baec620dc3a4a754885dd6
|
||||||
F test/fts2j.test f68d7611f76309bc8b94170f3740d9fbbc061d9b
|
F test/fts2j.test f68d7611f76309bc8b94170f3740d9fbbc061d9b
|
||||||
F test/fts2k.test 222d0b3bc8667753f18406aaea9906a6098ea016
|
F test/fts2k.test c7ebf4a4937594aa07459e3e1bca1251c1be8659
|
||||||
F test/fts2l.test 4c53c89ce3919003765ff4fd8d98ecf724d97dd3
|
F test/fts2l.test 4c53c89ce3919003765ff4fd8d98ecf724d97dd3
|
||||||
F test/fts2m.test 4b30142ead6f3ed076e880a2a464064c5ad58c51
|
F test/fts2m.test 4b30142ead6f3ed076e880a2a464064c5ad58c51
|
||||||
F test/fts2n.test a70357e72742681eaebfdbe9007b87ff3b771638
|
F test/fts2n.test a70357e72742681eaebfdbe9007b87ff3b771638
|
||||||
|
@ -524,7 +524,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P e01eb99edfa3390e97847a210532847cc64803da
|
P f267ce809424ec2cc167bf9750989413a8f925c1
|
||||||
R aac32bb1cd0df3e93b59fdd82b5116c9
|
R 7b50465ce600cfe9712feba4d5c8c556
|
||||||
U drh
|
U shess
|
||||||
Z 295b4c36a089304d77fa0f7b791dfdde
|
Z fb3f3f46abbb55040332d6f3d03499aa
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
f267ce809424ec2cc167bf9750989413a8f925c1
|
16730cb137eaf576b87cdc17913564c9c5c0ed82
|
|
@ -4,10 +4,10 @@
|
||||||
#
|
#
|
||||||
#*************************************************************************
|
#*************************************************************************
|
||||||
# This file implements regression tests for SQLite library. These
|
# This file implements regression tests for SQLite library. These
|
||||||
# make sure that inserted documents are visible to selects within the
|
# make sure that fts2 insertion buffering is fully transparent when
|
||||||
# transaction.
|
# using transactions.
|
||||||
#
|
#
|
||||||
# $Id: fts2k.test,v 1.1 2007/03/29 18:41:05 shess Exp $
|
# $Id: fts2k.test,v 1.2 2007/08/10 23:47:04 shess Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
|
@ -80,4 +80,26 @@ do_test fts2k-1.5 {
|
||||||
}
|
}
|
||||||
} {1 3 4 6}
|
} {1 3 4 6}
|
||||||
|
|
||||||
|
# Test that the obvious case works.
|
||||||
|
do_test fts2k-1.6 {
|
||||||
|
execsql {
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 (rowid, content) VALUES(12, "third world");
|
||||||
|
COMMIT;
|
||||||
|
SELECT rowid FROM t1 WHERE t1 MATCH 'third';
|
||||||
|
}
|
||||||
|
} {12}
|
||||||
|
|
||||||
|
# This is exactly the same as the previous test, except that older
|
||||||
|
# code loses the INSERT due to an SQLITE_SCHEMA error.
|
||||||
|
do_test fts2k-1.7 {
|
||||||
|
execsql {
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO t1 (rowid, content) VALUES(13, "third dimension");
|
||||||
|
CREATE TABLE x (c);
|
||||||
|
COMMIT;
|
||||||
|
SELECT rowid FROM t1 WHERE t1 MATCH 'dimension';
|
||||||
|
}
|
||||||
|
} {13}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
Loading…
Reference in New Issue