**
** 1. Ignore any compress= and uncompress= options.
**
- ** 2. Ignore any column names that were specified as part of the
- ** the CREATE VIRTUAL TABLE statement.
- **
- ** 3. Determine the actual column names to use for the FTS table
- ** based on the columns of the content= table.
+ ** 2. If no column names were specified as part of the CREATE VIRTUAL
+ ** TABLE statement, use all columns from the content table.
*/
if( rc==SQLITE_OK && zContent ){
- sqlite3_free(aCol);
sqlite3_free(zCompress);
sqlite3_free(zUncompress);
zCompress = 0;
zUncompress = 0;
- aCol = 0;
- rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+ if( nCol==0 ){
+ sqlite3_free(aCol);
+ aCol = 0;
+ rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+ }
assert( rc!=SQLITE_OK || nCol>0 );
}
if( rc!=SQLITE_OK ) goto fts3_init_out;
return SQLITE_OK;
}
+/*
+** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then
+** compose and prepare an SQL statement of the form:
+**
+** "SELECT <columns> FROM %_content WHERE rowid = ?"
+**
+** (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){
+ 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);
+ }
+ *ppStmt = pCsr->pStmt;
+ return rc;
+}
+
/*
** Position the pCsr->pStmt statement so that it is on the row
** of the %_content table that contains the last match. Return
** SQLITE_OK on success.
*/
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
+ int rc = SQLITE_OK;
if( pCsr->isRequireSeek ){
- sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
- pCsr->isRequireSeek = 0;
- if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
- return SQLITE_OK;
- }else{
- int rc = sqlite3_reset(pCsr->pStmt);
- if( rc==SQLITE_OK ){
- Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
- if( p->zContentTbl==0 ){
+ sqlite3_stmt *pStmt = 0;
+
+ rc = fts3CursorSeekStmt(pCsr, &pStmt);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
+ pCsr->isRequireSeek = 0;
+ if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
+ return SQLITE_OK;
+ }else{
+ rc = sqlite3_reset(pCsr->pStmt);
+ if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
/* If no row was found and no error has occured, then the %_content
** table is missing a row that is present in the full-text index.
- ** The data structures are corrupt.
- */
+ ** The data structures are corrupt. */
rc = SQLITE_CORRUPT_VTAB;
- }else{
- return SQLITE_OK;
+ pCsr->isEof = 1;
}
}
- pCsr->isEof = 1;
- if( pContext ){
- sqlite3_result_error_code(pContext, rc);
- }
- return rc;
}
- }else{
- return SQLITE_OK;
}
+
+ if( rc!=SQLITE_OK && pContext ){
+ sqlite3_result_error_code(pContext, rc);
+ }
+ return rc;
}
/*
** row by docid.
*/
if( idxNum==FTS3_FULLSCAN_SEARCH ){
- const char *zTmpl = "SELECT %s ORDER BY rowid %s";
- zSql = sqlite3_mprintf(zTmpl,
+ zSql = sqlite3_mprintf(
+ "SELECT %s ORDER BY rowid %s",
p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
);
- }else{
- const char *zTmpl = "SELECT %s WHERE rowid = ?";
- zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist);
+ if( zSql ){
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
+ sqlite3_free(zSql);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }else if( idxNum==FTS3_DOCID_SEARCH ){
+ rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
+ }
}
- if( !zSql ) return SQLITE_NOMEM;
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
- sqlite3_free(zSql);
if( rc!=SQLITE_OK ) return rc;
- if( idxNum==FTS3_DOCID_SEARCH ){
- rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
- if( rc!=SQLITE_OK ) return rc;
- }
-
return fts3NextMethod(pCursor);
}
** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
** still happen if the user reads data directly from the %_segments or
** %_segdir tables instead of going through FTS3 though.
+**
+** This reasoning does not apply to a content=xxx table.
*/
int sqlite3Fts3ReadLock(Fts3Table *p){
int rc; /* Return code */
sqlite3_stmt *pStmt; /* Statement used to obtain lock */
- rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_null(pStmt, 1);
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
+ if( p->zContentTbl==0 ){
+ rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_null(pStmt, 1);
+ sqlite3_step(pStmt);
+ rc = sqlite3_reset(pStmt);
+ }
+ }else{
+ rc = SQLITE_OK;
}
+
return rc;
}
-C Fix\sa\sproblem\swith\sIO\serror\shandling\sin\sthe\srebuild-index\scode.
-D 2011-10-05T06:07:00.875
+C Change\sFTS4\sso\sthat\sif\sboth\sthe\scontent=xxx\soption\sand\scolumn\snames\sare\sspecified,\sthe\svirtual\stable\sassumes\sthat\sthe\snamed\scolumns\scorrespond\sto\scolumns\sof\stable\sxxx.
+D 2011-10-05T15:11:30.760
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c 6d6f3d331ed785d2e68608443eff66448ea95354
+F ext/fts3/fts3.c f2ed0ae669534e0c9c8ba95b60b6c137544e7e49
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 06f442ce096e6254432a6b16a56b6fe7b24bd372
F ext/fts3/fts3_aux.c 0ebfa7b86cf8ff6a0861605fcc63b83ec1b70691
F ext/fts3/fts3_tokenizer.c 9ff7ec66ae3c5c0340fa081958e64f395c71a106
F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
F ext/fts3/fts3_tokenizer1.c 0dde8f307b8045565cf63797ba9acfaff1c50c68
-F ext/fts3/fts3_write.c 16fba93fc840f15421ebf1a783a8c3395700bbf9
+F ext/fts3/fts3_write.c 06520aa8a0a32a7bed08b29a9004fde1cb7f0318
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F test/fts3snippet.test 8e956051221a34c7daeb504f023cb54d5fa5a8b2
F test/fts3sort.test 95be0b19d7e41c44b29014f13ea8bddd495fd659
F test/fts4aa.test 6e7f90420b837b2c685f3bcbe84c868492d40a68
-F test/fts4content.test 5c226c7c666e250c175bcbdfbdd4be3f275c73ba
+F test/fts4content.test c5f531ecfc3d446b90032cae212549dbbb18dd78
F test/func.test 6c5ce11e3a0021ca3c0649234e2d4454c89110ca
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2
-P 0f439944ab49a5691615bc170fdcf652055573df
-R 29197ea13db81f2ba07fe324b03117e5
+P c6ba81fcad32192674bd510e607f787adc1f7038
+R 0217fe49810be9d8f9417ba3c648ab3e
U dan
-Z a28913360f741831433fc7b43c93a8a9
+Z 1eb4f36513f7844867f45162778888e7
-c6ba81fcad32192674bd510e607f787adc1f7038
\ No newline at end of file
+289ee43179369fce2fde50870d72c445e184e896
\ No newline at end of file
# creating a content=xxx FTS index.
#
-do_execsql_test 1.1 {
+do_execsql_test 1.1.1 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES('w x', 'x y', 'y z');
CREATE VIRTUAL TABLE ft1 USING fts4(content=t1);
}
-do_execsql_test 1.2 {
+do_execsql_test 1.1.2 {
PRAGMA table_info(ft1);
} {
0 a {} 0 {} 0
2 c {} 0 {} 0
}
-do_execsql_test 1.3 { SELECT *, rowid FROM ft1 } {{w x} {x y} {y z} 1}
-do_execsql_test 1.4 { SELECT a, c FROM ft1 WHERE rowid=1 } {{w x} {y z}}
+do_execsql_test 1.1.3 { SELECT *, rowid FROM ft1 } {{w x} {x y} {y z} 1}
+do_execsql_test 1.1.4 { SELECT a, c FROM ft1 WHERE rowid=1 } {{w x} {y z}}
-do_execsql_test 1.5 { INSERT INTO ft1(ft1) VALUES('rebuild') } {}
-do_execsql_test 1.6 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'x' } {1}
-do_execsql_test 1.7 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'a' } {}
+do_execsql_test 1.1.5 { INSERT INTO ft1(ft1) VALUES('rebuild') } {}
+do_execsql_test 1.1.6 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'x' } {1}
+do_execsql_test 1.1.7 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'a' } {}
+
+do_execsql_test 1.2.1 {
+ DROP TABLE ft1;
+ CREATE VIRTUAL TABLE ft1 USING fts4(content=t1, b);
+ PRAGMA table_info(ft1);
+} {
+ 0 b {} 0 {} 0
+}
+do_execsql_test 1.2.2 {
+ SELECT *, rowid FROM ft1
+} {{x y} 1}
#-------------------------------------------------------------------------
# The following block of tests - 2.* - test that a content=xxx FTS table
CREATE TABLE t7(x);
}
do_catchsql_test 6.2.8 {
- SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
+ SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
} {1 {SQL logic error or missing database}}
do_catchsql_test 6.2.9 {
- SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
+ SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
} {1 {SQL logic error or missing database}}
db close
SELECT rowid, * FROM ft7 WHERE ft7 MATCH '"A A"';
} {0 {2 {}}}
+#-------------------------------------------------------------------------
+# Test cases 7.*
+#
+do_execsql_test 7.1.1 {
+ CREATE VIRTUAL TABLE ft8 USING fts4(content=nosuchtable, x);
+ INSERT INTO ft8(docid, x) VALUES(13, 'U O N X G');
+ INSERT INTO ft8(docid, x) VALUES(14, 'C J J U B');
+ INSERT INTO ft8(docid, x) VALUES(15, 'N J Y G X');
+ INSERT INTO ft8(docid, x) VALUES(16, 'R Y D O R');
+ INSERT INTO ft8(docid, x) VALUES(17, 'I Y T Q O');
+}
+
+do_execsql_test 7.1.2 {
+ SELECT docid FROM ft8 WHERE ft8 MATCH 'N';
+} {13 15}
+
finish_test