]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify FTS1 so that the "magic" column has the same name as the virtual
authordrh <drh@noemail.net>
Mon, 18 Sep 2006 02:12:47 +0000 (02:12 +0000)
committerdrh <drh@noemail.net>
Mon, 18 Sep 2006 02:12:47 +0000 (02:12 +0000)
table.  Offsets are retrieved using a special "offsets" function whose
first argument is the magic column.  Snippets will ultimately be retrieved
in the same way. (CVS 3427)

FossilOrigin-Name: 5e35dc1ffadfe7fa47673d052501ee79903eead9

ext/fts1/fts1.c
manifest
manifest.uuid
test/fts1b.test
test/fts1c.test

index 389b12163ef12bfdc0374d6c47ab1ed7c4685d44..d50808e3ffbc96d4d2691e14c3bc1d2e9ff70e69 100644 (file)
@@ -1748,17 +1748,15 @@ int parseSpec(TableSpec *pSpec, int argc, const char *const*argv, char**pzErr){
 
 /*
 ** Generate a CREATE TABLE statement that describes the schema of
-** the virtual table.  Return a pointer to this schema.  
-**
-** If the addAllColumn parameter is true, then add a column named
-** "_all" to the end of the schema.  Also add the "offset" column.
+** the virtual table.  Return a pointer to this schema string.
 **
 ** Space is obtained from sqlite3_mprintf() and should be freed
 ** using sqlite3_free().
 */
 static char *fulltextSchema(
   int nColumn,                  /* Number of columns */
-  const char *const* azColumn   /* List of columns */
+  const char *const* azColumn,  /* List of columns */
+  const char *zTableName        /* Name of the table */
 ){
   int i;
   char *zSchema, *zNext;
@@ -1770,7 +1768,7 @@ static char *fulltextSchema(
     zSchema = zNext;
     zSep = ",";
   }
-  zNext = sqlite3_mprintf("%s,_all,offset)", zSchema);
+  zNext = sqlite3_mprintf("%s,%Q)", zSchema, zTableName);
   sqlite3_free(zSchema);
   return zNext;
 }
@@ -1826,7 +1824,8 @@ static int constructVtab(
 
   /* TODO: verify the existence of backing tables foo_content, foo_term */
 
-  schema = fulltextSchema(v->nColumn, (const char*const*)v->azColumn);
+  schema = fulltextSchema(v->nColumn, (const char*const*)v->azColumn,
+                          spec->zName);
   rc = sqlite3_declare_vtab(db, schema);
   sqlite3_free(schema);
   if( rc!=SQLITE_OK ) goto err;
@@ -2603,14 +2602,10 @@ static int fulltextColumn(sqlite3_vtab_cursor *pCursor,
     sqlite3_value *pVal = sqlite3_column_value(c->pStmt, idxCol+1);
     sqlite3_result_value(pContext, pVal);
   }else if( idxCol==v->nColumn ){
-    /* The _all column */
-    sqlite3_result_null(pContext);
-  }else if( idxCol==v->nColumn+1 ){
-    /* The offset column */
-    snippetAllOffsets(c);
-    snippetOffsetText(&c->snippet);
-    sqlite3_result_text(pContext, c->snippet.zOffset, c->snippet.nOffset,
-                                   SQLITE_STATIC);
+    /* The extra column whose name is the same as the table.
+    ** Return a blob which is a pointer to the cursor
+    */
+    sqlite3_result_blob(pContext, &c, sizeof(c), SQLITE_TRANSIENT);
   }
   return SQLITE_OK;
 }
@@ -2833,11 +2828,74 @@ static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg,
    * ppArg[2+v->nColumn] = value for _all (we ignore this)
    * ppArg[3+v->nColumn] = value of offset (we ignore this too)
    */
-  assert( nArg==2+v->nColumn+2);    
+  assert( nArg==2+v->nColumn+1);    
 
   return index_insert(v, ppArg[1], &ppArg[2], pRowid);
 }
 
