| # 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. |
| # |
| #*********************************************************************** |
| # |
| # Tests focusing on the built-in fts5 tokenizers. |
| # |
| |
| source [file join [file dirname [info script]] fts5_common.tcl] |
| set testprefix fts5locale |
| |
| # If SQLITE_ENABLE_FTS5 is not defined, omit this file. |
| ifcapable !fts5 { |
| finish_test |
| return |
| } |
| |
| proc transform_token {locale token} { |
| switch -- $locale { |
| reverse { |
| set ret "" |
| foreach c [split $token ""] { |
| set ret "$c$ret" |
| } |
| set token $ret |
| } |
| |
| default { |
| # no-op |
| } |
| } |
| |
| set token |
| } |
| |
| proc tcl_create {args} { return "tcl_tokenize" } |
| proc tcl_tokenize {tflags text} { |
| set iToken 1 |
| set bSkip 0 |
| if {[sqlite3_fts5_locale]=="second"} { set bSkip 1 } |
| foreach {w iStart iEnd} [fts5_tokenize_split $text] { |
| incr iToken |
| if {(($iToken) % ($bSkip + 1))} continue |
| |
| set w [transform_token [sqlite3_fts5_locale] $w] |
| sqlite3_fts5_token $w $iStart $iEnd |
| } |
| } |
| |
| #------------------------------------------------------------------------- |
| # Check that queries can have a locale attached to them. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| |
| do_execsql_test 1.0 { |
| CREATE VIRTUAL TABLE t1 USING fts5(a, tokenize=tcl); |
| INSERT INTO t1 VALUES('abc'); |
| INSERT INTO t1 VALUES('cba'); |
| } {} |
| |
| do_execsql_test 1.1 { |
| SELECT rowid, a FROM t1( fts5_locale('en_US', 'abc') ); |
| } {1 abc} |
| |
| do_execsql_test 1.2 { |
| SELECT rowid, a FROM t1( fts5_locale('reverse', 'abc') ); |
| } {2 cba} |
| |
| |
| #------------------------------------------------------------------------- |
| # Test that the locale= option exists and seems to accept values. And |
| # that fts5_locale() values may only be inserted into an internal-content |
| # table if the locale=1 option was specified. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| |
| do_execsql_test 2.1 { |
| CREATE VIRTUAL TABLE b1 USING fts5(x, y, locale=1, tokenize=tcl); |
| CREATE VIRTUAL TABLE b2 USING fts5(x, y, locale=0, tokenize=tcl); |
| |
| CREATE VIRTUAL TABLE ttt USING fts5vocab('b1', instance); |
| } |
| |
| do_catchsql_test 2.2.1 { |
| CREATE VIRTUAL TABLE b3 USING fts5(x, y, locale=2); |
| } {1 {malformed locale=... directive}} |
| do_catchsql_test 2.2.2 { |
| CREATE VIRTUAL TABLE b3 USING fts5(x, y, locale=111); |
| } {1 {malformed locale=... directive}} |
| |
| do_catchsql_test 2.3 { |
| INSERT INTO b1(b1, rank) VALUES('locale', 0); |
| } {1 {SQL logic error}} |
| |
| do_execsql_test 2.4.1 { |
| INSERT INTO b1 VALUES('abc', 'one two three'); |
| } |
| |
| do_execsql_test 2.4.2 { |
| INSERT INTO b1 VALUES('def', fts5_locale('reverse', 'four five six')); |
| } |
| |
| do_execsql_test 2.5 { |
| INSERT INTO b2 VALUES('abc', 'one two three'); |
| } |
| |
| do_catchsql_test 2.6 { |
| INSERT INTO b2 VALUES('def', fts5_locale('reverse', 'four five six')); |
| } {1 {fts5_locale() requires locale=1}} |
| |
| do_execsql_test 2.7 { SELECT rowid FROM b1('one') } {1} |
| do_execsql_test 2.8 { SELECT rowid FROM b1('four') } {} |
| do_execsql_test 2.9 { SELECT rowid FROM b1('ruof') } 2 |
| do_execsql_test 2.10 { SELECT rowid FROM b1(fts5_locale('reverse', 'five'))} 2 |
| |
| do_execsql_test 2.11 { |
| SELECT x, quote(y) FROM b1 |
| } { |
| abc {'one two three'} |
| def {'four five six'} |
| } |
| |
| do_execsql_test 2.12 { SELECT quote(y) FROM b1('ruof') } { |
| {'four five six'} |
| } |
| |
| do_execsql_test 2.13 { |
| INSERT INTO b1(b1) VALUES('integrity-check'); |
| } |
| |
| do_execsql_test 2.14 { |
| INSERT INTO b1(b1) VALUES('rebuild'); |
| } |
| do_execsql_test 2.15 { |
| INSERT INTO b1(b1) VALUES('integrity-check'); |
| } |
| |
| do_execsql_test 2.16 { |
| DELETE FROM b1 WHERE rowid=2 |
| } |
| do_execsql_test 2.17 { |
| INSERT INTO b1(b1) VALUES('integrity-check'); |
| } |
| |
| do_execsql_test 2.18 { |
| INSERT INTO b1(rowid, x, y) VALUES( |
| test_setsubtype(45, 76), 'abc def', 'def abc' |
| ); |
| } |
| |
| #------------------------------------------------------------------------- |
| # Test the 'delete' command with contentless tables. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| |
| do_execsql_test 3.1 { |
| CREATE VIRTUAL TABLE c1 USING fts5(x, content=, tokenize=tcl, locale=1); |
| CREATE VIRTUAL TABLE c2 USING fts5vocab('c1', instance); |
| |
| INSERT INTO c1 VALUES('hello world'); |
| INSERT INTO c1 VALUES( fts5_locale('reverse', 'one two three') ); |
| } |
| |
| do_execsql_test 3.2 { |
| SELECT DISTINCT term FROM c2 ORDER BY 1 |
| } { |
| eerht eno hello owt world |
| } |
| |
| do_execsql_test 3.3 { |
| INSERT INTO c1(c1, rowid, x) |
| VALUES('delete', 2, fts5_locale('reverse', 'one two three') ); |
| } |
| |
| do_execsql_test 3.4 { |
| SELECT DISTINCT term FROM c2 ORDER BY 1 |
| } { |
| hello world |
| } |
| |
| #------------------------------------------------------------------------- |
| # Test that an UPDATE that updates a subset of the columns does not |
| # magically discard the locale from those columns not updated. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| |
| do_execsql_test 4.1 { |
| CREATE VIRTUAL TABLE d1 USING fts5(x, y, locale=1, tokenize=tcl); |
| CREATE VIRTUAL TABLE d2 USING fts5vocab('d1', instance); |
| |
| INSERT INTO d1(rowid, x, y) VALUES(1, 'abc', 'def'); |
| INSERT INTO d1(rowid, x, y) VALUES(2, 'ghi', fts5_locale('reverse', 'hello')); |
| } |
| |
| do_execsql_test 4.2 { |
| SELECT DISTINCT term FROM d2 ORDER BY 1 |
| } { |
| abc def ghi olleh |
| } |
| |
| do_execsql_test 4.3 { |
| UPDATE d1 SET x='jkl' WHERE rowid=2; |
| } |
| |
| do_execsql_test 4.4 { |
| SELECT DISTINCT term FROM d2 ORDER BY 1 |
| } { |
| abc def jkl olleh |
| } |
| |
| do_execsql_test 4.5 { |
| SELECT rowid, * FROM d1 |
| } { |
| 1 abc def |
| 2 jkl hello |
| } |
| |
| do_execsql_test 4.6 { |
| UPDATE d1 SET rowid=4 WHERE rowid=2 |
| } |
| |
| do_execsql_test 4.7 { |
| SELECT rowid, * FROM d1 |
| } { |
| 1 abc def |
| 4 jkl hello |
| } |
| |
| fts5_aux_test_functions db |
| |
| do_execsql_test 4.8.1 { |
| SELECT fts5_test_columntext(d1) FROM d1('jkl') |
| } {{jkl hello}} |
| do_execsql_test 4.8.2 { |
| SELECT fts5_test_columntext(d1) FROM d1(fts5_locale('reverse', 'hello')) |
| } {{jkl hello}} |
| |
| do_execsql_test 4.9 { |
| SELECT fts5_test_columnlocale(d1) FROM d1(fts5_locale('reverse', 'hello')) |
| } {{{} reverse}} |
| |
| do_execsql_test 4.10 { |
| SELECT fts5_test_columnlocale(d1) FROM d1 |
| } { |
| {{} {}} |
| {{} reverse} |
| } |
| |
| #------------------------------------------------------------------------- |
| # Test that if an fts5_locale() value is written to an UNINDEXED |
| # column it is stored as text. This is so that blobs and other values |
| # can also be stored as is. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| |
| do_execsql_test 5.1 { |
| CREATE VIRTUAL TABLE t1 USING fts5( |
| x, y UNINDEXED, locale=1, tokenize=tcl |
| ); |
| |
| INSERT INTO t1(rowid, x, y) VALUES(111, |
| fts5_locale('reverse', 'one two three'), |
| fts5_locale('reverse', 'four five six') |
| ); |
| } |
| |
| do_execsql_test 5.2 { |
| SELECT rowid, x, y FROM t1 |
| } { |
| 111 {one two three} {four five six} |
| } |
| |
| do_execsql_test 5.3 { |
| SELECT typeof(c0), typeof(c1), typeof(l0) FROM t1_content |
| } { |
| text text text |
| } |
| |
| #------------------------------------------------------------------------- |
| |
| foreach {tn opt} { |
| 1 {} |
| 2 {, columnsize=0} |
| } { |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| do_execsql_test 6.$tn.1 " |
| CREATE VIRTUAL TABLE y1 USING fts5(t, locale=1, tokenize=tcl $opt); |
| " |
| |
| do_execsql_test 6.$tn.2 { |
| INSERT INTO y1(rowid, t) VALUES |
| (1, fts5_locale('second', 'the city of London')), |
| (2, fts5_locale('second', 'shall have all the old')), |
| (3, fts5_locale('second', 'Liberties and Customs')), |
| (4, fts5_locale('second', 'which it hath been used to have')); |
| } |
| |
| fts5_aux_test_functions db |
| |
| do_execsql_test 6.$tn.3 { |
| SELECT fts5_test_columnsize(y1) FROM y1 |
| } { |
| 2 3 2 4 |
| } |
| |
| do_execsql_test 6.$tn.4 { |
| SELECT rowid, fts5_test_columnsize(y1) FROM y1('shall'); |
| } { |
| 2 3 |
| } |
| |
| do_execsql_test 6.$tn.5 { |
| SELECT rowid, fts5_test_columnsize(y1) FROM y1('shall'); |
| } { |
| 2 3 |
| } |
| |
| do_execsql_test 6.$tn.6 { |
| SELECT rowid, fts5_test_columnsize(y1) FROM y1('have'); |
| } { |
| 4 4 |
| } |
| |
| do_execsql_test 6.$tn.7 { |
| SELECT rowid, highlight(y1, 0, '[', ']') FROM y1('have'); |
| } { |
| 4 {which it hath been used to [have]} |
| } |
| |
| do_execsql_test 6.$tn.8 { |
| SELECT rowid, |
| highlight(y1, 0, '[', ']'), |
| snippet(y1, 0, '[', ']', '...', 10) |
| FROM y1('Liberties + Customs'); |
| } { |
| 3 {[Liberties and Customs]} |
| {[Liberties and Customs]} |
| } |
| } |
| |
| #------------------------------------------------------------------------- |
| reset_db |
| do_execsql_test 6.0 { |
| CREATE VIRTUAL TABLE x1 USING fts5(x); |
| } |
| do_catchsql_test 6.1 { |
| INSERT INTO x1(rowid, x) VALUES(123, fts5_locale('en_AU', 'hello world')); |
| } {1 {fts5_locale() requires locale=1}} |
| |
| do_execsql_test 6.2 { |
| SELECT typeof( fts5_locale(NULL, 'xyz') ), typeof( fts5_locale('', 'abc') ); |
| } {text text} |
| |
| #-------------------------------------------------------------------------- |
| # Test that fts5_locale() works with external-content tables. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| |
| do_execsql_test 7.1 { |
| CREATE TABLE t1(ii INTEGER PRIMARY KEY, bb BLOB, tt TEXT, locale TEXT); |
| CREATE VIEW v1 AS |
| SELECT ii AS rowid, bb, fts5_locale(locale, tt) AS tt FROM t1; |
| |
| CREATE VIRTUAL TABLE ft USING fts5( |
| bb, tt, locale=1, tokenize=tcl, content=v1 |
| ); |
| |
| INSERT INTO t1 VALUES(1, NULL, 'one two three', NULL); |
| INSERT INTO t1 VALUES(2, '7800616263', 'four five six', 'reverse'); |
| INSERT INTO t1 VALUES(3, '000000007800616263', 'seven eight nine', 'second'); |
| } |
| |
| do_execsql_test 7.2 { |
| INSERT INTO ft(ft) VALUES('rebuild'); |
| INSERT INTO ft(ft) VALUES('integrity-check'); |
| } |
| |
| do_execsql_test 7.3 { |
| SELECT rowid, quote(bb), quote(tt) FROM ft |
| } { |
| 1 NULL {'one two three'} |
| 2 '7800616263' {'four five six'} |
| 3 '000000007800616263' {'seven eight nine'} |
| } |
| |
| do_execsql_test 7.4 { SELECT rowid FROM ft('six'); } |
| do_execsql_test 7.5 { SELECT rowid FROM ft(fts5_locale('reverse','six')); } 2 |
| |
| fts5_aux_test_functions db |
| |
| do_execsql_test 7.6 { |
| SELECT fts5_test_columnlocale(ft) FROM ft; |
| } { |
| {{} {}} {{} reverse} {{} second} |
| } |
| |
| #------------------------------------------------------------------------- |
| # Test that the porter tokenizer works with locales. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| |
| do_execsql_test 8.1 { |
| CREATE VIRTUAL TABLE ft USING fts5(tt, locale=1, tokenize="porter tcl"); |
| CREATE VIRTUAL TABLE vocab USING fts5vocab('ft', instance); |
| |
| INSERT INTO ft(rowid, tt) VALUES |
| (111, fts5_locale('second', 'the porter tokenizer is a wrapper tokenizer')), |
| (222, fts5_locale('reverse', 'This value may also be set')); |
| } |
| |
| do_execsql_test 8.1 { |
| SELECT DISTINCT term FROM vocab ORDER BY 1 |
| } { |
| a eb eulav osla sihT te the token yam |
| } |
| |
| #------------------------------------------------------------------------- |
| # Test that position-lists (used by xInst, xPhraseFirst etc.) work with |
| # locales and modes other than detail=full. |
| # |
| foreach {tn detail} { |
| 1 detail=full |
| 2 detail=none |
| 3 detail=column |
| } { |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| do_execsql_test 9.$tn.0 " |
| CREATE VIRTUAL TABLE ft USING fts5(tt, locale=1, tokenize=tcl, $detail); |
| " |
| do_execsql_test 9.$tn.1 { |
| CREATE VIRTUAL TABLE vocab USING fts5vocab('ft', instance); |
| INSERT INTO ft(rowid, tt) VALUES |
| (-1, fts5_locale('second', 'it is an ancient mariner')); |
| } |
| |
| do_execsql_test 9.$tn.2 { |
| SELECT DISTINCT term FROM vocab |
| } {an it mariner} |
| |
| do_execsql_test 9.$tn.3 { |
| SELECT highlight(ft, 0, '[', ']') FROM ft('mariner') |
| } {{it is an ancient [mariner]}} |
| } |
| |
| #------------------------------------------------------------------------- |
| # Check some corrupt fts5_locale() blob formats are detected. |
| # |
| foreach_detail_mode $::testprefix { |
| |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| fts5_aux_test_functions db |
| do_execsql_test 10.1 { |
| CREATE TABLE x1(ii INTEGER PRIMARY KEY, x); |
| CREATE VIRTUAL TABLE ft USING fts5(x, |
| content=x1, content_rowid=ii, locale=1, detail=%DETAIL%, columnsize=0 |
| ); |
| |
| CREATE VIRTUAL TABLE ft2 USING fts5( |
| x, locale=1, detail=%DETAIL%, columnsize=0 |
| ); |
| } |
| |
| foreach {tn v} { |
| 1 X'001152' |
| 2 X'0011223344' |
| 3 X'00E0B2EB68656c6c6f' |
| 4 X'00E0B2EB0068656c6c6f' |
| } { |
| do_execsql_test 10.2.$tn.0 { INSERT INTO ft(ft) VALUES('delete-all') } |
| do_execsql_test 10.2.$tn.1 { DELETE FROM x1; } |
| do_execsql_test 10.2.$tn.2 " INSERT INTO x1 VALUES(NULL, $v) " |
| |
| do_catchsql_test 10.2.$tn.3 { |
| INSERT INTO ft(ft) VALUES('rebuild'); |
| } {0 {}} |
| |
| do_catchsql_test 10.2.$tn.4 " |
| SELECT * FROM ft( test_setsubtype($v, 76) ); |
| " {1 {fts5: syntax error near ""}} |
| |
| do_execsql_test 10.2.$tn.5 { |
| INSERT INTO ft(rowid, x) VALUES(1, 'hello world'); |
| } |
| |
| if {"%DETAIL%"=="full"} { |
| do_execsql_test 10.2.$tn.6 { |
| SELECT fts5_test_poslist(ft) FROM ft('world'); |
| } {0.0.1} |
| |
| do_execsql_test 10.2.$tn.7.1 { |
| SELECT fts5_test_columnsize(ft) FROM ft('world'); |
| } {1} |
| |
| do_execsql_test 10.2.$tn.7.2 { |
| SELECT fts5_test_columnlocale(ft) FROM ft('world'); |
| } {{{}}} |
| } |
| |
| do_catchsql_test 10.2.$tn.8 { |
| SELECT count(*) FROM ft('hello') |
| } {0 1} |
| |
| do_catchsql_test 10.2.$tn.9 { |
| PRAGMA integrity_check; |
| } {0 ok} |
| |
| do_execsql_test 10.2.$tn.10 { |
| DELETE FROM x1; |
| INSERT INTO x1(ii, x) VALUES(1, 'hello world'); |
| } |
| |
| do_catchsql_test 10.2.$tn.11 " |
| INSERT INTO ft(ft, rowid, x) VALUES('delete', 1, test_setsubtype($v,76) ) |
| " {0 {}} |
| |
| do_catchsql_test 10.2.$tn.12 " |
| INSERT INTO ft(rowid, x) VALUES(2, test_setsubtype($v,76) ) |
| " {0 {}} |
| |
| do_execsql_test 10.2.$tn.13 { |
| INSERT INTO ft2(rowid, x) VALUES(1, 'hello world'); |
| } |
| do_execsql_test 10.2.$tn.14 "UPDATE ft2_content SET c0=$v" |
| |
| do_catchsql_test 10.2.$tn.15 { |
| PRAGMA integrity_check; |
| } {0 {{malformed inverted index for FTS5 table main.ft2}}} |
| |
| do_execsql_test 10.2.$tn.16 { |
| DELETE FROM ft2_content; |
| INSERT INTO ft2(ft2) VALUES('rebuild'); |
| } |
| } |
| |
| } |
| |
| #------------------------------------------------------------------------- |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| fts5_aux_test_functions db |
| do_execsql_test 11.0 { |
| CREATE VIRTUAL TABLE x1 USING fts5(abc, locale=1); |
| INSERT INTO x1(rowid, abc) VALUES(123, fts5_locale('en_US', 'one two three')); |
| } |
| |
| do_catchsql_test 11.1 { |
| SELECT fts5_columnlocale(x1, -1) FROM x1('two'); |
| } {1 SQLITE_RANGE} |
| do_catchsql_test 11.2 { |
| SELECT fts5_columnlocale(x1, 1) FROM x1('two'); |
| } {1 SQLITE_RANGE} |
| |
| #------------------------------------------------------------------------- |
| # |
| reset_db |
| do_test 12.0 { |
| list [catch { |
| sqlite3_fts5_create_tokenizer -v2 -version 3 db tcl tcl_create |
| } msg] $msg |
| } {1 {error in fts5_api.xCreateTokenizer_v2()}} |
| |
| #------------------------------------------------------------------------- |
| # Tests for auxiliary function fts5_get_locale(). |
| # |
| reset_db |
| |
| # Check that if the table does not support locale=1, fts5_get_locale() |
| # always returns NULL. |
| do_execsql_test 13.1.0 { |
| CREATE VIRTUAL TABLE nolocale USING fts5(a, b); |
| INSERT INTO nolocale VALUES('one two three', 'four five six'); |
| INSERT INTO nolocale VALUES('three two one', 'seven eight nine'); |
| } |
| do_execsql_test 13.1.1 { |
| SELECT fts5_get_locale(nolocale, 0) IS NULL FROM nolocale; |
| } {1 1} |
| do_execsql_test 13.1.2 { |
| SELECT fts5_get_locale(nolocale, 1) IS NULL FROM nolocale('one + two'); |
| } {1} |
| do_execsql_test 13.1.3 { |
| SELECT fts5_get_locale(nolocale, 0) IS NULL FROM nolocale('one AND two'); |
| } {1 1} |
| do_execsql_test 13.1.4 { |
| SELECT |
| fts5_get_locale(nolocale, 1) IS NULL |
| FROM nolocale('three AND two') ORDER BY rank |
| } {1 1} |
| do_catchsql_test 13.1.5 { |
| SELECT fts5_get_locale(nolocale, 2) IS NULL FROM nolocale('three AND two'); |
| } {1 {column index out of range}} |
| do_catchsql_test 13.1.6 { |
| SELECT fts5_get_locale(nolocale, -1) IS NULL FROM nolocale('three AND two'); |
| } {1 {column index out of range}} |
| do_catchsql_test 13.1.7 { |
| SELECT fts5_get_locale(nolocale) IS NULL FROM nolocale('three AND two'); |
| } {1 {wrong number of arguments to function fts5_get_locale()}} |
| do_catchsql_test 13.1.8 { |
| SELECT fts5_get_locale(nolocale, 0, 0) IS NULL FROM nolocale('three AND two'); |
| } {1 {wrong number of arguments to function fts5_get_locale()}} |
| do_catchsql_test 13.1.9 { |
| SELECT fts5_get_locale(nolocale, 'text') FROM nolocale('three AND two'); |
| } {1 {non-integer argument passed to function fts5_get_locale()}} |
| |
| |
| # Check that if the table does support locale=1, fts5_get_locale() |
| # returns the locale of the identified row/column. |
| do_execsql_test 13.2.0 { |
| CREATE VIRTUAL TABLE ft USING fts5(a, b, locale=1); |
| INSERT INTO ft VALUES( |
| fts5_locale('th_TH', 'one two three'), 'four five six seven' |
| ); |
| INSERT INTO ft VALUES( |
| 'three two one', fts5_locale('en_AU', 'seven eight nine') |
| ); |
| } |
| |
| do_execsql_test 13.2.1 { |
| SELECT quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) FROM ft |
| } { 'th_TH' NULL NULL 'en_AU' } |
| do_execsql_test 13.2.2 { |
| SELECT |
| quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) |
| FROM ft('one AND three') |
| } { 'th_TH' NULL NULL 'en_AU' } |
| do_execsql_test 13.2.3 { |
| SELECT |
| quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) |
| FROM ft('one AND three') ORDER BY rank |
| } { NULL 'en_AU' 'th_TH' NULL } |
| do_execsql_test 13.2.4 { |
| SELECT |
| quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) |
| FROM ft('one AND three') ORDER BY rowid |
| } { 'th_TH' NULL NULL 'en_AU' } |
| |
| do_execsql_test 13.2.5 { |
| SELECT |
| quote(fts5_get_locale(ft, '0')), quote(fts5_get_locale(ft, 1)) |
| FROM ft('one AND three') ORDER BY rowid |
| } { 'th_TH' NULL NULL 'en_AU' } |
| |
| do_catchsql_test 13.2.6 { |
| SELECT |
| quote(fts5_get_locale(ft, '0.0')), quote(fts5_get_locale(ft, 1)) |
| FROM ft('one AND three') ORDER BY rowid |
| } {1 {non-integer argument passed to function fts5_get_locale()}} |
| do_catchsql_test 13.2.7 { |
| SELECT |
| quote(fts5_get_locale(ft, 0.0)), quote(fts5_get_locale(ft, 1)) |
| FROM ft('one AND three') ORDER BY rowid |
| } {1 {non-integer argument passed to function fts5_get_locale()}} |
| |
| #------------------------------------------------------------------------- |
| # Check that UPDATE statements that may affect more than one row work. |
| # |
| reset_db |
| do_execsql_test 14.1 { |
| CREATE VIRTUAL TABLE ft USING fts5(a, b, locale=1); |
| } |
| |
| do_execsql_test 14.2 { |
| INSERT INTO ft VALUES('hello', 'world'); |
| } |
| |
| do_execsql_test 14.3 { |
| UPDATE ft SET b = fts5_locale('en_AU', 'world'); |
| } |
| |
| do_execsql_test 14.4 { |
| INSERT INTO ft VALUES(X'abcd', X'1234'); |
| } {} |
| |
| do_execsql_test 14.5 { |
| SELECT quote(a), quote(b) FROM ft |
| } {'hello' 'world' X'ABCD' X'1234'} |
| |
| do_execsql_test 14.6 { |
| DELETE FROM ft; |
| INSERT INTO ft VALUES(NULL, 'null'); |
| INSERT INTO ft VALUES(123, 'int'); |
| INSERT INTO ft VALUES(345.0, 'real'); |
| INSERT INTO ft VALUES('abc', 'text'); |
| INSERT INTO ft VALUES(fts5_locale('abc', 'def'), 'text'); |
| |
| SELECT a, typeof(a), b FROM ft |
| } { |
| {} null null |
| 123 integer int |
| 345.0 real real |
| abc text text |
| def text text |
| } |
| |
| do_execsql_test 14.7 { |
| SELECT quote(c0), typeof(c0) FROM ft_content |
| } { |
| NULL null |
| 123 integer |
| 345.0 real |
| 'abc' text |
| 'def' text |
| } |
| |
| #------------------------------------------------------------------------- |
| # Check that inserting UNINDEXED columns between indexed columns of a |
| # locale=1 table does not cause a problem. |
| # |
| reset_db |
| sqlite3_fts5_create_tokenizer -v2 db tcl tcl_create |
| fts5_aux_test_functions db |
| |
| do_execsql_test 15.1 { |
| CREATE VIRTUAL TABLE ft USING fts5(a, b UNINDEXED, c, locale=1, tokenize=tcl); |
| } |
| |
| do_execsql_test 15.2 { |
| INSERT INTO ft VALUES('one', 'two', 'three'); |
| INSERT INTO ft VALUES('one', 'two', fts5_locale('loc', 'three')); |
| } |
| |
| do_execsql_test 15.3 { |
| SELECT c2, l2 FROM ft_content |
| } {three {} three loc} |
| |
| do_execsql_test 15.4 { |
| SELECT c, fts5_columnlocale(ft, 2) FROM ft |
| } {three {} three loc} |
| |
| |
| finish_test |
| |