Annotation of embedaddon/sqlite3/test/e_fts3.test, revision 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>