+/*
+** Implementation of the snippet() function for FTS1
+*/
+static void snippetFunc(
+  sqlite3_context *pContext,
+  int argc,
+  sqlite3_value **argv
+){
+  fulltext_cursor *pCursor;
+  if( argc<1 ) return;
+  if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
+      sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
+    sqlite3_result_error(pContext, "illegal first argument to html_snippet",-1);
+  }else{
+    memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
+    /* TODO:  Return the snippet */
+  }
+}
+
+/*
+** Implementation of the offsets() function for FTS1
+*/
+static void snippetOffsetsFunc(
+  sqlite3_context *pContext,
+  int argc,
+  sqlite3_value **argv
+){
+  fulltext_cursor *pCursor;
+  if( argc<1 ) return;
+  if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
+      sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
+    sqlite3_result_error(pContext, "illegal first argument to offsets",-1);
+  }else{
+    memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
+    snippetAllOffsets(pCursor);
+    snippetOffsetText(&pCursor->snippet);
+    sqlite3_result_text(pContext,
+                        pCursor->snippet.zOffset, pCursor->snippet.nOffset,
+                        SQLITE_STATIC);
+  }
+}
+
+/*
+** This routine implements the xFindFunction method for the FTS1
+** virtual table.
+*/
+static int fulltextFindFunction(
+  sqlite3_vtab *pVtab,
+  int nArg,
+  const char *zName,
+  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
+  void **ppArg
+){
+  if( strcasecmp(zName,"snippet")==0 ){
+    *pxFunc = snippetFunc;
+    return 1;
+  }else if( strcasecmp(zName,"offsets")==0 ){
+    *pxFunc = snippetOffsetsFunc;
+    return 1;
+  }
+  return 0;
+}
+
 static const sqlite3_module fulltextModule = {
   /* iVersion      */ 0,
   /* xCreate       */ fulltextCreate,
@@ -2857,18 +2915,22 @@ static const sqlite3_module fulltextModule = {
   /* xSync         */ 0,
   /* xCommit       */ 0,
   /* xRollback     */ 0,
-  /* xFindFunction */ 0,
+  /* xFindFunction */ fulltextFindFunction,
 };
 
 int sqlite3Fts1Init(sqlite3 *db){
- return sqlite3_create_module(db, "fts1", &fulltextModule, 0);
+  sqlite3_overload_function(db, "snippet", -1);
+  sqlite3_overload_function(db, "offsets", -1);
+  return sqlite3_create_module(db, "fts1", &fulltextModule, 0);
 }
 
 #if !SQLITE_CORE
 int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg,
                            const sqlite3_api_routines *pApi){
- SQLITE_EXTENSION_INIT2(pApi)
- return sqlite3Fts1Init(db);
+  int rc;
+  SQLITE_EXTENSION_INIT2(pApi)
+  rc = sqlite3Fts1Init(db);
+  if( rc ) return rc;
 }
 #endif
 
index 9263f99918ffc3ab32332060f65b6c101d3e8ea9..b93cabb37791ba018813c54d8c9338fd1d71fc2b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\ssqlite3_overload_function()\sAPI\s-\spart\sof\sthe\svirtual\stable\ninterface.\s(CVS\s3426)
-D 2006-09-16T21:45:14
+C Modify\sFTS1\sso\sthat\sthe\s"magic"\scolumn\shas\sthe\ssame\sname\sas\sthe\svirtual\ntable.\s\sOffsets\sare\sretrieved\susing\sa\sspecial\s"offsets"\sfunction\swhose\nfirst\sargument\sis\sthe\smagic\scolumn.\s\sSnippets\swill\sultimately\sbe\sretrieved\nin\sthe\ssame\sway.\s(CVS\s3427)
+D 2006-09-18T02:12:48
 F Makefile.in cabd42d34340f49260bc2a7668c38eba8d4cfd99
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -21,7 +21,7 @@ F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
 F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
 F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5
-F ext/fts1/fts1.c 10d0c351fb1ee51ef3b8bd3eb29d1f7f91773ddb
+F ext/fts1/fts1.c 298a1b77f51083cf76fae406971c6a2312315409
 F ext/fts1/fts1.h 6060b8f62c1d925ea8356cb1a6598073eb9159a6
 F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114
 F ext/fts1/fts1_hash.h 957d378355ed29f672cd5add012ce8b088a5e089
@@ -191,8 +191,8 @@ F test/expr.test c78843f730ccbe973d0c2ad1c99978f936893131
 F test/fkey1.test 153004438d51e6769fb1ce165f6313972d6263ce
 F test/format4.test bf3bed3b13c63abfb3cfec232597a319a31d0bcc
 F test/fts1a.test 54fd9451c00fb91074d5abdc207b05dcba6d2d65
