# 2014 June 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # # This file is focused on OOM errors. # source [file join [file dirname [info script]] fts5_common.tcl] source $testdir/malloc_common.tcl set testprefix fts5fault2 # If SQLITE_ENABLE_FTS5 is not defined, omit this file. ifcapable !fts5 { finish_test return } set doc [string trim [string repeat "x y z " 200]] do_execsql_test 1.0 { CREATE TABLE t1(a INTEGER PRIMARY KEY, x); CREATE VIRTUAL TABLE x1 USING fts5(x, content='t1', content_rowid='a'); INSERT INTO x1(x1, rank) VALUES('pgsz', 32); WITH input(a,b) AS ( SELECT 1, $doc UNION ALL SELECT a+1, ($doc || CASE WHEN (a+1)%100 THEN '' ELSE ' xyz' END) FROM input WHERE a < 1000 ) INSERT INTO t1 SELECT * FROM input; INSERT INTO x1(x1) VALUES('rebuild'); } do_faultsim_test 1.1 -faults oom-* -prep { } -body { execsql { SELECT rowid FROM x1 WHERE x1 MATCH 'z AND xyz' } } -test { faultsim_test_result {0 {100 200 300 400 500 600 700 800 900 1000}} } do_faultsim_test 1.2 -faults oom-* -prep { } -body { execsql { SELECT rowid FROM x1 WHERE x1 MATCH 'z + xyz' ORDER BY 1 DESC} } -test { faultsim_test_result {0 {1000 900 800 700 600 500 400 300 200 100}} } #------------------------------------------------------------------------- # OOM within a query that accesses the in-memory hash table. # reset_db do_execsql_test 2.0 { CREATE VIRTUAL TABLE "a b c" USING fts5(a, b, c); INSERT INTO "a b c" VALUES('one two', 'x x x', 'three four'); INSERT INTO "a b c" VALUES('nine ten', 'y y y', 'two two'); } do_faultsim_test 2.1 -faults oom-trans* -prep { execsql { BEGIN; INSERT INTO "a b c" VALUES('one one', 'z z z', 'nine ten'); } } -body { execsql { SELECT rowid FROM "a b c" WHERE "a b c" MATCH 'one' } } -test { faultsim_test_result {0 {1 3}} catchsql { ROLLBACK } } #------------------------------------------------------------------------- # OOM within an 'optimize' operation that writes multiple pages to disk. # reset_db do_execsql_test 3.0 { CREATE VIRTUAL TABLE zzz USING fts5(z); INSERT INTO zzz(zzz, rank) VALUES('pgsz', 32); INSERT INTO zzz VALUES('a b c d'); INSERT INTO zzz SELECT 'c d e f' FROM zzz; INSERT INTO zzz SELECT 'e f g h' FROM zzz; INSERT INTO zzz SELECT 'i j k l' FROM zzz; INSERT INTO zzz SELECT 'l k m n' FROM zzz; INSERT INTO zzz SELECT 'o p q r' FROM zzz; } faultsim_save_and_close do_faultsim_test 3.1 -faults oom-trans* -prep { faultsim_restore_and_reopen execsql { SELECT rowid FROM zzz } } -body { execsql { INSERT INTO zzz(zzz) VALUES('optimize') } } -test { faultsim_test_result {0 {}} } #------------------------------------------------------------------------- # OOM within an 'integrity-check' operation. # reset_db db func rnddoc fts5_rnddoc do_execsql_test 4.0 { CREATE VIRTUAL TABLE zzz USING fts5(z); INSERT INTO zzz(zzz, rank) VALUES('pgsz', 32); WITH ii(i) AS (SELECT 1 UNION SELECT i+1 FROM ii WHERE i<10) INSERT INTO zzz SELECT rnddoc(10) || ' xccc' FROM ii; } do_faultsim_test 4.1 -faults oom-trans* -prep { } -body { execsql { INSERT INTO zzz(zzz) VALUES('integrity-check') } } -test { faultsim_test_result {0 {}} } #------------------------------------------------------------------------- # OOM while parsing a tokenize=option # reset_db faultsim_save_and_close do_faultsim_test 5.0 -faults oom-* -prep { faultsim_restore_and_reopen } -body { execsql { CREATE VIRTUAL TABLE uio USING fts5(a, b, tokenize="porter 'ascii'", content="another table", content_rowid="somecolumn" ); } } -test { faultsim_test_result {0 {}} } finish_test