zSchema = zNext;
zSep = ",";
}
- zNext = sqlite3_mprintf("%s,%Q HIDDEN)", zSchema, zTableName);
+ zNext = sqlite3_mprintf("%s,%Q HIDDEN", zSchema, zTableName);
+ sqlite3_free(zSchema);
+ zSchema = zNext;
+ zNext = sqlite3_mprintf("%s,docid HIDDEN)", zSchema);
sqlite3_free(zSchema);
return zNext;
}
/* Decide how to handle an SQL query. */
static int fulltextBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
+ fulltext_vtab *v = (fulltext_vtab *)pVTab;
int i;
TRACE(("FTS3 BestIndex\n"));
const struct sqlite3_index_constraint *pConstraint;
pConstraint = &pInfo->aConstraint[i];
if( pConstraint->usable ) {
- if( pConstraint->iColumn==-1 &&
+ if( (pConstraint->iColumn==-1 || pConstraint->iColumn==v->nColumn+1) &&
pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
pInfo->idxNum = QUERY_DOCID; /* lookup by docid */
TRACE(("FTS3 QUERY_DOCID\n"));
- } else if( pConstraint->iColumn>=0 &&
+ } else if( pConstraint->iColumn>=0 && pConstraint->iColumn<=v->nColumn &&
pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
/* full-text search */
pInfo->idxNum = QUERY_FULLTEXT + pConstraint->iColumn;
** Return a blob which is a pointer to the cursor
*/
sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT);
+ }else if( idxCol==v->nColumn+1 ){
+ /* The docid column, which is an alias for rowid. */
+ sqlite3_value *pVal = sqlite3_column_value(c->pStmt, 0);
+ sqlite3_result_value(pContext, pVal);
}
return SQLITE_OK;
}
* ppArg[1] = new rowid
* ppArg[2..2+v->nColumn-1] = values
* ppArg[2+v->nColumn] = value for magic column (we ignore this)
+ * ppArg[2+v->nColumn+1] = value for docid
*/
sqlite_int64 rowid = sqlite3_value_int64(ppArg[0]);
if( sqlite3_value_type(ppArg[1]) != SQLITE_INTEGER ||
- sqlite3_value_int64(ppArg[1]) != rowid ){
+ sqlite3_value_int64(ppArg[1]) != rowid ){
rc = SQLITE_ERROR; /* we don't allow changing the rowid */
- } else {
- assert( nArg==2+v->nColumn+1);
+ }else if( sqlite3_value_type(ppArg[2+v->nColumn+1]) != SQLITE_INTEGER ||
+ sqlite3_value_int64(ppArg[2+v->nColumn+1]) != rowid ){
+ rc = SQLITE_ERROR; /* we don't allow changing the docid */
+ }else{
+ assert( nArg==2+v->nColumn+2);
rc = index_update(v, rowid, &ppArg[2]);
}
} else {
* ppArg[1] = requested rowid
* ppArg[2..2+v->nColumn-1] = values
* ppArg[2+v->nColumn] = value for magic column (we ignore this)
+ * ppArg[2+v->nColumn+1] = value for docid
*/
- assert( nArg==2+v->nColumn+1);
- rc = index_insert(v, ppArg[1], &ppArg[2], pRowid);
+ sqlite3_value *pRequestDocid = ppArg[2+v->nColumn+1];
+ assert( nArg==2+v->nColumn+2);
+ if( SQLITE_NULL != sqlite3_value_type(pRequestDocid) &&
+ SQLITE_NULL != sqlite3_value_type(ppArg[1]) ){
+ /* TODO(shess) Consider allowing this to work if the values are
+ ** identical. I'm inclined to discourage that usage, though,
+ ** given that both rowid and docid are special columns. Better
+ ** would be to define one or the other as the default winner,
+ ** but should it be fts3-centric (docid) or SQLite-centric
+ ** (rowid)?
+ */
+ rc = SQLITE_ERROR;
+ }else{
+ if( SQLITE_NULL == sqlite3_value_type(pRequestDocid) ){
+ pRequestDocid = ppArg[1];
+ }
+ rc = index_insert(v, pRequestDocid, &ppArg[2], pRowid);
+ }
}
return rc;
-C Mark\sthe\stable-named\scolumn\sHIDDEN.\s\sAdd\stests\sto\smake\ssure\sit's\nworking\sas\sexpected.\s(CVS\s4425)
-D 2007-09-13T18:12:10
+C Add\san\simplicit\s(HIDDEN)\sdocid\scolumn.\s\sThis\sworks\sas\san\salias\sto\nrowid,\ssimilar\sto\show\sthings\swork\sin\sSQLite\stables\swith\sINTEGER\nPRIMARY\sKEY.\s\sAdd\stests\sto\sverify\soperation.\s(CVS\s4426)
+D 2007-09-13T18:14:49
F Makefile.in cbfb898945536a8f9ea8b897e1586dd1fdbcc5db
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
F ext/fts3/README.tokenizers a97c9a55b3422f6cb04af9de9296fe2447ea4a78
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c fa62f3981802f260bd2131f7aabb532e7957b537
+F ext/fts3/fts3.c 6d266d7250a544ae27026dc5caf655b94f63d74b
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3_hash.c 84654768178452b00bbc986dd878a8299dc1e3dc
F ext/fts3/fts3_hash.h af585d6867d478fc0457f64cfaae60e09541e63a
F test/fts3an.test 2da4df52fe8ea8389f6fa7a01e4c1a0f091118d6
F test/fts3ao.test 0aa29dd4fc1c8d46b1f7cfe5926f7ac97551bea9
F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa
-F test/fts3b.test 7c697946fe11b651c4531c522519f8c50bc333ec
+F test/fts3b.test b3a25180a633873d37d86e1ccd00ed690d37237a
F test/func.test 590fe3e1d28256d98dd73efb671de0823043e82a
F test/fuzz.test 62fc19dd36a427777fd671b569df07166548628a
F test/fuzz2.test ea38692ce2da99ad79fe0be5eb1a452c1c4d37bb
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 2cfdbfe6543bac42961deecec7d085d806e604b5
-R f4605f4a6437f7ace832bd72a3a46cf2
+P ca669eaf1b4af441741129bee4af02f32a7c74b8
+R a51a9cf24cdebc5c4ac36a19e3d14834
U shess
-Z 8703f97ca6b737d36a523e680d867934
+Z 890136427fcf1284643fc3a90d814552
-ca669eaf1b4af441741129bee4af02f32a7c74b8
\ No newline at end of file
+c8d2345200f9ece1af712543982097d0b6f348c7
\ No newline at end of file
# This file implements regression tests for SQLite library. This
# script tests for the fts2 rowid-versus-vacuum problem (ticket #2566).
#
-# $Id: fts3b.test,v 1.2 2007/09/13 18:12:10 shess Exp $
+# $Id: fts3b.test,v 1.3 2007/09/13 18:14:49 shess Exp $
#
set testdir [file dirname $argv0]
}
} {}
+# fts3 adds a new implicit column, docid, which acts as an alias for
+# rowid.
+
+db eval {
+ CREATE VIRTUAL TABLE t4 USING fts3(c);
+ INSERT INTO t4 (c) VALUES('this is a test');
+ INSERT INTO t4 (c) VALUES('that was a test');
+ INSERT INTO t4 (c) VALUES('this is fun');
+ DELETE FROM t4 WHERE c = 'that was a test';
+}
+
+# Test that docid is present and identical to rowid.
+do_test fts3b-4.1 {
+ execsql {
+ SELECT rowid FROM t4 WHERE rowid <> docid;
+ }
+} {}
+
+# Test that docid is hidden.
+do_test fts3b-4.2 {
+ execsql {
+ SELECT * FROM t4 WHERE rowid = 1;
+ }
+} {{this is a test}}
+
+# Test that docid can be selected.
+do_test fts3b-4.3 {
+ execsql {
+ SELECT docid, * FROM t4 WHERE rowid = 1;
+ }
+} {1 {this is a test}}
+
+# Test that docid can be used in WHERE.
+do_test fts3b-4.4 {
+ execsql {
+ SELECT docid, * FROM t4 WHERE docid = 1;
+ }
+} {1 {this is a test}}
+
+# Test that the column doesn't conflict with inserts that don't name
+# columns. [Yes, this is the same as fts3b-3.3, here just in case the
+# goals of that test change.]
+do_test fts3b-4.5 {
+ execsql {
+ INSERT INTO t4 VALUES ('another test');
+ }
+} {}
+
+# Test that the docid can be forced on insert.
+do_test fts3b-4.6 {
+ execsql {
+ INSERT INTO t4 (docid, c) VALUES (10, 'yet another test');
+ SELECT * FROM t4 WHERE docid = 10;
+ }
+} {{yet another test}}
+
+# Test that rowid can also be forced.
+do_test fts3b-4.7 {
+ execsql {
+ INSERT INTO t4 (docid, c) VALUES (12, 'still testing');
+ SELECT * FROM t4 WHERE docid = 12;
+ }
+} {{still testing}}
+
+# If an insert tries to set both docid and rowid, require an error.
+do_test fts3b-4.8 {
+ catchsql {
+ INSERT INTO t4 (rowid, docid, c) VALUES (14, 15, 'bad test');
+ SELECT * FROM t4 WHERE docid = 14;
+ }
+} {1 {SQL logic error or missing database}}
+
+# Don't allow update of docid, to match rowid behaviour.
+do_test fts3b-4.9 {
+ catchsql {
+ UPDATE t4 SET docid = 14 WHERE docid = 12;
+ }
+} {1 {SQL logic error or missing database}}
+
finish_test