mirror of https://github.com/sqlite/sqlite
Modify FTS1 so that the "magic" column has the same name as the virtual
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
This commit is contained in:
parent
b7481e70c5
commit
b08249ced3
102
ext/fts1/fts1.c
102
ext/fts1/fts1.c
|
@ -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
|
||||
|
||||
|
|
16
manifest
16
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
|
||||
|
|
|
@ -1 +1 @@
|
|||
aa7728f9f5b80dbb1b3db124f84b9166bf72bdd3
|
||||
5e35dc1ffadfe7fa47673d052501ee79903eead9
|
|
@ -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}
|
||||
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue