summaryrefslogtreecommitdiffstats
path: root/test/windowfault.test
diff options
context:
space:
mode:
Diffstat (limited to 'test/windowfault.test')
-rw-r--r--test/windowfault.test334
1 files changed, 334 insertions, 0 deletions
diff --git a/test/windowfault.test b/test/windowfault.test
new file mode 100644
index 0000000..5340ce0
--- /dev/null
+++ b/test/windowfault.test
@@ -0,0 +1,334 @@
+# 2018 May 8
+#
+# 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 implements regression tests for SQLite library.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix windowfault
+
+ifcapable !windowfunc {
+ finish_test
+ return
+}
+
+do_execsql_test 1.0 {
+ CREATE TABLE t1(a, b, c, d);
+ INSERT INTO t1 VALUES(1, 2, 3, 4);
+ INSERT INTO t1 VALUES(5, 6, 7, 8);
+ INSERT INTO t1 VALUES(9, 10, 11, 12);
+}
+faultsim_save_and_close
+
+do_faultsim_test 1 -start 1 -faults oom-t* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT row_number() OVER win,
+ rank() OVER win,
+ dense_rank() OVER win,
+ ntile(2) OVER win,
+ first_value(d) OVER win,
+ last_value(d) OVER win,
+ nth_value(d,2) OVER win,
+ lead(d) OVER win,
+ lag(d) OVER win,
+ max(d) OVER win,
+ min(d) OVER win
+ FROM t1
+ WINDOW win AS (ORDER BY a)
+ }
+} -test {
+ faultsim_test_result {0 {1 1 1 1 4 4 {} 8 {} 4 4 2 2 2 1 4 8 8 12 4 8 4 3 3 3 2 4 12 8 {} 8 12 4}}
+}
+
+do_faultsim_test 1.1 -faults oom-t* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT row_number() OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t1
+ WINDOW win AS (PARTITION BY c<7 ORDER BY a)
+ }
+} -test {
+ faultsim_test_result {0 {1 1 1 2 2 2 1 1 1}}
+}
+
+do_faultsim_test 1.2 -faults oom-t* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT ntile(105)
+ OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
+ FROM t1
+ }
+} -test {
+ faultsim_test_result {0 {1 2 3}}
+}
+
+do_faultsim_test 2 -start 1 -faults oom-* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT round(percent_rank() OVER win, 2),
+ round(cume_dist() OVER win, 2)
+ FROM t1
+ WINDOW win AS (ORDER BY a)
+ }
+} -test {
+ faultsim_test_result {0 {0.0 0.33 0.5 0.67 1.0 1.0}}
+}
+
+do_faultsim_test 3 -faults oom-* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT min(d) OVER win, max(d) OVER win
+ FROM t1
+ WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
+ }
+} -test {
+ faultsim_test_result {0 {4 12 8 12 12 12}}
+}
+
+do_faultsim_test 4 -faults oom-* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ CREATE VIEW aaa AS
+ SELECT min(d) OVER w, max(d) OVER w
+ FROM t1
+ WINDOW w AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING);
+ SELECT * FROM aaa;
+ }
+} -test {
+ faultsim_test_result {0 {4 12 8 12 12 12}}
+}
+
+do_faultsim_test 5 -start 1 -faults oom-* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT last_value(a) OVER win1,
+ last_value(a) OVER win2
+ FROM t1
+ WINDOW win1 AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),
+ win2 AS (ORDER BY a)
+ }
+} -test {
+ faultsim_test_result {0 {5 1 9 5 9 9}}
+}
+
+do_faultsim_test 6 -faults oom-* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT percent_rank() OVER (), cume_dist() OVER () FROM t1
+ }
+} -test {
+ faultsim_test_result {0 {0.0 1.0 0.0 1.0 0.0 1.0}}
+}
+
+do_faultsim_test 7 -faults oom-* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT percent_rank() OVER (), cume_dist() OVER () FROM t1
+ }
+} -test {
+ faultsim_test_result {0 {0.0 1.0 0.0 1.0 0.0 1.0}}
+}
+
+do_faultsim_test 8 -faults oom-t* -prep {
+ faultsim_restore_and_reopen
+} -body {
+ execsql {
+ SELECT a, sum(b) OVER win1 FROM t1
+ WINDOW win1 AS (PARTITION BY a ),
+ win2 AS (PARTITION BY b )
+ ORDER BY a;
+ }
+} -test {
+ faultsim_test_result {0 {1 2 5 6 9 10}}
+}
+
+#-------------------------------------------------------------------------
+# The following test causes a cursor in REQURESEEK state to be passed
+# to sqlite3BtreeDelete(). An error is simulated within the seek operation
+# to restore the cursors position.
+#
+reset_db
+set big [string repeat x 900]
+do_execsql_test 9.0 {
+ PRAGMA page_size = 512;
+ PRAGMA cache_size = 2;
+ CREATE TABLE t(x INTEGER PRIMARY KEY, y TEXT);
+ WITH s(i) AS (
+ VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1900
+ )
+ INSERT INTO t(y) SELECT $big FROM s;
+}
+db close
+
+testvfs tvfs -default 1
+tvfs script vfs_callback
+tvfs filter xRead
+
+sqlite3 db test.db
+proc vfs_callback {method file args} {
+ if {$file=="" && [info exists ::tmp_read_fail]} {
+ incr ::tmp_read_fail -1
+ if {$::tmp_read_fail<=0} {
+ return "SQLITE_IOERR"
+ }
+ }
+ return "SQLITE_OK"
+}
+
+set FAULTSIM(tmpread) [list \
+ -injectstart tmpread_injectstart \
+ -injectstop tmpread_injectstop \
+ -injecterrlist {{1 {disk I/O error}}} \
+]
+proc tmpread_injectstart {iFail} {
+ set ::tmp_read_fail $iFail
+}
+proc tmpread_injectstop {} {
+ set ret [expr $::tmp_read_fail<=0]
+ unset -nocomplain ::tmp_read_fail
+ return $ret
+}
+
+set L [db eval {SELECT 0.0 FROM t}]
+do_faultsim_test 9 -end 25 -faults tmpread -body {
+ execsql {
+ SELECT sum(y) OVER win FROM t
+ WINDOW win AS (
+ ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND 1800 FOLLOWING
+ )
+ }
+} -test {
+ faultsim_test_result [list 0 $::L]
+}
+
+catch {db close}
+tvfs delete
+
+reset_db
+do_execsql_test 10.0 {
+ CREATE TABLE t1(a, b, c, d);
+ CREATE TABLE t2(a, b, c, d);
+}
+
+do_faultsim_test 10 -faults oom* -prep {
+} -body {
+ execsql {
+ SELECT row_number() OVER win
+ FROM t1
+ WINDOW win AS (
+ ORDER BY (
+ SELECT percent_rank() OVER win2 FROM t2
+ WINDOW win2 AS (ORDER BY a)
+ )
+ )
+ }
+} -test {
+ faultsim_test_result {0 {}}
+}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 11.0 {
+ DROP TABLE IF EXISTS t0;
+ CREATE TABLE t0(c0 INTEGER UNIQUE);
+ INSERT INTO t0 VALUES(0);
+} {}
+
+do_faultsim_test 11.1 -faults oom* -prep {
+} -body {
+ execsql {
+ SELECT * FROM t0 WHERE
+ (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0);
+ }
+} -test {
+ faultsim_test_result {0 {}}
+}
+
+do_faultsim_test 11.2 -faults oom* -prep {
+} -body {
+ execsql {
+ VALUES(false),(current_date collate binary)
+ intersect
+ values(count() not like group_concat(cast(cast(0e00 as text) as integer) <= NULL || 0.4e-0 || 0x8 & true ) over () collate rtrim);
+ }
+} -test {
+ faultsim_test_result {0 {}}
+}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 12.0 {
+ CREATE TABLE t1(a, b, c);
+} {}
+do_faultsim_test 12 -faults oom* -prep {
+} -body {
+ execsql {
+ WITH v(a, b, row_number) AS (
+ SELECT a, b, row_number() OVER (PARTITION BY a COLLATE nocase ORDER BY b) FROM t1
+ )
+ SELECT * FROM v WHERE a=2
+ }
+} -test {
+ faultsim_test_result {0 {}}
+}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 13.0 {
+ CREATE TABLE t1(id INTEGER PRIMARY KEY, a, b);
+ INSERT INTO t1 VALUES(1, '1', 'a');
+ INSERT INTO t1 VALUES(2, '22', 'b');
+ INSERT INTO t1 VALUES(3, '333', 'c');
+ INSERT INTO t1 VALUES(4, '4444', 'dddd');
+ INSERT INTO t1 VALUES(5, '55555', 'e');
+ INSERT INTO t1 VALUES(6, '666666', 'f');
+ INSERT INTO t1 VALUES(7, '7777777', 'gggggggggg');
+} {}
+
+set queryres [list {*}{
+ 1b22
+ 1b22c333
+ 22c333dddd4444
+ 333dddd4444e55555
+ 4444e55555f666666
+ 55555f666666gggggggggg7777777
+ 666666gggggggggg7777777
+}]
+do_execsql_test 13.1 {
+ SELECT group_concat(a, b) OVER (
+ ORDER BY id RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1
+} $queryres
+
+do_faultsim_test 13 -faults oom* -prep {
+} -body {
+ execsql {
+ SELECT group_concat(a, b) OVER (
+ ORDER BY id RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1
+ }
+} -test {
+ faultsim_test_result [list 0 $::queryres]
+}
+
+finish_test