From: adamd Date: Tue, 12 Sep 2006 23:36:45 +0000 (+0000) Subject: Answer queries for a particular rowid in a full-text table by looking up X-Git-Tag: version-3.6.10~2760 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=341d60838c6669a81ff6f550134a0bea3ab31f88;p=thirdparty%2Fsqlite.git Answer queries for a particular rowid in a full-text table by looking up that rowid directly rather than by performing a table scan. (CVS 3407) FossilOrigin-Name: 877d5558b1a6f65201b1825336935b146583bffa --- diff --git a/ext/fts1/fts1.c b/ext/fts1/fts1.c index a4134f38ae..b9ae5c2f91 100644 --- a/ext/fts1/fts1.c +++ b/ext/fts1/fts1.c @@ -750,8 +750,11 @@ static int sql_prepare(sqlite3 *db, const char *zName, sqlite3_stmt **ppStmt, /* end utility functions */ -#define QUERY_GENERIC 0 -#define QUERY_FULLTEXT 1 +typedef enum QueryType { + QUERY_GENERIC, /* table scan */ + QUERY_ROWID, /* lookup by rowid */ + QUERY_FULLTEXT /* full-text search */ +} QueryType; /* TODO(shess) CHUNK_MAX controls how much data we allow in segment 0 ** before we start aggregating into larger segments. Lower CHUNK_MAX @@ -817,14 +820,12 @@ typedef struct fulltext_vtab { typedef struct fulltext_cursor { sqlite3_vtab_cursor base; - int iCursorType; /* QUERY_GENERIC or QUERY_FULLTEXT */ + QueryType iCursorType; sqlite3_stmt *pStmt; - int eof; - /* The following is used only when iCursorType == QUERY_FULLTEXT. */ - DocListReader result; + DocListReader result; /* used when iCursorType == QUERY_FULLTEXT */ } fulltext_cursor; static struct fulltext_vtab *cursor_vtab(fulltext_cursor *c){ @@ -1456,13 +1457,23 @@ static int fulltextBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ for(i=0; inConstraint; ++i){ const struct sqlite3_index_constraint *pConstraint; pConstraint = &pInfo->aConstraint[i]; - if( pConstraint->iColumn==0 && - pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH && - pConstraint->usable ){ /* a full-text search */ + if( pConstraint->usable ) { + if( pConstraint->iColumn==-1 && + pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + pInfo->idxNum = QUERY_ROWID; /* lookup by rowid */ + } else if( pConstraint->iColumn==0 && + pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + pInfo->idxNum = QUERY_FULLTEXT; /* full-text search */ + } else continue; + pInfo->aConstraintUsage[i].argvIndex = 1; pInfo->aConstraintUsage[i].omit = 1; - pInfo->idxNum = QUERY_FULLTEXT; - pInfo->estimatedCost = 1.0; /* an arbitrary value for now */ + + /* An arbitrary value for now. + * TODO: Perhaps rowid matches should be considered cheaper than + * full-text searches. */ + pInfo->estimatedCost = 1.0; + return SQLITE_OK; } } @@ -1518,43 +1529,39 @@ static int fulltextNext(sqlite3_vtab_cursor *pCursor){ int rc; TRACE(("FTS1 Next %p\n", pCursor)); - switch( c->iCursorType ){ - case QUERY_GENERIC: - /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */ - rc = sqlite3_step(c->pStmt); - switch( rc ){ - case SQLITE_ROW: - c->eof = 0; - return SQLITE_OK; - case SQLITE_DONE: - c->eof = 1; - return SQLITE_OK; - default: - c->eof = 1; - return rc; - } - case QUERY_FULLTEXT: - rc = sqlite3_reset(c->pStmt); - if( rc!=SQLITE_OK ) return rc; - - iDocid = nextValidDocid(&c->result); - if( iDocid==0 ){ - c->eof = 1; - return SQLITE_OK; - } - rc = sqlite3_bind_int64(c->pStmt, 1, iDocid); - if( rc!=SQLITE_OK ) return rc; - /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */ - rc = sqlite3_step(c->pStmt); - if( rc==SQLITE_ROW ){ /* the case we expect */ + if( c->iCursorType != QUERY_FULLTEXT ){ + /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */ + rc = sqlite3_step(c->pStmt); + switch( rc ){ + case SQLITE_ROW: c->eof = 0; return SQLITE_OK; - } - /* an error occurred; abort */ - return rc==SQLITE_DONE ? SQLITE_ERROR : rc; - default: - assert( 0 ); - return SQLITE_ERROR; /* not reached */ + case SQLITE_DONE: + c->eof = 1; + return SQLITE_OK; + default: + c->eof = 1; + return rc; + } + } else { /* full-text query */ + rc = sqlite3_reset(c->pStmt); + if( rc!=SQLITE_OK ) return rc; + + iDocid = nextValidDocid(&c->result); + if( iDocid==0 ){ + c->eof = 1; + return SQLITE_OK; + } + rc = sqlite3_bind_int64(c->pStmt, 1, iDocid); + if( rc!=SQLITE_OK ) return rc; + /* TODO(shess) Handle SQLITE_SCHEMA AND SQLITE_BUSY. */ + rc = sqlite3_step(c->pStmt); + if( rc==SQLITE_ROW ){ /* the case we expect */ + c->eof = 0; + return SQLITE_OK; + } + /* an error occurred; abort */ + return rc==SQLITE_DONE ? SQLITE_ERROR : rc; } } @@ -1830,13 +1837,21 @@ static int fulltextFilter(sqlite3_vtab_cursor *pCursor, fulltext_cursor *c = (fulltext_cursor *) pCursor; fulltext_vtab *v = cursor_vtab(c); int rc; - const char *zStatement; TRACE(("FTS1 Filter %p\n",pCursor)); c->iCursorType = idxNum; switch( idxNum ){ case QUERY_GENERIC: - zStatement = "select rowid, content from %_content"; + rc = sql_prepare(v->db, v->zName, &c->pStmt, + "select rowid, content from %_content"); + break; + + case QUERY_ROWID: + rc = sql_prepare(v->db, v->zName, &c->pStmt, + "select rowid, content from %_content where rowid = ?"); + if( rc!=SQLITE_OK ) return rc; + + rc = sqlite3_bind_int64(c->pStmt, 1, sqlite3_value_int64(argv[0])); break; case QUERY_FULLTEXT: /* full-text search */ @@ -1847,7 +1862,8 @@ static int fulltextFilter(sqlite3_vtab_cursor *pCursor, rc = fulltextQuery(v, zQuery, -1, &pResult); if( rc!=SQLITE_OK ) return rc; readerInit(&c->result, pResult); - zStatement = "select rowid, content from %_content where rowid = ?"; + rc = sql_prepare(v->db, v->zName, &c->pStmt, + "select rowid, content from %_content where rowid = ?"); break; } @@ -1855,7 +1871,6 @@ static int fulltextFilter(sqlite3_vtab_cursor *pCursor, assert( 0 ); } - rc = sql_prepare(v->db, v->zName, &c->pStmt, zStatement); if( rc!=SQLITE_OK ) return rc; return fulltextNext(pCursor); diff --git a/manifest b/manifest index bffdcbbe15..e6a0feac07 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sIF\sEXISTS\son\sCREATE/DROP\sTRIGGER/VIEW.\s\sTicket\s#1899.\s(CVS\s3406) -D 2006-09-11T23:45:49 +C Answer\squeries\sfor\sa\sparticular\srowid\sin\sa\sfull-text\stable\sby\slooking\sup\nthat\srowid\sdirectly\srather\sthan\sby\sperforming\sa\stable\sscan.\s(CVS\s3407) +D 2006-09-12T23:36:45 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 5c5e362ec08487a0bdcf58b7467a28321eed8025 +F ext/fts1/fts1.c 9ba2598d8f7fe6a774282150602b4dcf8d08981d F ext/fts1/fts1.h fe8e8f38dd6d2d2645b9b0d6972e80985249575f F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114 F ext/fts1/fts1_hash.h 957d378355ed29f672cd5add012ce8b088a5e089 @@ -397,7 +397,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 2f5f6290c9ef99c7b060aecc4d996c976c50c9d7 -R d17bd6ef8648d9d2f3852e6272db6a75 -U drh -Z 86240886575897a77ef3f7d53b2d3c49 +P e4fe736cfbbdc081581911a01690576034877b72 +R cd04ef21e43abddd90a3615c7fb02f51 +U adamd +Z 7cc52eecbd18356560e00617aa5563fc diff --git a/manifest.uuid b/manifest.uuid index a92c67e518..7dc2fe997b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4fe736cfbbdc081581911a01690576034877b72 \ No newline at end of file +877d5558b1a6f65201b1825336935b146583bffa \ No newline at end of file