Annotation of embedaddon/sqlite3/test/e_fts3.test, revision 1.1.1.1

1.1       misho       1: # 2009 November 28
                      2: #
                      3: # The author disclaims copyright to this source code.  In place of
                      4: # a legal notice, here is a blessing:
                      5: #
                      6: #    May you do good and not evil.
                      7: #    May you find forgiveness for yourself and forgive others.
                      8: #    May you share freely, never taking more than you give.
                      9: #
                     10: #***********************************************************************
                     11: #
                     12: # This file implements tests to verify the "testable statements" in the
                     13: # fts3.in document.
                     14: #
                     15: 
                     16: set testdir [file dirname $argv0]
                     17: source $testdir/tester.tcl
                     18: 
                     19: # If this build does not include FTS3, skip the tests in this file.
                     20: #
                     21: ifcapable !fts3 { finish_test ; return }
                     22: source $testdir/fts3_common.tcl
                     23: source $testdir/malloc_common.tcl
                     24: 
                     25: # Procs used to make the tests in this file easier to read.
                     26: #
                     27: proc ddl_test {tn ddl} {
                     28:   uplevel [list do_write_test e_fts3-$tn sqlite_master $ddl]
                     29: }
                     30: proc write_test {tn tbl sql} {
                     31:   uplevel [list do_write_test e_fts3-$tn $tbl $sql]
                     32: }
                     33: proc read_test {tn sql result} {
                     34:   uplevel [list do_select_test e_fts3-$tn $sql $result]
                     35: }
                     36: proc error_test {tn sql result} {
                     37:   uplevel [list do_error_test e_fts3-$tn $sql $result]
                     38: }
                     39: 
                     40: 
                     41: #-------------------------------------------------------------------------
                     42: # The body of the following [foreach] block contains test cases to verify
                     43: # that the example code in fts3.html works as expected. The tests run three
                     44: # times, with different values for DO_MALLOC_TEST.
                     45: # 
                     46: #   DO_MALLOC_TEST=0: Run tests with no OOM errors.
                     47: #   DO_MALLOC_TEST=1: Run tests with transient OOM errors.
                     48: #   DO_MALLOC_TEST=2: Run tests with persistent OOM errors.
                     49: #
                     50: foreach {DO_MALLOC_TEST enc} {
                     51:   0 utf-8
                     52:   1 utf-8
                     53:   2 utf-8
                     54:   1 utf-16
                     55: } {
                     56: 
                     57: #if {$DO_MALLOC_TEST} break
                     58: 
                     59: # Reset the database and database connection. If this iteration of the 
                     60: # [foreach] loop is testing with OOM errors, disable the lookaside buffer.
                     61: #
                     62: db close
                     63: forcedelete test.db test.db-journal
                     64: sqlite3 db test.db
                     65: if {$DO_MALLOC_TEST} { sqlite3_db_config_lookaside db 0 0 0 }
                     66: db eval "PRAGMA encoding = '$enc'"
                     67: 
                     68: proc mit {blob} {
                     69:   set scan(littleEndian) i*
                     70:   set scan(bigEndian) I*
                     71:   binary scan $blob $scan($::tcl_platform(byteOrder)) r
                     72:   return $r
                     73: }
                     74: db func mit mit
                     75: 
                     76: ##########################################################################
                     77: # Test the example CREATE VIRTUAL TABLE statements in section 1.1 
                     78: # of fts3.in.
                     79: #
                     80: ddl_test   1.1.1.1 {CREATE VIRTUAL TABLE data USING fts3()}
                     81: read_test  1.1.1.2 {PRAGMA table_info(data)} {0 content {} 0 {} 0}
                     82: 
                     83: ddl_test   1.1.2.1 {
                     84:   CREATE VIRTUAL TABLE pages USING fts3(title, keywords, body)
                     85: }
                     86: read_test  1.1.2.2 {
                     87:   PRAGMA table_info(pages)
                     88: } {0 title {} 0 {} 0 1 keywords {} 0 {} 0 2 body {} 0 {} 0}
                     89: 
                     90: ddl_test   1.1.3.1 {
                     91:   CREATE VIRTUAL TABLE mail USING fts3(
                     92:       subject VARCHAR(256) NOT NULL,
                     93:       body TEXT CHECK(length(body)<10240)
                     94:   )
                     95: }
                     96: read_test  1.1.3.2 {
                     97:   PRAGMA table_info(mail)
                     98: } {0 subject {} 0 {} 0 1 body {} 0 {} 0}
                     99: 
                    100: # A very large string. Used to test if the constraint on column "body" of
                    101: # table "mail" is enforced (it should not be - FTS3 tables do not support
                    102: # constraints).
                    103: set largetext [string repeat "the quick brown fox " 5000]
                    104: write_test 1.1.3.3 mail_content { INSERT INTO mail VALUES(NULL, $largetext) }
                    105: read_test  1.1.3.4 {
                    106:   SELECT subject IS NULL, length(body) FROM mail
                    107: } [list 1 100000]
                    108: 
                    109: ddl_test   1.1.4.1 {
                    110:   CREATE VIRTUAL TABLE papers USING fts3(author, document, tokenize=porter)
                    111: }
                    112: read_test  1.1.4.2 {
                    113:   PRAGMA table_info(papers)
                    114: } {0 author {} 0 {} 0 1 document {} 0 {} 0}
                    115: 
                    116: ddl_test   1.1.5.1 {
                    117:   CREATE VIRTUAL TABLE simpledata USING fts3(tokenize=simple)
                    118: }
                    119: read_test  1.1.5.2 {
                    120:   PRAGMA table_info(simpledata)
                    121: } {0 content {} 0 {} 0}
                    122: 
                    123: ifcapable icu {
                    124:   ddl_test 1.1.6.1 {
                    125:     CREATE VIRTUAL TABLE names USING fts3(a, b, tokenize=icu en_AU)
                    126:   }
                    127:   read_test  1.1.6.2 {
                    128:     PRAGMA table_info(names)
                    129:   } {0 a {} 0 {} 0 1 b {} 0 {} 0}
                    130: }
                    131: 
                    132: ddl_test   1.1.7.1 {DROP TABLE data}
                    133: ddl_test   1.1.7.2 {DROP TABLE pages}
                    134: ddl_test   1.1.7.3 {DROP TABLE mail}
                    135: ddl_test   1.1.7.4 {DROP TABLE papers}
                    136: ddl_test   1.1.7.5 {DROP TABLE simpledata}
                    137: read_test  1.1.7.6 {SELECT * FROM sqlite_master} {}
                    138: 
                    139: # The following is not one of the examples in section 1.1. It tests 
                    140: # specifying an FTS3 table with no module arguments using a slightly
                    141: # different syntax.
                    142: ddl_test   1.1.8.1 {CREATE VIRTUAL TABLE data USING fts3;}
                    143: read_test  1.1.8.2 {PRAGMA table_info(data)} {0 content {} 0 {} 0}
                    144: ddl_test   1.1.8.3 {DROP TABLE data}
                    145: 
                    146: ##########################################################################
                    147: # Test the examples in section 1.2 (populating fts3 tables)
                    148: #
                    149: ddl_test   1.2.1.1 {
                    150:   CREATE VIRTUAL TABLE pages USING fts3(title, body);
                    151: }
                    152: write_test 1.2.1.2 pages_content {
                    153:   INSERT INTO pages(docid, title, body) 
                    154:   VALUES(53, 'Home Page', 'SQLite is a software...');
                    155: }
                    156: read_test  1.2.1.3 {
                    157:   SELECT docid, * FROM pages
                    158: } {53 {Home Page} {SQLite is a software...}}
                    159: 
                    160: write_test 1.2.1.4 pages_content {
                    161:   INSERT INTO pages(title, body) 
                    162:   VALUES('Download', 'All SQLite source code...');
                    163: }
                    164: read_test  1.2.1.5 {
                    165:   SELECT docid, * FROM pages
                    166: } {53 {Home Page} {SQLite is a software...} 54 Download {All SQLite source code...}}
                    167: 
                    168: write_test 1.2.1.6 pages_content {
                    169:   UPDATE pages SET title = 'Download SQLite' WHERE rowid = 54
                    170: }
                    171: read_test  1.2.1.7 {
                    172:   SELECT docid, * FROM pages
                    173: } {53 {Home Page} {SQLite is a software...} 54 {Download SQLite} {All SQLite source code...}}
                    174: 
                    175: write_test 1.2.1.8 pages_content { DELETE FROM pages }
                    176: read_test  1.2.1.9 { SELECT docid, * FROM pages } {}
                    177: 
                    178: do_error_test fts3-1.2.1.10 {
                    179:   INSERT INTO pages(rowid, docid, title, body) VALUES(1, 2, 'A title', 'A document body');
                    180: } {SQL logic error or missing database}
                    181: 
                    182: # Test the optimize() function example:
                    183: ddl_test   1.2.2.1 { CREATE VIRTUAL TABLE docs USING fts3 }
                    184: write_test 1.2.2.2 docs_content {
                    185:   INSERT INTO docs VALUES('Others translate the first clause as');
                    186: }
                    187: write_test 1.2.2.3 docs_content {
                    188:   INSERT INTO docs VALUES('"which is for Solomon," meaning that');
                    189: }
                    190: write_test 1.2.2.4 docs_content {
                    191:   INSERT INTO docs VALUES('the book is dedicated to Solomon.');
                    192: }
                    193: read_test  1.2.2.5 { SELECT count(*) FROM docs_segdir } {3}
                    194: write_test 1.2.2.6 docs_segdir {
                    195:   INSERT INTO docs(docs) VALUES('optimize');
                    196: }
                    197: read_test  1.2.2.7 { SELECT count(*) FROM docs_segdir } {1}
                    198: ddl_test   1.2.2.8 { DROP TABLE docs }
                    199: 
                    200: ##########################################################################
                    201: # Test the examples in section 1.3 (querying FTS3 tables)
                    202: #
                    203: ddl_test   1.3.1.1 { CREATE VIRTUAL TABLE mail USING fts3(subject, body) }
                    204: read_test  1.3.1.2 { 
                    205:   SELECT * FROM mail WHERE rowid = 15;                -- Fast. Rowid lookup.
                    206:   SELECT * FROM mail WHERE body MATCH 'sqlite';       -- Fast. Full-text query.
                    207:   SELECT * FROM mail WHERE mail MATCH 'search';       -- Fast. Full-text query.
                    208:   SELECT * FROM mail WHERE rowid BETWEEN 15 AND 20;   -- Slow. Linear scan.
                    209:   SELECT * FROM mail WHERE subject = 'database';      -- Slow. Linear scan.
                    210:   SELECT * FROM mail WHERE subject MATCH 'database';  -- Fast. Full-text query.
                    211: } {}
                    212: ddl_test   1.3.1.3 { DROP TABLE mail }
                    213: 
                    214: ddl_test   1.3.2.1 { CREATE VIRTUAL TABLE mail USING fts3(subject, body) }
                    215: 
                    216: write_test 1.3.2.2 mail_content {
                    217:   INSERT INTO mail(docid, subject, body) 
                    218:   VALUES(1, 'software feedback', 'found it too slow')
                    219: }
                    220: write_test 1.3.2.3 mail_content {
                    221:   INSERT INTO mail(docid, subject, body) 
                    222:   VALUES(2, 'software feedback', 'no feedback')
                    223: }
                    224: write_test 1.3.2.4 mail_content {
                    225:   INSERT INTO mail(docid, subject, body) 
                    226:   VALUES(3, 'slow lunch order',  'was a software problem')
                    227: }
                    228: read_test  1.3.2.5 {
                    229:   SELECT * FROM mail WHERE subject MATCH 'software'
                    230: } {{software feedback} {found it too slow} {software feedback} {no feedback}}
                    231: read_test  1.3.2.6 {
                    232:   SELECT * FROM mail WHERE body MATCH 'feedback'
                    233: } {{software feedback} {no feedback}}
                    234: read_test  1.3.2.7 {
                    235:   SELECT * FROM mail WHERE mail MATCH 'software'
                    236: } {{software feedback} {found it too slow} {software feedback} {no feedback} {slow lunch order} {was a software problem}}
                    237: read_test  1.3.2.7 {
                    238:   SELECT * FROM mail WHERE mail MATCH 'slow'
                    239: } {{software feedback} {found it too slow} {slow lunch order} {was a software problem}}
                    240: ddl_test   1.3.2.8 { DROP TABLE mail }
                    241: 
                    242: ddl_test   1.3.3.1 { CREATE VIRTUAL TABLE docs USING fts3(content) }
                    243: read_test  1.3.3.2 { SELECT * FROM docs WHERE docs MATCH 'sqlite' } {}
                    244: read_test  1.3.3.3 { SELECT * FROM docs WHERE docs.docs MATCH 'sqlite' } {}
                    245: read_test  1.3.3.4 { SELECT * FROM docs WHERE main.docs.docs MATCH 'sqlite' } {}
                    246: do_error_test e_fts3-1.3.3.5 { 
                    247:   SELECT * FROM docs WHERE main.docs MATCH 'sqlite' 
                    248: } {no such column: main.docs}
                    249: ddl_test   1.3.2.8 { DROP TABLE docs }
                    250: 
                    251: ##########################################################################
                    252: # Test the examples in section 3 (full-text index queries).
                    253: #
                    254: ddl_test   1.4.1.1 { CREATE VIRTUAL TABLE docs USING fts3(title, body) }
                    255: unset -nocomplain R
                    256: foreach {tn title body} {
                    257:   2 "linux driver" "a device"
                    258:   3 "driver"       "linguistic trick"
                    259:   4 "problems"     "linux problems"
                    260:   5 "linux"        "big problems"
                    261:   6 "linux driver" "a device driver problem"
                    262:   7 "good times"   "applications for linux"
                    263:   8 "not so good"  "linux applications"
                    264:   9 "alternative"  "linoleum appliances"
                    265:  10 "no L I N"     "to be seen"
                    266: } {
                    267:   write_test 1.4.1.$tn docs_content { INSERT INTO docs VALUES($title,$body) }
                    268:   set R($tn) [list $title $body]
                    269: }
                    270: 
                    271: read_test  1.4.1.11 { 
                    272:   SELECT * FROM docs WHERE docs MATCH 'linux'
                    273: } [concat $R(2) $R(4) $R(5) $R(6) $R(7) $R(8)]
                    274: read_test  1.4.1.12 { 
                    275:   SELECT * FROM docs WHERE docs MATCH 'lin*'
                    276: } [concat $R(2) $R(3) $R(4) $R(5) $R(6) $R(7) $R(8) $R(9)]
                    277: read_test  1.4.1.13 { 
                    278:   SELECT * FROM docs WHERE docs MATCH 'title:linux problems'
                    279: } [concat $R(5)]
                    280: read_test  1.4.1.14 { 
                    281:   SELECT * FROM docs WHERE body MATCH 'title:linux driver'
                    282: } [concat $R(6)]
                    283: read_test  1.4.1.15 { 
                    284:   SELECT * FROM docs WHERE docs MATCH '"linux applications"'
                    285: } [concat $R(8)]
                    286: read_test  1.4.1.16 { 
                    287:   SELECT * FROM docs WHERE docs MATCH '"lin* app*"'
                    288: } [concat $R(8) $R(9)]
                    289: ddl_test   1.4.1.17 { DROP TABLE docs }
                    290: unset R
                    291: 
                    292: ddl_test   1.4.2.1 { CREATE VIRTUAL TABLE docs USING fts3() }
                    293: write_test 1.4.2.2 docs_content { 
                    294:   INSERT INTO docs VALUES(
                    295:   'SQLite is an ACID compliant embedded relational database management system')
                    296: }
                    297: foreach {tn query hit} {
                    298: 3 {SELECT * FROM docs WHERE docs MATCH 'sqlite NEAR database'} 1
                    299: 4 {SELECT * FROM docs WHERE docs MATCH 'database NEAR/6 sqlite'} 1
                    300: 5 {SELECT * FROM docs WHERE docs MATCH 'database NEAR/5 sqlite'} 0
                    301: 6 {SELECT * FROM docs WHERE docs MATCH 'database NEAR/2 "ACID compliant"'} 1
                    302: 7 {SELECT * FROM docs WHERE docs MATCH '"ACID compliant" NEAR/2 sqlite'} 1
                    303: 8 {SELECT * FROM docs WHERE docs MATCH 'sqlite NEAR/2 acid NEAR/2 relational'} 1
                    304: 9 {SELECT * FROM docs WHERE docs MATCH 'acid NEAR/2 sqlite NEAR/2 relational'} 0
                    305: } {
                    306:   set res [db eval {SELECT * FROM docs WHERE $hit}]
                    307:   read_test 1.4.2.$tn $query $res
                    308: }
                    309: ddl_test 1.4.2.10 { DROP TABLE docs }
                    310: 
                    311: ##########################################################################
                    312: # Test the example in section 3.1 (set operators with enhanced syntax).
                    313: #
                    314: set sqlite_fts3_enable_parentheses 1
                    315: ddl_test 1.5.1.1 { CREATE VIRTUAL TABLE docs USING fts3() }
                    316: foreach {tn docid content} {
                    317:   2 1 "a database is a software system"
                    318:   3 2 "sqlite is a software system"
                    319:   4 3 "sqlite is a database"
                    320: } {
                    321:   set R($docid) $content
                    322:   write_test 1.5.1.$tn docs_content { 
                    323:     INSERT INTO docs(docid, content) VALUES($docid, $content)
                    324:   }
                    325: }
                    326: read_test 1.5.1.4 {
                    327:   SELECT * FROM docs WHERE docs MATCH 'sqlite AND database'
                    328: } [list $R(3)]
                    329: read_test 1.5.1.5 {
                    330:   SELECT * FROM docs WHERE docs MATCH 'database sqlite'
                    331: } [list $R(3)]
                    332: read_test 1.5.1.6 {
                    333:   SELECT * FROM docs WHERE docs MATCH 'sqlite OR database'
                    334: } [list $R(1) $R(2) $R(3)]
                    335: read_test 1.5.1.7 {
                    336:   SELECT * FROM docs WHERE docs MATCH 'database NOT sqlite'
                    337: } [list $R(1)]
                    338: read_test 1.5.1.8 {
                    339:   SELECT * FROM docs WHERE docs MATCH 'database and sqlite'
                    340: } {}
                    341: 
                    342: write_test 1.5.2.1 docs_content {
                    343:   INSERT INTO docs 
                    344:     SELECT 'sqlite is also a library' UNION ALL
                    345:     SELECT 'library software'
                    346: }
                    347: read_test 1.5.2.2 {
                    348:   SELECT docid FROM docs WHERE docs MATCH 'sqlite AND database OR library'
                    349: } {3 4 5}
                    350: read_test 1.5.2.3 {
                    351:   SELECT docid FROM docs WHERE docs MATCH 'sqlite AND database'
                    352:     UNION
                    353:   SELECT docid FROM docs WHERE docs MATCH 'library'
                    354: } {3 4 5}
                    355: write_test 1.5.2.4 docs_content {
                    356:   INSERT INTO docs 
                    357:     SELECT 'the sqlite library runs on linux' UNION ALL
                    358:     SELECT 'as does the sqlite database (on linux)' UNION ALL
                    359:     SELECT 'the sqlite database is accessed by the sqlite library'
                    360: }
                    361: read_test 1.5.2.2 {
                    362:   SELECT docid FROM docs 
                    363:   WHERE docs MATCH '("sqlite database" OR "sqlite library") AND linux';
                    364: } {6 7}
                    365: read_test 1.5.2.3 {
                    366:   SELECT docid FROM docs WHERE docs MATCH 'linux'
                    367:     INTERSECT
                    368:   SELECT docid FROM (
                    369:     SELECT docid FROM docs WHERE docs MATCH '"sqlite library"'
                    370:       UNION
                    371:     SELECT docid FROM docs WHERE docs MATCH '"sqlite database"'
                    372:   );
                    373: } {6 7}
                    374: 
                    375: ##########################################################################
                    376: # Test the examples in section 3.2 (set operators with standard syntax).
                    377: # These tests reuse the table populated by the block above.
                    378: #
                    379: set sqlite_fts3_enable_parentheses 0
                    380: read_test 1.6.1.1 {
                    381:   SELECT * FROM docs WHERE docs MATCH 'sqlite -database'
                    382: } {{sqlite is a software system} {sqlite is also a library} {the sqlite library runs on linux}}
                    383: read_test 1.6.1.2 {
                    384:   SELECT * FROM docs WHERE docs MATCH 'sqlite OR database library'
                    385: } {{sqlite is also a library} {the sqlite library runs on linux} {the sqlite database is accessed by the sqlite library}}
                    386: 
                    387: set sqlite_fts3_enable_parentheses 1
                    388: read_test 1.6.1.3 {
                    389:   SELECT * FROM docs WHERE docs MATCH 'sqlite OR database library'
                    390: } {{sqlite is a software system} {sqlite is a database} {sqlite is also a library} {the sqlite library runs on linux} {as does the sqlite database (on linux)} {the sqlite database is accessed by the sqlite library}}
                    391: read_test 1.6.1.4 {
                    392:   SELECT * FROM docs WHERE docs MATCH '(sqlite OR database) library'
                    393: } {{sqlite is also a library} {the sqlite library runs on linux} {the sqlite database is accessed by the sqlite library}}
                    394: set sqlite_fts3_enable_parentheses 0
                    395: ddl_test  1.6.1.5 { DROP TABLE docs }
                    396: 
                    397: ##########################################################################
                    398: # Test the examples in section 4 (auxillary functions).
                    399: #
                    400: ddl_test   1.7.1.1 { CREATE VIRTUAL TABLE mail USING fts3(subject, body) }
                    401: 
                    402: write_test 1.7.1.2 mail_content { 
                    403:   INSERT INTO mail VALUES(
                    404:     'hello world', 'This message is a hello world message.');
                    405: }
                    406: write_test 1.7.1.3 mail_content { 
                    407:   INSERT INTO mail VALUES(
                    408:     'urgent: serious', 'This mail is seen as a more serious mail');
                    409: }
                    410: 
                    411: read_test  1.7.1.4 { 
                    412:   SELECT offsets(mail) FROM mail WHERE mail MATCH 'world';
                    413: } {{0 0 6 5 1 0 24 5}}
                    414: read_test  1.7.1.5 { 
                    415:   SELECT offsets(mail) FROM mail WHERE mail MATCH 'message'
                    416: } {{1 0 5 7 1 0 30 7}}
                    417: read_test  1.7.1.6 { 
                    418:   SELECT offsets(mail) FROM mail WHERE mail MATCH '"serious mail"'
                    419: } {{1 0 28 7 1 1 36 4}}
                    420: 
                    421: ddl_test   1.7.2.1 { CREATE VIRTUAL TABLE text USING fts3() }
                    422: 
                    423: write_test 1.7.2.2 text_content {
                    424:   INSERT INTO text VALUES('
                    425:     During 30 Nov-1 Dec, 2-3oC drops. Cool in the upper portion, minimum temperature 14-16oC and cool elsewhere, minimum temperature 17-20oC. Cold to very cold on mountaintops, minimum temperature 6-12oC. Northeasterly winds 15-30 km/hr. After that, temperature increases. Northeasterly winds 15-30 km/hr.
                    426:   ');
                    427: }
                    428: 
                    429: read_test  1.7.2.3 {
                    430:   SELECT snippet(text) FROM text WHERE text MATCH 'cold'
                    431: } {{<b>...</b>cool elsewhere, minimum temperature 17-20oC. <b>Cold</b> to very <b>cold</b> on mountaintops, minimum temperature 6<b>...</b>}}
                    432: 
                    433: read_test  1.7.2.4 {
                    434:   SELECT snippet(text, '[', ']', '...') FROM text WHERE text MATCH '"min* tem*"'
                    435: } {{...the upper portion, [minimum] [temperature] 14-16oC and cool elsewhere, [minimum] [temperature] 17-20oC. Cold...}}
                    436: 
                    437: ddl_test   1.7.3.1 { DROP TABLE IF EXISTS t1 }
                    438: ddl_test   1.7.3.2 { CREATE VIRTUAL TABLE t1 USING fts3(a, b) }
                    439: write_test 1.7.3.3 t1_content { 
                    440:   INSERT INTO t1 VALUES(
                    441:     'transaction default models default', 'Non transaction reads');
                    442: }
                    443: write_test 1.7.3.4 t1_content { 
                    444:   INSERT INTO t1 VALUES('the default transaction', 'these semantics present');
                    445: }
                    446: write_test 1.7.3.5 t1_content { 
                    447:   INSERT INTO t1 VALUES('single request', 'default data');
                    448: }
                    449: read_test  1.7.3.6 { 
                    450:   SELECT mit(matchinfo(t1)) FROM t1 
                    451:     WHERE t1 MATCH 'default transaction "these semantics"';
                    452: } {{3 2 1 3 2 0 1 1 1 2 2 0 1 1 0 0 0 1 1 1}}
                    453: 
                    454: ##########################################################################
                    455: # Test the example in section 5 (custom tokenizers).
                    456: #
                    457: ddl_test   1.8.1.1 { CREATE VIRTUAL TABLE simple USING fts3(tokenize=simple) } 
                    458: write_test 1.8.1.2 simple_content { 
                    459:   INSERT INTO simple VALUES('Right now they''re very frustrated')
                    460: }
                    461: read_test 1.8.1.3 {SELECT docid FROM simple WHERE simple MATCH 'Frustrated'} {1} 
                    462: read_test 1.8.1.4 {SELECT docid FROM simple WHERE simple MATCH 'Frustration'} {}
                    463: 
                    464: ddl_test   1.8.2.1 { CREATE VIRTUAL TABLE porter USING fts3(tokenize=porter) } 
                    465: write_test 1.8.2.2 porter_content { 
                    466:   INSERT INTO porter VALUES('Right now they''re very frustrated')
                    467: }
                    468: read_test 1.8.2.4 {
                    469:   SELECT docid FROM porter WHERE porter MATCH 'Frustration'
                    470: } {1}
                    471: 
                    472: }
                    473: # End of tests of example code in fts3.html
                    474: #-------------------------------------------------------------------------
                    475: 
                    476: #-------------------------------------------------------------------------
                    477: # Test that errors in the arguments passed to the snippet and offsets
                    478: # functions are handled correctly.
                    479: #
                    480: set DO_MALLOC_TEST 0
                    481: ddl_test   2.1.0 { DROP TABLE IF EXISTS t1 }
                    482: ddl_test   2.1.1 { CREATE VIRTUAL TABLE t1 USING fts3(a, b) }
                    483: write_test 2.1.2 t1_content { 
                    484:   INSERT INTO t1 VALUES('one two three', x'A1B2C3D4E5F6');
                    485: }
                    486: error_test 2.1.3 {
                    487:   SELECT offsets(a) FROM t1 WHERE a MATCH 'one'
                    488: } {illegal first argument to offsets}
                    489: error_test 2.1.4 {
                    490:   SELECT offsets(b) FROM t1 WHERE a MATCH 'one'
                    491: } {illegal first argument to offsets}
                    492: error_test 2.1.5 {
                    493:   SELECT optimize(a) FROM t1 LIMIT 1
                    494: } {illegal first argument to optimize}
                    495: error_test 2.1.6 {
                    496:   SELECT snippet(a) FROM t1 WHERE a MATCH 'one'
                    497: } {illegal first argument to snippet}
                    498: error_test 2.1.7 {
                    499:   SELECT snippet() FROM t1 WHERE a MATCH 'one'
                    500: } {unable to use function snippet in the requested context}
                    501: error_test 2.1.8 {
                    502:   SELECT snippet(a, b, 'A', 'B', 'C', 'D', 'E') FROM t1 WHERE a MATCH 'one'
                    503: } {wrong number of arguments to function snippet()}
                    504: #-------------------------------------------------------------------------
                    505: 
                    506: #-------------------------------------------------------------------------
                    507: # Test the effect of an OOM error while installing the FTS3 module (i.e.
                    508: # opening a database handle). This case was not tested by the OOM testing
                    509: # of the document examples above.
                    510: #
                    511: do_malloc_test e_fts3-3 -tclbody { 
                    512:   if {[catch {sqlite3 db test.db}]} { error "out of memory" }
                    513: }
                    514: #-------------------------------------------------------------------------
                    515: 
                    516: #-------------------------------------------------------------------------
                    517: # Verify the return values of the optimize() function. If no error occurs,
                    518: # the returned value should be "Index optimized" if the data structure
                    519: # was modified, or "Index already optimal" if it were not.
                    520: #
                    521: set DO_MALLOC_TEST 0
                    522: ddl_test   4.1 { CREATE VIRTUAL TABLE t4 USING fts3(a, b) }
                    523: write_test 4.2 t4_content {
                    524:   INSERT INTO t4 VALUES('In Xanadu', 'did Kubla Khan');
                    525: }
                    526: write_test 4.3 t4_content {
                    527:   INSERT INTO t4 VALUES('a stately pleasure', 'dome decree');
                    528: }
                    529: do_test e_fts3-4.4 {
                    530:   execsql { SELECT optimize(t4) FROM t4 LIMIT 1 } 
                    531: } {{Index optimized}}
                    532: do_test e_fts3-4.5 {
                    533:   execsql { SELECT optimize(t4) FROM t4 LIMIT 1 } 
                    534: } {{Index already optimal}}
                    535: #-------------------------------------------------------------------------
                    536: 
                    537: #-------------------------------------------------------------------------
                    538: # Test that the snippet function appears to work correctly with 1, 2, 3
                    539: # or 4 arguments passed to it.
                    540: #
                    541: set DO_MALLOC_TEST 0
                    542: ddl_test   5.1 { CREATE VIRTUAL TABLE t5 USING fts3(x) }
                    543: write_test 5.2 t5_content {
                    544:   INSERT INTO t5 VALUES('In Xanadu did Kubla Khan A stately pleasure-dome decree Where Alph, the sacred river, ran Through caverns measureless to man Down to a sunless sea.  So twice five miles of fertile ground With walls and towers were girdled round : And there were gardens bright with sinuous rills, Where blossomed many an incense-bearing tree ; And here were forests ancient as the hills, Enfolding sunny spots of greenery.');
                    545: }
                    546: read_test 5.3 { 
                    547:   SELECT snippet(t5) FROM t5 WHERE t5 MATCH 'miles'
                    548: } {{<b>...</b>to a sunless sea.  So twice five <b>miles</b> of fertile ground With walls and towers<b>...</b>}}
                    549: read_test 5.4 { 
                    550:   SELECT snippet(t5, '<i>') FROM t5 WHERE t5 MATCH 'miles'
                    551: } {{<b>...</b>to a sunless sea.  So twice five <i>miles</b> of fertile ground With walls and towers<b>...</b>}}
                    552: read_test 5.5 { 
                    553:   SELECT snippet(t5, '<i>', '</i>') FROM t5 WHERE t5 MATCH 'miles'
                    554: } {{<b>...</b>to a sunless sea.  So twice five <i>miles</i> of fertile ground With walls and towers<b>...</b>}}
                    555: read_test 5.6 { 
                    556:   SELECT snippet(t5, '<i>', '</i>', 'XXX') FROM t5 WHERE t5 MATCH 'miles'
                    557: } {{XXXto a sunless sea.  So twice five <i>miles</i> of fertile ground With walls and towersXXX}}
                    558: #-------------------------------------------------------------------------
                    559: 
                    560: #-------------------------------------------------------------------------
                    561: # Test that an empty MATCH expression returns an empty result set. As
                    562: # does passing a NULL value as a MATCH expression.
                    563: #
                    564: set DO_MALLOC_TEST 0
                    565: ddl_test   6.1 { CREATE VIRTUAL TABLE t6 USING fts3(x) }
                    566: write_test 6.2 t5_content { INSERT INTO t6 VALUES('a'); }
                    567: write_test 6.3 t5_content { INSERT INTO t6 VALUES('b'); }
                    568: write_test 6.4 t5_content { INSERT INTO t6 VALUES('c'); }
                    569: read_test  6.5 { SELECT * FROM t6 WHERE t6 MATCH '' } {}
                    570: read_test  6.6 { SELECT * FROM t6 WHERE x MATCH '' } {}
                    571: read_test  6.7 { SELECT * FROM t6 WHERE t6 MATCH NULL } {}
                    572: read_test  6.8 { SELECT * FROM t6 WHERE x MATCH NULL } {}
                    573: #-------------------------------------------------------------------------
                    574: 
                    575: #-------------------------------------------------------------------------
                    576: # Test a few facets of the FTS3 xFilter() callback implementation:
                    577: #
                    578: #   1. That the sqlite3_index_constraint.usable flag is respected.
                    579: #
                    580: #   2. That it is an error to use the "docid" or "rowid" column of
                    581: #      an FTS3 table as the LHS of a MATCH operator.
                    582: #
                    583: #   3. That it is an error to AND together two MATCH expressions in 
                    584: #      that refer to a single FTS3 table in a WHERE clause.
                    585: #
                    586: #
                    587: set DO_MALLOC_TEST 0
                    588: ddl_test   7.1.1 { CREATE VIRTUAL TABLE t7 USING fts3(a) }
                    589: ddl_test   7.1.2 { CREATE VIRTUAL TABLE t8 USING fts3(b) }
                    590: write_test 7.1.3 t7_content { INSERT INTO t7(docid, a) VALUES(4,'number four') }
                    591: write_test 7.1.4 t7_content { INSERT INTO t7(docid, a) VALUES(5,'number five') }
                    592: write_test 7.1.5 t8_content { INSERT INTO t8(docid, b) VALUES(4,'letter D') }
                    593: write_test 7.1.6 t8_content { INSERT INTO t8(docid, b) VALUES(5,'letter E') }
                    594: read_test  7.1.7 {
                    595:   SELECT a || ':' || b FROM t7 JOIN t8 USING(docid)
                    596: } {{number four:letter D} {number five:letter E}}
                    597: 
                    598: error_test 7.2.1 {
                    599:   SELECT * FROM t7 WHERE docid MATCH 'number'
                    600: } {unable to use function MATCH in the requested context}
                    601: error_test 7.2.2 {
                    602:   SELECT * FROM t7 WHERE rowid MATCH 'number'
                    603: } {unable to use function MATCH in the requested context}
                    604: 
                    605: error_test 7.3.1 {
                    606:   SELECT * FROM t7 WHERE a MATCH 'number' AND a MATCH 'four'
                    607: } {unable to use function MATCH in the requested context}
                    608: error_test 7.3.2 {
                    609:   SELECT * FROM t7, t8 WHERE a MATCH 'number' AND a MATCH 'four'
                    610: } {unable to use function MATCH in the requested context}
                    611: error_test 7.3.3 {
                    612:   SELECT * FROM t7, t8 WHERE b MATCH 'letter' AND b MATCH 'd'
                    613: } {unable to use function MATCH in the requested context}
                    614: read_test 7.3.4 {
                    615:   SELECT * FROM t7, t8 WHERE a MATCH 'number' AND b MATCH 'letter'
                    616: } {{number four} {letter D} {number four} {letter E} {number five} {letter D} {number five} {letter E}}
                    617: read_test 7.3.5 {
                    618:   SELECT * FROM t7 WHERE a MATCH 'number' AND docid = 4
                    619: } {{number four}}
                    620: 
                    621: #-------------------------------------------------------------------------
                    622: # Test the quoting of FTS3 table column names. Names may be quoted using
                    623: # any of "", '', ``` or [].
                    624: #
                    625: set DO_MALLOC_TEST 0
                    626: ddl_test  8.1.1 { CREATE VIRTUAL TABLE t9a USING fts3("c1", [c2]) }
                    627: ddl_test  8.1.2 { CREATE VIRTUAL TABLE t9b USING fts3('c1', `c2`) }
                    628: read_test 8.1.3 { PRAGMA table_info(t9a) } {0 c1 {} 0 {} 0 1 c2 {} 0 {} 0}
                    629: read_test 8.1.4 { PRAGMA table_info(t9b) } {0 c1 {} 0 {} 0 1 c2 {} 0 {} 0}
                    630: ddl_test  8.2.1 { CREATE VIRTUAL TABLE t9c USING fts3("c""1", 'c''2') }
                    631: read_test 8.2.2 { PRAGMA table_info(t9c) } {0 c\"1 {} 0 {} 0 1 c'2 {} 0 {} 0}
                    632: #-------------------------------------------------------------------------
                    633: 
                    634: #-------------------------------------------------------------------------
                    635: # Test that FTS3 tables can be renamed using the ALTER RENAME command.
                    636: # OOM errors are tested during ALTER RENAME commands also.
                    637: #
                    638: foreach DO_MALLOC_TEST {0 1 2} {
                    639:   db close
                    640:   forcedelete test.db test.db-journal
                    641:   sqlite3 db test.db
                    642:   if {$DO_MALLOC_TEST} { sqlite3_db_config_lookaside db 0 0 0 }
                    643: 
                    644:   ddl_test   9.1.1             { CREATE VIRTUAL TABLE t10 USING fts3(x) }
                    645:   write_test 9.1.2 t10_content { INSERT INTO t10 VALUES('fts3 tables') }
                    646:   write_test 9.1.3 t10_content { INSERT INTO t10 VALUES('are renameable') }
                    647: 
                    648:   read_test  9.1.4 {
                    649:     SELECT * FROM t10 WHERE t10 MATCH 'table*'
                    650:   } {{fts3 tables}}
                    651:   read_test  9.1.5 {
                    652:     SELECT * FROM t10 WHERE x MATCH 'rename*'
                    653:   } {{are renameable}}
                    654: 
                    655:   ddl_test   9.1.6             { ALTER TABLE t10 RENAME TO t11 }
                    656: 
                    657:   read_test  9.1.7 {
                    658:     SELECT * FROM t11 WHERE t11 MATCH 'table*'
                    659:   } {{fts3 tables}}
                    660:   read_test  9.1.8 {
                    661:     SELECT * FROM t11 WHERE x MATCH 'rename*'
                    662:   } {{are renameable}}
                    663: }
                    664: #-------------------------------------------------------------------------
                    665: 
                    666: #-------------------------------------------------------------------------
                    667: # Test a couple of cases involving corrupt data structures:
                    668: #
                    669: #   1) A case where a document referenced by the full-text index is
                    670: #      not present in the %_content table.
                    671: #
                    672: #   2) A badly formatted b-tree segment node.
                    673: #
                    674: set DO_MALLOC_TEST 0
                    675: ddl_test   10.1.1 { CREATE VIRTUAL TABLE ta USING fts3 }
                    676: write_test 10.1.2 ta_content { 
                    677:   INSERT INTO ta VALUES('During a summer vacation in 1790') }
                    678: write_test 10.1.3 ta_content {
                    679:   INSERT INTO ta VALUES('Wordsworth went on a walking tour') }
                    680: write_test 10.1.4 ta_content { DELETE FROM ta_content WHERE rowid = 2 }
                    681: read_test  10.1.5 {
                    682:   SELECT * FROM ta WHERE ta MATCH 'summer'
                    683: } {{During a summer vacation in 1790}}
                    684: error_test 10.1.6 {
                    685:   SELECT * FROM ta WHERE ta MATCH 'walking'
                    686: } {database disk image is malformed}
                    687: 
                    688: write_test 10.2.1 ta_content { DELETE FROM ta }
                    689: write_test 10.2.2 ta_content { 
                    690:   INSERT INTO ta VALUES('debate demonstrated the rising difficulty') }
                    691: write_test 10.2.3 ta_content { 
                    692:   INSERT INTO ta VALUES('Google released its browser beta') }
                    693: 
                    694: set blob [db one {SELECT root FROM ta_segdir WHERE rowid = 2}]
                    695: binary scan $blob "a6 a3 a*" start middle end
                    696: set middle "\x0E\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x06\x06"
                    697: set blob [binary format "a6 a* a*" $start $middle $end]
                    698: write_test 10.2.4 ta_segdir { 
                    699:   UPDATE ta_segdir SET root = $blob WHERE rowid = 2
                    700: }
                    701: error_test 10.2.5 {
                    702:   SELECT * FROM ta WHERE ta MATCH 'beta'
                    703: } {database disk image is malformed}
                    704: 
                    705: 
                    706: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>