xref: /sqlite-3.40.0/test/fts3query.test (revision 8210233c)
1e61fc3b6Sdan# 2009 December 20
2e61fc3b6Sdan#
3e61fc3b6Sdan# The author disclaims copyright to this source code.  In place of
4e61fc3b6Sdan# a legal notice, here is a blessing:
5e61fc3b6Sdan#
6e61fc3b6Sdan#    May you do good and not evil.
7e61fc3b6Sdan#    May you find forgiveness for yourself and forgive others.
8e61fc3b6Sdan#    May you share freely, never taking more than you give.
9e61fc3b6Sdan#
10e61fc3b6Sdan#***********************************************************************
11e61fc3b6Sdan#
12e61fc3b6Sdan# This file contains tests of fts3 queries that have been useful during
13e61fc3b6Sdan# the development process as well as some that have been useful in tracking
14e61fc3b6Sdan# down bugs. They are not focused on any particular functionality.
15e61fc3b6Sdan#
16e61fc3b6Sdan
17e61fc3b6Sdanset testdir [file dirname $argv0]
18e61fc3b6Sdansource $testdir/tester.tcl
19e61fc3b6Sdan
20e61fc3b6Sdan# If this build does not include FTS3, skip the tests in this file.
21e61fc3b6Sdan#
22e61fc3b6Sdanifcapable !fts3 { finish_test ; return }
23ef378025Sdansource $testdir/malloc_common.tcl
24e61fc3b6Sdansource $testdir/fts3_common.tcl
25e61fc3b6Sdanset DO_MALLOC_TEST 0
26e61fc3b6Sdan
27ddf80eb8Sdanset testprefix fts3query
28ddf80eb8Sdan
29e61fc3b6Sdando_test fts3query-1.1 {
30e61fc3b6Sdan  execsql {
31e61fc3b6Sdan    CREATE VIRTUAL TABLE t1 USING fts3(x);
32e61fc3b6Sdan    BEGIN;
33e61fc3b6Sdan      INSERT INTO t1 VALUES('The source code for SQLite is in the public');
34e61fc3b6Sdan  }
35e61fc3b6Sdan} {}
36e61fc3b6Sdan
37e61fc3b6Sdando_select_test fts3query-1.2 {
38e61fc3b6Sdan  SELECT * FROM t1;
39e61fc3b6Sdan} {{The source code for SQLite is in the public}}
40e61fc3b6Sdando_select_test fts3query-1.3 {
41e61fc3b6Sdan  SELECT * FROM t1 WHERE t1 MATCH 'sqlite'
42e61fc3b6Sdan} {{The source code for SQLite is in the public}}
43e61fc3b6Sdan
44e61fc3b6Sdando_test fts3query-1.4 { execsql {COMMIT} } {}
45e61fc3b6Sdan
46e61fc3b6Sdando_select_test fts3query-1.5 {
47e61fc3b6Sdan  SELECT * FROM t1;
48e61fc3b6Sdan} {{The source code for SQLite is in the public}}
49e61fc3b6Sdando_select_test fts3query-1.6 {
50e61fc3b6Sdan  SELECT * FROM t1 WHERE t1 MATCH 'sqlite'
51e61fc3b6Sdan} {{The source code for SQLite is in the public}}
52e61fc3b6Sdan
53e61fc3b6Sdan
54e61fc3b6Sdanset sqlite_fts3_enable_parentheses 1
55e61fc3b6Sdando_test fts3query-2.1 {
56e61fc3b6Sdan  execsql {
57e61fc3b6Sdan    CREATE VIRTUAL TABLE zoink USING fts3;
58e61fc3b6Sdan    INSERT INTO zoink VALUES('The apple falls far from the tree');
59e61fc3b6Sdan  }
60e61fc3b6Sdan} {}
61e61fc3b6Sdando_test fts3query-2.2 {
62e61fc3b6Sdan  execsql {
63e61fc3b6Sdan    SELECT docid FROM zoink WHERE zoink MATCH '(apple oranges) AND apple'
64e61fc3b6Sdan  }
65e61fc3b6Sdan} {}
66e61fc3b6Sdando_test fts3query-2.3 {
67e61fc3b6Sdan  execsql {
68e61fc3b6Sdan    SELECT docid FROM zoink WHERE zoink MATCH 'apple AND (oranges apple)'
69e61fc3b6Sdan  }
70e61fc3b6Sdan} {}
71e61fc3b6Sdanset sqlite_fts3_enable_parentheses 0
72e61fc3b6Sdan
73e61fc3b6Sdando_test fts3query-3.1 {
74e61fc3b6Sdan  execsql {
75e61fc3b6Sdan    CREATE VIRTUAL TABLE foobar using FTS3(description, tokenize porter);
76e61fc3b6Sdan    INSERT INTO foobar (description) values ('
77e61fc3b6Sdan      Filed under: Emerging Technologies, EV/Plug-in, Hybrid, Chevrolet, GM,
78e61fc3b6Sdan      ZENN 2011 Chevy Volt - Click above for high-res image gallery There are
79e61fc3b6Sdan      16 days left in the month of December. Besides being time for most
80e61fc3b6Sdan      Americans to kick their Christmas shopping sessions into high gear and
81e61fc3b6Sdan      start planning their resolutions for 2010, it also means that there''s
82e61fc3b6Sdan      precious little time for EEStor to "deliver functional technology" to
83e61fc3b6Sdan      Zenn Motors as promised. Still, the promises held out by the secretive
84e61fc3b6Sdan      company are too great for us to forget about entirely. We''d love for
85e61fc3b6Sdan      EEStor''s claims to be independently verified and proven accurate, as
86e61fc3b6Sdan      would just about anyone else looking to break free of petroleum in fav
87e61fc3b6Sdan    ');
88e61fc3b6Sdan  }
89e61fc3b6Sdan} {}
90e61fc3b6Sdan
91e61fc3b6Sdando_test fts3query-3.2 {
92e61fc3b6Sdan  execsql { SELECT docid FROM foobar WHERE description MATCH '"high sp d"' }
93e61fc3b6Sdan} {}
94e61fc3b6Sdan
953540c1f7Sdanproc mit {blob} {
963540c1f7Sdan  set scan(littleEndian) i*
973540c1f7Sdan  set scan(bigEndian) I*
983540c1f7Sdan  binary scan $blob $scan($::tcl_platform(byteOrder)) r
993540c1f7Sdan  return $r
1003540c1f7Sdan}
1013540c1f7Sdandb func mit mit
1023540c1f7Sdan
1033540c1f7Sdando_test fts3query-3.3 {
1043540c1f7Sdan  execsql { SELECT mit(matchinfo(foobar)) FROM foobar WHERE foobar MATCH 'the' }
105f596da5cSdan} {{1 1 3 3 1}}
1063540c1f7Sdan
107c26c0049Sdan# The following tests check that ticket 775b39dd3c has been fixed.
108c26c0049Sdan#
109c26c0049Sdando_test fts3query-4.1 {
110c26c0049Sdan  execsql {
111c26c0049Sdan    DROP TABLE IF EXISTS t1;
112c26c0049Sdan    CREATE TABLE t1(number INTEGER PRIMARY KEY, date);
113c26c0049Sdan    CREATE INDEX i1 ON t1(date);
114c26c0049Sdan    CREATE VIRTUAL TABLE ft USING fts3(title);
115c26c0049Sdan    CREATE TABLE bt(title);
116c26c0049Sdan  }
117c26c0049Sdan} {}
1183985479bSdando_eqp_test fts3query-4.2 {
1193985479bSdan  SELECT t1.number FROM t1, ft WHERE t1.number=ft.rowid ORDER BY t1.date
1203985479bSdan} {
121b3f0276bSdrh  QUERY PLAN
122*8210233cSdrh  |--SCAN t1 USING COVERING INDEX i1
123*8210233cSdrh  `--SCAN ft VIRTUAL TABLE INDEX 1:
1243985479bSdan}
1253985479bSdando_eqp_test fts3query-4.3 {
1263985479bSdan  SELECT t1.number FROM ft, t1 WHERE t1.number=ft.rowid ORDER BY t1.date
1273985479bSdan} {
128b3f0276bSdrh  QUERY PLAN
129*8210233cSdrh  |--SCAN t1 USING COVERING INDEX i1
130*8210233cSdrh  `--SCAN ft VIRTUAL TABLE INDEX 1:
1313985479bSdan}
1323985479bSdando_eqp_test fts3query-4.4 {
1333985479bSdan  SELECT t1.number FROM t1, bt WHERE t1.number=bt.rowid ORDER BY t1.date
1343985479bSdan} {
135b3f0276bSdrh  QUERY PLAN
136*8210233cSdrh  |--SCAN t1 USING COVERING INDEX i1
137*8210233cSdrh  `--SEARCH bt USING INTEGER PRIMARY KEY (rowid=?)
1383985479bSdan}
1393985479bSdando_eqp_test fts3query-4.5 {
1403985479bSdan  SELECT t1.number FROM bt, t1 WHERE t1.number=bt.rowid ORDER BY t1.date
1413985479bSdan} {
142b3f0276bSdrh  QUERY PLAN
143*8210233cSdrh  |--SCAN t1 USING COVERING INDEX i1
144*8210233cSdrh  `--SEARCH bt USING INTEGER PRIMARY KEY (rowid=?)
1453985479bSdan}
146c26c0049Sdan
147c26c0049Sdan
148ddf80eb8Sdan# Test that calling matchinfo() with the wrong number of arguments, or with
149ddf80eb8Sdan# an invalid argument returns an error.
150ddf80eb8Sdan#
151ddf80eb8Sdando_execsql_test 5.1 {
152ddf80eb8Sdan  CREATE VIRTUAL TABLE t2 USING FTS4;
153ddf80eb8Sdan  INSERT INTO t2 VALUES('it was the first time in history');
154ddf80eb8Sdan}
155ddf80eb8Sdando_select_tests 5.2 -errorformat {
156ddf80eb8Sdan  wrong number of arguments to function %s()
157ddf80eb8Sdan} {
158ddf80eb8Sdan  1 "SELECT matchinfo() FROM t2 WHERE t2 MATCH 'history'"       matchinfo
159ddf80eb8Sdan  3 "SELECT snippet(t2, 1, 2, 3, 4, 5, 6) FROM t2 WHERE t2 MATCH 'history'"
160ddf80eb8Sdan    snippet
161ddf80eb8Sdan}
162ddf80eb8Sdando_select_tests 5.3 -errorformat {
163ddf80eb8Sdan  illegal first argument to %s
164ddf80eb8Sdan} {
165ddf80eb8Sdan  1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo
166ddf80eb8Sdan  2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'"   offsets
167ddf80eb8Sdan  3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'"   snippet
168ddf80eb8Sdan  4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'"  optimize
169ddf80eb8Sdan}
1700f0d3ddfSdrhsqlite3_db_config db DEFENSIVE 0
171ddf80eb8Sdando_execsql_test 5.4.0 { UPDATE t2_content SET c0content = X'1234' }
172ddf80eb8Sdando_select_tests 5.4 -errorformat {
173ddf80eb8Sdan  illegal first argument to %s
174ddf80eb8Sdan} {
175ddf80eb8Sdan  1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo
176ddf80eb8Sdan  2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'"   offsets
177ddf80eb8Sdan  3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'"   snippet
178ddf80eb8Sdan  4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'"  optimize
179ddf80eb8Sdan}
1801e66e40eSdando_catchsql_test 5.5.1 {
18199eaf397Sdan  SELECT matchinfo(t2, 'abcd') FROM t2 WHERE t2 MATCH 'history'
18299eaf397Sdan} {1 {unrecognized matchinfo request: d}}
1831e66e40eSdan
184ddf80eb8Sdando_execsql_test 5.5 { DROP TABLE t2 }
185ddf80eb8Sdan
1861e66e40eSdan
187ddf80eb8Sdan# Test the snippet() function with 1 to 6 arguments.
188ddf80eb8Sdan#
189ddf80eb8Sdando_execsql_test 6.1 {
190ddf80eb8Sdan  CREATE VIRTUAL TABLE t3 USING FTS4(a, b);
191ddf80eb8Sdan  INSERT INTO t3 VALUES('no gestures', 'another intriguing discovery by observing the hand gestures (called beats) people make while speaking. Research has shown that such gestures do more than add visual emphasis to our words (many people gesture while they''re on the telephone, for example); it seems they actually help our brains find words');
192ddf80eb8Sdan}
193ddf80eb8Sdando_select_tests 6.2 {
194ddf80eb8Sdan  1 "SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'gestures'"
195ddf80eb8Sdan  {{<b>...</b>hand <b>gestures</b> (called beats) people make while speaking. Research has shown that such <b>gestures</b> do<b>...</b>}}
196ddf80eb8Sdan
197ddf80eb8Sdan  2 "SELECT snippet(t3, 'XXX') FROM t3 WHERE t3 MATCH 'gestures'"
198ddf80eb8Sdan  {{<b>...</b>hand XXXgestures</b> (called beats) people make while speaking. Research has shown that such XXXgestures</b> do<b>...</b>}}
199ddf80eb8Sdan
200ddf80eb8Sdan  3 "SELECT snippet(t3, 'XXX', 'YYY') FROM t3 WHERE t3 MATCH 'gestures'"
201ddf80eb8Sdan  {{<b>...</b>hand XXXgesturesYYY (called beats) people make while speaking. Research has shown that such XXXgesturesYYY do<b>...</b>}}
202ddf80eb8Sdan
203ddf80eb8Sdan  4 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ') FROM t3 WHERE t3 MATCH 'gestures'"
204ddf80eb8Sdan  {{ZZZhand XXXgesturesYYY (called beats) people make while speaking. Research has shown that such XXXgesturesYYY doZZZ}}
205ddf80eb8Sdan
206ddf80eb8Sdan  5 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1) FROM t3 WHERE t3 MATCH 'gestures'"
207ddf80eb8Sdan  {{ZZZhand XXXgesturesYYY (called beats) people make while speaking. Research has shown that such XXXgesturesYYY doZZZ}}
208ddf80eb8Sdan
209ddf80eb8Sdan  6 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 0) FROM t3 WHERE t3 MATCH 'gestures'"
210ddf80eb8Sdan  {{no XXXgesturesYYY}}
211ddf80eb8Sdan
212ddf80eb8Sdan  7 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1, 5) FROM t3 WHERE t3 MATCH 'gestures'"
213ddf80eb8Sdan  {{ZZZthe hand XXXgesturesYYY (called beatsZZZ}}
214ddf80eb8Sdan}
215ddf80eb8Sdan
21688392bf3Sdan# Test some range queries on the rowid field.
21788392bf3Sdan#
21888392bf3Sdando_execsql_test 7.1 {
21988392bf3Sdan  CREATE VIRTUAL TABLE ft4 USING fts4(x);
22088392bf3Sdan  CREATE TABLE t4(x);
22188392bf3Sdan}
22288392bf3Sdan
22388392bf3Sdanset SMALLINT -9223372036854775808
22488392bf3Sdanset LARGEINT  9223372036854775807
22588392bf3Sdando_test 7.2 {
22688392bf3Sdan  db transaction {
22788392bf3Sdan    foreach {iFirst nEntry} [subst {
22888392bf3Sdan      0                      100
22988392bf3Sdan      $SMALLINT              100
23088392bf3Sdan      [expr $LARGEINT - 99]  100
23188392bf3Sdan    }] {
23288392bf3Sdan      for {set i 0} {$i < $nEntry} {incr i} {
23388392bf3Sdan        set iRowid [expr $i + $iFirst]
23488392bf3Sdan        execsql {
23588392bf3Sdan          INSERT INTO ft4(rowid, x) VALUES($iRowid, 'x y z');
23688392bf3Sdan          INSERT INTO  t4(rowid, x) VALUES($iRowid, 'x y z');
23788392bf3Sdan        }
23888392bf3Sdan      }
23988392bf3Sdan    }
24088392bf3Sdan  }
24188392bf3Sdan} {}
24288392bf3Sdan
24388392bf3Sdanforeach {tn iFirst iLast} [subst {
24488392bf3Sdan  1   5 10
24588392bf3Sdan  2   $SMALLINT [expr $SMALLINT+5]
24688392bf3Sdan  3   $SMALLINT [expr $SMALLINT+50]
24788392bf3Sdan  4   [expr $LARGEINT-5] $LARGEINT
24888392bf3Sdan  5   $LARGEINT $LARGEINT
24988392bf3Sdan  6   $SMALLINT $LARGEINT
25088392bf3Sdan  7   $SMALLINT $SMALLINT
25188392bf3Sdan  8   $LARGEINT $SMALLINT
25288392bf3Sdan}] {
25388392bf3Sdan  set res [db eval {
25488392bf3Sdan    SELECT rowid FROM t4 WHERE rowid BETWEEN $iFirst AND $iLast
25588392bf3Sdan  } ]
25688392bf3Sdan
25788392bf3Sdan  do_execsql_test 7.2.$tn.1.[llength $res] {
25888392bf3Sdan    SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast
25988392bf3Sdan  } $res
26007b38959Sdrh  set res [db eval {
26107b38959Sdrh    SELECT rowid FROM t4 WHERE rowid BETWEEN $iFirst AND $iLast
26207b38959Sdrh     ORDER BY +rowid DESC
26307b38959Sdrh  } ]
26488392bf3Sdan  do_execsql_test 7.2.$tn.2.[llength $res] {
26588392bf3Sdan    SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast
26688392bf3Sdan    ORDER BY rowid DESC
26707b38959Sdrh  } $res
26888392bf3Sdan}
26988392bf3Sdan
27088392bf3Sdanforeach ii [db eval {SELECT rowid FROM t4}] {
27188392bf3Sdan  set res1 [db eval {SELECT rowid FROM t4 WHERE rowid > $ii}]
27288392bf3Sdan  set res2 [db eval {SELECT rowid FROM t4 WHERE rowid < $ii}]
27307b38959Sdrh  set res1s [db eval {SELECT rowid FROM t4 WHERE rowid > $ii ORDER BY +rowid DESC}]
27407b38959Sdrh  set res2s [db eval {SELECT rowid FROM t4 WHERE rowid < $ii ORDER BY +rowid DESC}]
27588392bf3Sdan
27688392bf3Sdan  do_execsql_test 7.3.$ii.1 {
27788392bf3Sdan    SELECT rowid FROM ft4 WHERE rowid > $ii
27888392bf3Sdan  } $res1
27988392bf3Sdan
28088392bf3Sdan  do_execsql_test 7.3.$ii.2 {
28188392bf3Sdan    SELECT rowid FROM ft4 WHERE rowid < $ii
28288392bf3Sdan  } $res2
28388392bf3Sdan
28488392bf3Sdan  do_execsql_test 7.3.$ii.3 {
28588392bf3Sdan    SELECT rowid FROM ft4 WHERE rowid > $ii ORDER BY rowid DESC
28607b38959Sdrh  } $res1s
28788392bf3Sdan
28888392bf3Sdan  do_execsql_test 7.3.$ii.4 {
28988392bf3Sdan    SELECT rowid FROM ft4 WHERE rowid < $ii ORDER BY rowid DESC
29007b38959Sdrh  } $res2s
29188392bf3Sdan}
292e25ac099Sdan
293e61fc3b6Sdanfinish_test
294