45bcd6c274
FossilOrigin-Name: eee921a99e69a9cd868a89de620bf47c4e26e4b5
203 lines
7.7 KiB
Plaintext
203 lines
7.7 KiB
Plaintext
# 2009 December 03
|
|
#
|
|
# 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.
|
|
#
|
|
#***********************************************************************
|
|
#
|
|
# The tests in this file are structural coverage tests. They are designed
|
|
# to complement the tests in fts3rnd.test and fts3doc.test. Between them,
|
|
# the three files should provide full coverage of the fts3 extension code.
|
|
#
|
|
|
|
set testdir [file dirname $argv0]
|
|
source $testdir/tester.tcl
|
|
|
|
# If this build does not include FTS3, skip the tests in this file.
|
|
#
|
|
ifcapable !fts3 { finish_test ; return }
|
|
source $testdir/fts3_common.tcl
|
|
|
|
set DO_MALLOC_TEST 0
|
|
|
|
#--------------------------------------------------------------------------
|
|
# When it first needs to read a block from the %_segments table, the FTS3
|
|
# module compiles an SQL statement for that purpose. The statement is
|
|
# stored and reused each subsequent time a block is read. This test case
|
|
# tests the effects of an OOM error occuring while compiling the statement.
|
|
#
|
|
# Similarly, when FTS3 first needs to scan through a set of segment leaves
|
|
# to find a set of documents that matches a term, it allocates a string
|
|
# containing the text of the required SQL, and compiles one or more
|
|
# statements to traverse the leaves. This test case tests that OOM errors
|
|
# that occur while allocating this string and statement are handled correctly
|
|
# also.
|
|
#
|
|
do_test fts3cov-1.1 {
|
|
execsql {
|
|
CREATE VIRTUAL TABLE t1 USING fts3(x);
|
|
INSERT INTO t1(t1) VALUES('nodesize=24');
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES('Is the night chilly and dark?');
|
|
INSERT INTO t1 VALUES('The night is chilly, but not dark.');
|
|
INSERT INTO t1 VALUES('The thin gray cloud is spread on high,');
|
|
INSERT INTO t1 VALUES('It covers but not hides the sky.');
|
|
COMMIT;
|
|
SELECT count(*)>0 FROM t1_segments;
|
|
}
|
|
} {1}
|
|
|
|
set DO_MALLOC_TEST 1
|
|
do_restart_select_test fts3cov-1.2 {
|
|
SELECT docid FROM t1 WHERE t1 MATCH 'chilly';
|
|
} {1 2}
|
|
set DO_MALLOC_TEST 0
|
|
|
|
#--------------------------------------------------------------------------
|
|
# When querying the full-text index, if an expected internal node block is
|
|
# missing from the %_segments table, or if a NULL value is stored in the
|
|
# %_segments table instead of a binary blob, database corruption should be
|
|
# reported.
|
|
#
|
|
# Even with tiny 24 byte nodes, it takes a fair bit of data to produce a
|
|
# segment b-tree that uses the %_segments table to store internal nodes.
|
|
#
|
|
do_test fts3cov-2.1 {
|
|
execsql {
|
|
INSERT INTO t1(t1) VALUES('nodesize=24');
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES('The moon is behind, and at the full;');
|
|
INSERT INTO t1 VALUES('And yet she looks both small and dull.');
|
|
INSERT INTO t1 VALUES('The night is chill, the cloud is gray:');
|
|
INSERT INTO t1 VALUES('''T is a month before the month of May,');
|
|
INSERT INTO t1 VALUES('And the Spring comes slowly up this way.');
|
|
INSERT INTO t1 VALUES('The lovely lady, Christabel,');
|
|
INSERT INTO t1 VALUES('Whom her father loves so well,');
|
|
INSERT INTO t1 VALUES('What makes her in the wood so late,');
|
|
INSERT INTO t1 VALUES('A furlong from the castle gate?');
|
|
INSERT INTO t1 VALUES('She had dreams all yesternight');
|
|
INSERT INTO t1 VALUES('Of her own betrothed knight;');
|
|
INSERT INTO t1 VALUES('And she in the midnight wood will pray');
|
|
INSERT INTO t1 VALUES('For the weal of her lover that''s far away.');
|
|
COMMIT;
|
|
|
|
INSERT INTO t1(t1) VALUES('optimize');
|
|
SELECT substr(hex(root), 1, 2) FROM t1_segdir;
|
|
}
|
|
} {03}
|
|
|
|
# Test the "missing entry" case:
|
|
do_test fts3cov-2.1 {
|
|
set root [db one {SELECT root FROM t1_segdir}]
|
|
read_fts3varint [string range $root 1 end] left_child
|
|
execsql { DELETE FROM t1_segments WHERE blockid = $left_child }
|
|
} {}
|
|
do_error_test fts3cov-2.2 {
|
|
SELECT * FROM t1 WHERE t1 MATCH 'c*'
|
|
} {database disk image is malformed}
|
|
|
|
# Test the "replaced with NULL" case:
|
|
do_test fts3cov-2.3 {
|
|
execsql { INSERT INTO t1_segments VALUES($left_child, NULL) }
|
|
} {}
|
|
do_error_test fts3cov-2.4 {
|
|
SELECT * FROM t1 WHERE t1 MATCH 'cloud'
|
|
} {database disk image is malformed}
|
|
|
|
#--------------------------------------------------------------------------
|
|
# The following tests are to test the effects of OOM errors while storing
|
|
# terms in the pending-hash table. Specifically, while creating doclist
|
|
# blobs to store in the table. More specifically, to test OOM errors while
|
|
# appending column numbers to doclists. For example, if a doclist consists
|
|
# of:
|
|
#
|
|
# <docid> <column 0 offset-list> 0x01 <column N> <column N offset-list>
|
|
#
|
|
# The following tests check that malloc errors encountered while appending
|
|
# the "0x01 <column N>" data to the dynamically growable blob used to
|
|
# accumulate the doclist in memory are handled correctly.
|
|
#
|
|
do_test fts3cov-3.1 {
|
|
set cols [list]
|
|
set vals [list]
|
|
for {set i 0} {$i < 120} {incr i} {
|
|
lappend cols "col$i"
|
|
lappend vals "'word'"
|
|
}
|
|
execsql "CREATE VIRTUAL TABLE t2 USING fts3([join $cols ,])"
|
|
} {}
|
|
set DO_MALLOC_TEST 1
|
|
do_write_test fts3cov-3.2 t2_content "
|
|
INSERT INTO t2(docid, [join $cols ,]) VALUES(1, [join $vals ,])
|
|
"
|
|
do_write_test fts3cov-3.3 t2_content "
|
|
INSERT INTO t2(docid, [join $cols ,]) VALUES(200, [join $vals ,])
|
|
"
|
|
do_write_test fts3cov-3.4 t2_content "
|
|
INSERT INTO t2(docid, [join $cols ,]) VALUES(60000, [join $vals ,])
|
|
"
|
|
|
|
#-------------------------------------------------------------------------
|
|
# If too much data accumulates in the pending-terms hash table, it is
|
|
# flushed to the database automatically, even if the transaction has not
|
|
# finished. The following tests check the effects of encountering an OOM
|
|
# while doing this.
|
|
#
|
|
do_test fts3cov-4.1 {
|
|
execsql {
|
|
CREATE VIRTUAL TABLE t3 USING fts3(x);
|
|
INSERT INTO t3(t3) VALUES('nodesize=24');
|
|
INSERT INTO t3(t3) VALUES('maxpending=100');
|
|
}
|
|
} {}
|
|
set DO_MALLOC_TEST 1
|
|
do_write_test fts3cov-4.2 t3_content {
|
|
INSERT INTO t3(docid, x)
|
|
SELECT 1, 'Then Christabel stretched forth her hand,' UNION ALL
|
|
SELECT 3, 'And comforted fair Geraldine:' UNION ALL
|
|
SELECT 4, '''O well, bright dame, may you command' UNION ALL
|
|
SELECT 5, 'The service of Sir Leoline;' UNION ALL
|
|
SELECT 2, 'And gladly our stout chivalry' UNION ALL
|
|
SELECT 7, 'Will he send forth, and friends withal,' UNION ALL
|
|
SELECT 8, 'To guide and guard you safe and free' UNION ALL
|
|
SELECT 6, 'Home to your noble father''s hall.'''
|
|
}
|
|
|
|
#-------------------------------------------------------------------------
|
|
# When building the internal tree structure for each segment b-tree, FTS3
|
|
# assumes that the content of each internal node will be less than
|
|
# $nodesize bytes, where $nodesize is the advisory node size. If this turns
|
|
# out to be untrue, then an extra buffer must be malloc'd for each term.
|
|
# This test case tests these paths and the effects of said mallocs failing
|
|
# by inserting insert a document with some fairly large terms into a
|
|
# full-text table with a very small node-size.
|
|
#
|
|
do_test fts3cov-5.1 {
|
|
execsql {
|
|
CREATE VIRTUAL TABLE t4 USING fts3(x);
|
|
INSERT INTO t4(t4) VALUES('nodesize=24');
|
|
}
|
|
} {}
|
|
set DO_MALLOC_TEST 1
|
|
do_write_test fts3cov-5.2 t4_content {
|
|
INSERT INTO t4
|
|
SELECT 'ItisanancientMarinerAndhestoppethoneofthreeAA' UNION ALL
|
|
SELECT 'ItisanancientMarinerAndhestoppethoneofthreeBB' UNION ALL
|
|
SELECT 'ItisanancientMarinerAndhestoppethoneofthreeCC' UNION ALL
|
|
SELECT 'BythylonggreybeardandglitteringeyeNowwhereforestoppstAA' UNION ALL
|
|
SELECT 'BythylonggreybeardandglitteringeyeNowwhereforestoppstBB' UNION ALL
|
|
SELECT 'BythylonggreybeardandglitteringeyeNowwhereforestoppstCC'
|
|
}
|
|
do_test fts3cov-5.3 {
|
|
execsql { INSERT INTO t4 VALUES('extra!') }
|
|
} {}
|
|
do_write_test fts3cov-5.2 t4_segments {
|
|
INSERT INTO t4(t4) VALUES('optimize')
|
|
}
|
|
|
|
|
|
|
|
finish_test
|
|
|