Update the spellfix virtual table to optimize queries of the form "SELECT ... FROM tbl WHERE rowid=?".

FossilOrigin-Name: a0ba55ff0596c5f15e9cdb254c68ef50df2dfaad
This commit is contained in:
dan 2014-01-22 17:43:16 +00:00
parent 8561c81ed6
commit a8a0617e06
4 changed files with 81 additions and 12 deletions

View File

@ -2051,6 +2051,7 @@ static int spellfix1Close(sqlite3_vtab_cursor *cur){
** (D) scope = $scope
** (E) distance < $distance
** (F) distance <= $distance
** (G) rowid = $rowid
**
** The plan number is a bit mask formed with these bits:
**
@ -2060,8 +2061,9 @@ static int spellfix1Close(sqlite3_vtab_cursor *cur){
** 0x08 (D) is found
** 0x10 (E) is found
** 0x20 (F) is found
** 0x40 (G) is found
**
** filter.argv[*] values contains $str, $langid, $top, and $scope,
** filter.argv[*] values contains $str, $langid, $top, $scope and $rowid
** if specified and in that order.
*/
static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
@ -2070,6 +2072,7 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int iTopTerm = -1;
int iScopeTerm = -1;
int iDistTerm = -1;
int iRowidTerm = -1;
int i;
const struct sqlite3_index_constraint *pConstraint;
pConstraint = pIdxInfo->aConstraint;
@ -2122,6 +2125,15 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
iPlan |= pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ? 16 : 32;
iDistTerm = i;
}
/* Terms of the form: distance < $dist or distance <= $dist */
if( (iPlan & 64)==0
&& pConstraint->iColumn<0
&& pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
){
iPlan |= 64;
iRowidTerm = i;
}
}
if( iPlan&1 ){
int idx = 2;
@ -2149,6 +2161,11 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->aConstraintUsage[iDistTerm].omit = 1;
}
pIdxInfo->estimatedCost = 1e5;
}else if( (iPlan & 64) ){
pIdxInfo->idxNum = 64;
pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
pIdxInfo->estimatedCost = 5;
}else{
pIdxInfo->idxNum = 0;
pIdxInfo->estimatedCost = 1e50;
@ -2465,16 +2482,23 @@ static int spellfix1FilterForFullScan(
int argc,
sqlite3_value **argv
){
int rc;
int rc = SQLITE_OK;
char *zSql;
spellfix1_vtab *pVTab = pCur->pVTab;
spellfix1ResetCursor(pCur);
assert( idxNum==0 || idxNum==64 );
zSql = sqlite3_mprintf(
"SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"",
pVTab->zDbName, pVTab->zTableName);
"SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"%s",
pVTab->zDbName, pVTab->zTableName,
((idxNum & 64) ? " WHERE rowid=?" : "")
);
if( zSql==0 ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pFullScan, 0);
sqlite3_free(zSql);
if( rc==SQLITE_OK && (idxNum & 64) ){
assert( argc==1 );
rc = sqlite3_bind_value(pCur->pFullScan, 1, argv[0]);
}
pCur->nRow = pCur->iRow = 0;
if( rc==SQLITE_OK ){
rc = sqlite3_step(pCur->pFullScan);

View File

@ -1,5 +1,5 @@
C Remove\sthe\sundocumented\srequirement\sfor\sapplications\sthat\suse\san\sSQLITE_ENABLE_SQLLOG\sbuild\sto\sdefine\sa\ssqlite3_init_sqllog()\sfunction.
D 2014-01-21T15:04:47.807
C Update\sthe\sspellfix\svirtual\stable\sto\soptimize\squeries\sof\sthe\sform\s"SELECT\s...\sFROM\stbl\sWHERE\srowid=?".
D 2014-01-22T17:43:16.604
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -114,7 +114,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/spellfix.c 76578f2c56ceaa23d22032338d90db79c68490fb
F ext/misc/spellfix.c adfc569fafef7a1eb8f21528e5277686b358c3ce
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@ -825,7 +825,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4
F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be
F test/spellfix.test 674db5da8b16d2b54939b68ccc0ac31ca53d9977
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 7d9e22187daaa3160b875a1df17b924969bf718e
R 72db5d0300da6235ddfc19ebd0af857f
P 5e43bf013253921e4dfbe71de11ee7ed4b3e7eae
R d2ae80bd066cad79603d23bc83a10a19
U dan
Z 21763f37f81635b2fe9a520f9fd3a652
Z 90dc7fd11fe48035054a3857f5aa405e

View File

@ -1 +1 @@
5e43bf013253921e4dfbe71de11ee7ed4b3e7eae
a0ba55ff0596c5f15e9cdb254c68ef50df2dfaad

View File

@ -221,6 +221,51 @@ foreach {tn word res} {
} $res
}
#-------------------------------------------------------------------------
# Try some queries by rowid.
#
do_execsql_test 6.1.1 {
SELECT word FROM t3 WHERE rowid = 10;
} {keener}
do_execsql_test 6.1.2 {
SELECT word, distance FROM t3 WHERE rowid = 10;
} {keener {}}
do_execsql_test 6.1.3 {
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300}
proc trace_callback {sql} {
if {[string range $sql 0 2] == "-- "} {
lappend ::trace [string range $sql 3 end]
}
}
proc do_tracesql_test {tn sql {res {}}} {
set ::trace [list]
uplevel [list do_test $tn [subst -nocommands {
set vals [execsql {$sql}]
concat [set vals] [set ::trace]
}] [list {*}$res]]
}
db trace trace_callback
do_tracesql_test 6.2.1 {
SELECT word FROM t3 WHERE rowid = 10;
} {keener
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.2 {
SELECT word, distance FROM t3 WHERE rowid = 10;
} {keener {}
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.3 {
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300
{SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
}
finish_test