]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add an implicit (HIDDEN) docid column. This works as an alias to
authorshess <shess@noemail.net>
Thu, 13 Sep 2007 18:14:49 +0000 (18:14 +0000)
committershess <shess@noemail.net>
Thu, 13 Sep 2007 18:14:49 +0000 (18:14 +0000)
rowid, similar to how things work in SQLite tables with INTEGER
PRIMARY KEY.  Add tests to verify operation. (CVS 4426)

FossilOrigin-Name: c8d2345200f9ece1af712543982097d0b6f348c7

ext/fts3/fts3.c
manifest
manifest.uuid
test/fts3b.test

index af3a557945786418c7940f03b7d81fb0319ae6b6..605e7c5d27cc07f4f0d0faeff2499828382a2a5b 100644 (file)
@@ -2702,7 +2702,10 @@ static char *fulltextSchema(
     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;
 }
@@ -2861,6 +2864,7 @@ out:
 
 /* 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"));
 
@@ -2868,11 +2872,11 @@ static int fulltextBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
     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;
@@ -3763,6 +3767,10 @@ static int fulltextColumn(sqlite3_vtab_cursor *pCursor,
     ** 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;
 }
@@ -5674,13 +5682,17 @@ static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg,
      * 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 {
@@ -5688,9 +5700,26 @@ static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg,
      * 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;
index 9d7f544bd42c238ae268114a2b3322781987e2d2..e5b461d656d4629d05543a9b31d38dd69b12a5a3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
@@ -49,7 +49,7 @@ F ext/fts2/fts2_tokenizer1.c 8a545c232bdffafd117c4eeaf59789691909f26a
 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
@@ -304,7 +304,7 @@ F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8
 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
@@ -577,7 +577,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 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
index 476aaced2141b3435c259a02676a46ed25531104..a57a8d5389016a5c4ce51af495afd88c88a5cbf5 100644 (file)
@@ -1 +1 @@
-ca669eaf1b4af441741129bee4af02f32a7c74b8
\ No newline at end of file
+c8d2345200f9ece1af712543982097d0b6f348c7
\ No newline at end of file
index 770e97cd9d142c1f4057f61ed0432a3b749331cc..17ee0da85ac46b571ac0d2f0a5d610c3c4b78c9d 100644 (file)
@@ -11,7 +11,7 @@
 # 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]
@@ -136,4 +136,83 @@ do_test fts3b-3.3 {
   }
 } {}
 
+# 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