1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
# 2014 Dec 20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file focuses on testing queries that use the "rank" column.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5rank
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
#-------------------------------------------------------------------------
# "ORDER BY rank" + highlight() + large poslists.
#
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE xyz USING fts5(z);
}
do_test 1.1 {
set doc [string trim [string repeat "x y " 500]]
execsql { INSERT INTO xyz VALUES($doc) }
} {}
do_execsql_test 1.2 {
SELECT highlight(xyz, 0, '[', ']') FROM xyz WHERE xyz MATCH 'x' ORDER BY rank
} [list [string map {x [x]} $doc]]
do_execsql_test 1.3 {
SELECT highlight(xyz, 0, '[', ']') FROM xyz
WHERE xyz MATCH 'x AND y' ORDER BY rank
} [list [string map {x [x] y [y]} $doc]]
#-------------------------------------------------------------------------
# Check that the 'rank' option really is persistent.
#
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE tt USING fts5(a);
INSERT INTO tt VALUES('a x x x x');
INSERT INTO tt VALUES('x x a a a');
INSERT INTO tt VALUES('x a a x x');
}
proc firstinst {cmd} {
foreach {p c o} [$cmd xInst 0] {}
return $o
}
sqlite3_fts5_create_function db firstinst firstinst
do_execsql_test 2.1 {
SELECT rowid FROM tt('a') ORDER BY rank;
} {2 3 1}
do_execsql_test 2.2 {
SELECT rowid FROM tt('a', 'firstinst()') ORDER BY rank;
} {1 3 2}
do_execsql_test 2.3 {
INSERT INTO tt(tt, rank) VALUES('rank', 'firstinst()');
SELECT rowid FROM tt('a') ORDER BY rank;
} {1 3 2}
do_test 2.4 {
sqlite3 db2 test.db
catchsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 {no such function: firstinst}}
do_test 2.5 {
db2 close
sqlite3 db2 test.db
sqlite3_fts5_create_function db2 firstinst firstinst
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 3 2}
do_test 2.6 {
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 3 2}
do_test 2.7 {
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db
} {1 3 2}
db2 close
#--------------------------------------------------------------------------
# At one point there was a problem with queries such as:
#
# ... MATCH 'x OR y' ORDER BY rank;
#
# if there were zero occurrences of token 'y' in the dataset. The
# following tests verify that that problem has been addressed.
#
foreach_detail_mode $::testprefix {
do_execsql_test 3.1.0 {
CREATE VIRTUAL TABLE y1 USING fts5(z, detail=%DETAIL%);
INSERT INTO y1 VALUES('test xyz');
INSERT INTO y1 VALUES('test test xyz test');
INSERT INTO y1 VALUES('test test xyz');
}
do_execsql_test 3.1.1 {
SELECT rowid FROM y1('test OR tset');
} {1 2 3}
do_execsql_test 3.1.2 {
SELECT rowid FROM y1('test OR tset') ORDER BY bm25(y1)
} {2 3 1}
do_execsql_test 3.1.3 {
SELECT rowid FROM y1('test OR tset') ORDER BY +rank
} {2 3 1}
do_execsql_test 3.1.4 {
SELECT rowid FROM y1('test OR tset') ORDER BY rank
} {2 3 1}
do_execsql_test 3.1.5 {
SELECT rowid FROM y1('test OR xyz') ORDER BY rank
} {3 2 1}
do_execsql_test 3.2.1 {
CREATE VIRTUAL TABLE z1 USING fts5(a, detail=%DETAIL%);
INSERT INTO z1 VALUES('wrinkle in time');
SELECT * FROM z1 WHERE z1 MATCH 'wrinkle in time OR a wrinkle in time';
} {{wrinkle in time}}
}
do_execsql_test 4.1 {
DROP TABLE IF EXISTS VTest;
CREATE virtual TABLE VTest USING FTS5(
Title, AUthor, tokenize ='porter unicode61 remove_diacritics 1',
columnsize='1', detail=full
);
INSERT INTO VTest (Title, Author) VALUES ('wrinkle in time', 'Bill Smith');
SELECT * FROM VTest WHERE
VTest MATCH 'wrinkle in time OR a wrinkle in time' ORDER BY rank;
} {{wrinkle in time} {Bill Smith}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE ttt USING fts5(a);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
)
INSERT INTO ttt SELECT 'word ' || i FROM s;
}
do_execsql_test 5.1 {
SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
} {30 31 32 33 34 35 36 37 38 39 40}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE "My.Table" USING fts5(Text);
INSERT INTO "My.Table" VALUES ('hello this is a test');
INSERT INTO "My.Table" VALUES ('of trying to order by');
INSERT INTO "My.Table" VALUES ('rank on an fts5 table');
INSERT INTO "My.Table" VALUES ('that have periods in');
INSERT INTO "My.Table" VALUES ('the table names.');
INSERT INTO "My.Table" VALUES ('table table table');
}
do_execsql_test 6.1 {
SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank;
} {
{table table table} {the table names.} {rank on an fts5 table}
}
#-------------------------------------------------------------------------
# forum post: https://sqlite.org/forum/forumpost/a2dd636330
#
reset_db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t USING fts5 (a, b);
INSERT INTO t (a, b) VALUES ('data1', 'sentence1'), ('data2', 'sentence2');
INSERT INTO t(t, rank) VALUES ('rank', 'bm25(10.0,1.0)');
}
sqlite3 db2 test.db
do_execsql_test -db db2 1.1 {
SELECT *, rank<0.0 FROM t('data*') ORDER BY RANK;
} {data1 sentence1 1 data2 sentence2 1}
do_execsql_test 1.2 {
INSERT INTO t(t, rank) VALUES ('rank', 'bm25(10.0,1.0)');
}
do_execsql_test -db db2 1.3 {
SELECT *, rank<0.0 FROM t('data*') ORDER BY RANK;
} {data1 sentence1 1 data2 sentence2 1}
db2 close
finish_test
|