-F test/fts1b.test 5742c32c69ec9667c8d32df5bc79aa416d5f363a
-F test/fts1c.test 65a4e5a900ca0e0c9cd05612f9baf958d67a9d44
+F test/fts1b.test 5d8a01aefbecc8b7442b36c94c05eb7a845462d5
+F test/fts1c.test 4d84cfcacce229e4802fd676462f4616fabadad3
 F test/func.test 0ed54b5aeaad319f68016c033acfebef56f5874a
 F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a
 F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d
@@ -399,7 +399,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P a6b3f6bed209dc27d36cd4e159159f73266e9911
-R 41c034b9dce9d7c6fde9c3e87e61b1e4
+P aa7728f9f5b80dbb1b3db124f84b9166bf72bdd3
+R 5f7b3fdccab6ce661c65210783a1bcaa
 U drh
-Z 9301301f42636d8c9fe0c165b69e993c
+Z 772a57c08cf67baf90fc0fd4a8945191
index 4b286c870d6ff33ab76ab8f8d2a292cb17fee9ec..a4bf5c5889b6540e7233d035f7b6397a75814bd6 100644 (file)
@@ -1 +1 @@
-aa7728f9f5b80dbb1b3db124f84b9166bf72bdd3
\ No newline at end of file
+5e35dc1ffadfe7fa47673d052501ee79903eead9
\ No newline at end of file
index 3c9f0cbc189e2fa12be89ce2bc7af98f348c547f..2bbe1aab8004791af162a767022a7cd8d42ea1f6 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is testing the FTS1 module.
 #
-# $Id: fts1b.test,v 1.3 2006/09/13 16:02:44 drh Exp $
+# $Id: fts1b.test,v 1.4 2006/09/18 02:12:48 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -69,16 +69,16 @@ do_test fts1b-1.3 {
   execsql {SELECT rowid FROM t1 WHERE german MATCH 'one'}
 } {}
 do_test fts1b-1.4 {
-  execsql {SELECT rowid FROM t1 WHERE _all MATCH 'one'}
+  execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one'}
 } {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
 do_test fts1b-1.5 {
-  execsql {SELECT rowid FROM t1 WHERE _all MATCH 'one dos drei'}
+  execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one dos drei'}
 } {7 15 23 31}
 do_test fts1b-1.6 {
   execsql {SELECT english, spanish, german FROM t1 WHERE rowid=1}
 } {one un eine}
 do_test fts1b-1.7 {
-  execsql {SELECT rowid FROM t1 WHERE _all MATCH '"one un"'}
+  execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"one un"'}
 } {}
 
 do_test fts1b-2.1 {
@@ -116,31 +116,31 @@ for {set i 1} {$i<=15} {incr i} {
 }
 
 do_test fts1b-4.1 {
-  execsql {SELECT rowid FROM t4 WHERE _all MATCH 'norm:one'}
+  execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one'}
 } {1 3 5 7 9 11 13 15}
 do_test fts1b-4.2 {
   execsql {SELECT rowid FROM t4 WHERE norm MATCH 'one'}
 } {1 3 5 7 9 11 13 15}
 do_test fts1b-4.3 {
-  execsql {SELECT rowid FROM t4 WHERE _all MATCH 'one'}
+  execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'one'}
 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}
 do_test fts1b-4.4 {
-  execsql {SELECT rowid FROM t4 WHERE _all MATCH 'plusone:one'}
+  execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:one'}
 } {2 4 6 8 10 12 14}
 do_test fts1b-4.5 {
   execsql {SELECT rowid FROM t4 WHERE plusone MATCH 'one'}
 } {2 4 6 8 10 12 14}
 do_test fts1b-4.6 {
-  execsql {SELECT rowid FROM t4 WHERE _all MATCH 'norm:one plusone:two'}
+  execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one plusone:two'}
 } {1 5 9 13}
 do_test fts1b-4.7 {
-  execsql {SELECT rowid FROM t4 WHERE _all MATCH 'norm:one two'}
+  execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one two'}
 } {1 3 5 7 9 11 13 15}
 do_test fts1b-4.8 {
-  execsql {SELECT rowid FROM t4 WHERE _all MATCH 'plusone:two norm:one'}
+  execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:two norm:one'}
 } {1 5 9 13}
 do_test fts1b-4.9 {
-  execsql {SELECT rowid FROM t4 WHERE _all MATCH 'two norm:one'}
+  execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'two norm:one'}
 } {1 3 5 7 9 11 13 15}
 
 
index db0f19e0f6d402d1bed4ef5f2e601d99c23bb3ce..b62fc5ff1864bc378a15cc062f19f05954fe94b2 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is testing the FTS1 module.
 #
-# $Id: fts1c.test,v 1.5 2006/09/16 21:45:14 drh Exp $
+# $Id: fts1c.test,v 1.6 2006/09/18 02:12:48 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -1027,93 +1027,93 @@ http://home.enron.com:84/messaging/litebytztoolzprint.jpg');
 
 do_test fts1c-1.2 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH 'mark'
+    SELECT rowid FROM email WHERE email MATCH 'mark'
   }
 } {6 17 25 38 40 42 73 74}
 do_test fts1c-1.3 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH 'susan'
+    SELECT rowid FROM email WHERE email MATCH 'susan'
   }
 } {24 40}
 do_test fts1c-1.4 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH 'mark susan'
+    SELECT rowid FROM email WHERE email MATCH 'mark susan'
   }
 } {40}
 do_test fts1c-1.5 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH 'susan mark'
+    SELECT rowid FROM email WHERE email MATCH 'susan mark'
   }
 } {40}
 do_test fts1c-1.6 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH '"mark susan"'
+    SELECT rowid FROM email WHERE email MATCH '"mark susan"'
   }
 } {}
 do_test fts1c-1.7 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH 'mark -susan'
+    SELECT rowid FROM email WHERE email MATCH 'mark -susan'
   }
 } {6 17 25 38 42 73 74}
 do_test fts1c-1.8 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH '-mark susan'
+    SELECT rowid FROM email WHERE email MATCH '-mark susan'
   }
 } {24}
 do_test fts1c-1.9 {
   execsql {
-    SELECT rowid FROM email WHERE _all MATCH 'mark OR susan'
+    SELECT rowid FROM email WHERE email MATCH 'mark OR susan'
   }
 } {6 17 24 25 38 40 42 73 74}
 
-# Some simple tests of the automatic "offset" column.  In the sample
+# Some simple tests of the automatic "offsets(email)" column.  In the sample
 # data set above, only one message, number 20, contains the words
 # "gas" and "reminder" in both body and subject.
 #
 do_test fts1c-2.1 {
   execsql {
-    SELECT rowid, offset FROM email
-     WHERE _all MATCH 'gas reminder'
+    SELECT rowid, offsets(email) FROM email
+     WHERE email MATCH 'gas reminder'
   }
 } {20 {2 0 42 3 2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}}
 do_test fts1c-2.2 {
   execsql {
-    SELECT rowid, offset FROM email
-     WHERE _all MATCH 'subject:gas reminder'
+    SELECT rowid, offsets(email) FROM email
+     WHERE email MATCH 'subject:gas reminder'
   }
 } {20 {2 0 42 3 2 1 54 8 3 1 54 8}}
 do_test fts1c-2.3 {
   execsql {
-    SELECT rowid, offset FROM email
-     WHERE _all MATCH 'body:gas reminder'
+    SELECT rowid, offsets(email) FROM email
+     WHERE email MATCH 'body:gas reminder'
   }
 } {20 {2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}}
 do_test fts1c-2.4 {
   execsql {
-    SELECT rowid, offset FROM email
+    SELECT rowid, offsets(email) FROM email
      WHERE subject MATCH 'gas reminder'
   }
 } {20 {2 0 42 3 2 1 54 8}}
 do_test fts1c-2.5 {
   execsql {
-    SELECT rowid, offset FROM email
+    SELECT rowid, offsets(email) FROM email
      WHERE body MATCH 'gas reminder'
   }
 } {20 {3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}}
 
 # Document 32 contains 5 instances of the world "child".  But only
 # 3 of them are paired with "product".  Make sure only those instances
-# that match the phrase appear in the offset list.
+# that match the phrase appear in the offsets(email) list.
 #
 do_test fts1c-3.1 {
   execsql {
-    SELECT rowid, offset FROM email
+    SELECT rowid, offsets(email) FROM email
      WHERE body MATCH 'child product' AND +rowid=32
   }
 } {32 {3 0 94 5 3 0 114 5 3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7 3 1 493 7}}
 do_test fts1c-3.2 {
   execsql {
-    SELECT rowid, offset FROM email
+    SELECT rowid, offsets(email) FROM email
      WHERE body MATCH '"child product"'
   }
 } {32 {3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7}}