16fde1799Sdan# 2018 May 8 26fde1799Sdan# 36fde1799Sdan# The author disclaims copyright to this source code. In place of 46fde1799Sdan# a legal notice, here is a blessing: 56fde1799Sdan# 66fde1799Sdan# May you do good and not evil. 76fde1799Sdan# May you find forgiveness for yourself and forgive others. 86fde1799Sdan# May you share freely, never taking more than you give. 96fde1799Sdan# 106fde1799Sdan#*********************************************************************** 116fde1799Sdan# This file implements regression tests for SQLite library. 126fde1799Sdan# 136fde1799Sdan 146fde1799Sdanset testdir [file dirname $argv0] 156fde1799Sdansource $testdir/tester.tcl 166fde1799Sdanset testprefix windowfault 176fde1799Sdan 1867a9b8edSdanifcapable !windowfunc { 1967a9b8edSdan finish_test 2067a9b8edSdan return 2167a9b8edSdan} 226fde1799Sdan 236fde1799Sdando_execsql_test 1.0 { 246fde1799Sdan CREATE TABLE t1(a, b, c, d); 256fde1799Sdan INSERT INTO t1 VALUES(1, 2, 3, 4); 266fde1799Sdan INSERT INTO t1 VALUES(5, 6, 7, 8); 276fde1799Sdan INSERT INTO t1 VALUES(9, 10, 11, 12); 286fde1799Sdan} 296fde1799Sdanfaultsim_save_and_close 306fde1799Sdan 31108e6b2cSdando_faultsim_test 1 -start 1 -faults oom-t* -prep { 326fde1799Sdan faultsim_restore_and_reopen 336fde1799Sdan} -body { 346fde1799Sdan execsql { 356fde1799Sdan SELECT row_number() OVER win, 366fde1799Sdan rank() OVER win, 376fde1799Sdan dense_rank() OVER win, 386fde1799Sdan ntile(2) OVER win, 396fde1799Sdan first_value(d) OVER win, 406fde1799Sdan last_value(d) OVER win, 416fde1799Sdan nth_value(d,2) OVER win, 426fde1799Sdan lead(d) OVER win, 436fde1799Sdan lag(d) OVER win, 446fde1799Sdan max(d) OVER win, 456fde1799Sdan min(d) OVER win 466fde1799Sdan FROM t1 476fde1799Sdan WINDOW win AS (ORDER BY a) 486fde1799Sdan } 496fde1799Sdan} -test { 506fde1799Sdan 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}} 516fde1799Sdan} 526fde1799Sdan 539c27758eSdando_faultsim_test 1.1 -faults oom-t* -prep { 549c27758eSdan faultsim_restore_and_reopen 559c27758eSdan} -body { 569c27758eSdan execsql { 579c27758eSdan SELECT row_number() OVER win, 589c27758eSdan rank() OVER win, 599c27758eSdan dense_rank() OVER win 609c27758eSdan FROM t1 619c27758eSdan WINDOW win AS (PARTITION BY c<7 ORDER BY a) 629c27758eSdan } 639c27758eSdan} -test { 649c27758eSdan faultsim_test_result {0 {1 1 1 2 2 2 1 1 1}} 659c27758eSdan} 669c27758eSdan 6717074e3aSdando_faultsim_test 1.2 -faults oom-t* -prep { 6817074e3aSdan faultsim_restore_and_reopen 6917074e3aSdan} -body { 7017074e3aSdan execsql { 7117074e3aSdan SELECT ntile(105) 7217074e3aSdan OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) 7317074e3aSdan FROM t1 7417074e3aSdan } 7517074e3aSdan} -test { 7617074e3aSdan faultsim_test_result {0 {1 2 3}} 7717074e3aSdan} 7817074e3aSdan 799c27758eSdando_faultsim_test 2 -start 1 -faults oom-* -prep { 809c27758eSdan faultsim_restore_and_reopen 819c27758eSdan} -body { 829c27758eSdan execsql { 839c27758eSdan SELECT round(percent_rank() OVER win, 2), 849c27758eSdan round(cume_dist() OVER win, 2) 859c27758eSdan FROM t1 869c27758eSdan WINDOW win AS (ORDER BY a) 879c27758eSdan } 889c27758eSdan} -test { 899c27758eSdan faultsim_test_result {0 {0.0 0.33 0.5 0.67 1.0 1.0}} 909c27758eSdan} 919c27758eSdan 929c27758eSdando_faultsim_test 3 -faults oom-* -prep { 9313b08bb6Sdan faultsim_restore_and_reopen 9413b08bb6Sdan} -body { 9513b08bb6Sdan execsql { 9613b08bb6Sdan SELECT min(d) OVER win, max(d) OVER win 9713b08bb6Sdan FROM t1 9813b08bb6Sdan WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) 9913b08bb6Sdan } 10013b08bb6Sdan} -test { 10113b08bb6Sdan faultsim_test_result {0 {4 12 8 12 12 12}} 10213b08bb6Sdan} 10313b08bb6Sdan 1049c27758eSdando_faultsim_test 4 -faults oom-* -prep { 1059c27758eSdan faultsim_restore_and_reopen 1069c27758eSdan} -body { 1079c27758eSdan execsql { 1089c27758eSdan CREATE VIEW aaa AS 1099c27758eSdan SELECT min(d) OVER w, max(d) OVER w 1109c27758eSdan FROM t1 1119c27758eSdan WINDOW w AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING); 1129c27758eSdan SELECT * FROM aaa; 1139c27758eSdan } 1149c27758eSdan} -test { 1159c27758eSdan faultsim_test_result {0 {4 12 8 12 12 12}} 1169c27758eSdan} 1179c27758eSdan 1189c27758eSdando_faultsim_test 5 -start 1 -faults oom-* -prep { 1199c27758eSdan faultsim_restore_and_reopen 1209c27758eSdan} -body { 1219c27758eSdan execsql { 1229c27758eSdan SELECT last_value(a) OVER win1, 1239c27758eSdan last_value(a) OVER win2 1249c27758eSdan FROM t1 1259c27758eSdan WINDOW win1 AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING), 1269c27758eSdan win2 AS (ORDER BY a) 1279c27758eSdan } 1289c27758eSdan} -test { 1299c27758eSdan faultsim_test_result {0 {5 1 9 5 9 9}} 1309c27758eSdan} 1316fde1799Sdan 132cf0343b6Sdando_faultsim_test 6 -faults oom-* -prep { 133cf0343b6Sdan faultsim_restore_and_reopen 134cf0343b6Sdan} -body { 135cf0343b6Sdan execsql { 136cf0343b6Sdan SELECT percent_rank() OVER (), cume_dist() OVER () FROM t1 137cf0343b6Sdan } 138cf0343b6Sdan} -test { 139cf0343b6Sdan faultsim_test_result {0 {0.0 1.0 0.0 1.0 0.0 1.0}} 140cf0343b6Sdan} 141cf0343b6Sdan 142e6fcd1d5Sdando_faultsim_test 7 -faults oom-* -prep { 143e6fcd1d5Sdan faultsim_restore_and_reopen 144e6fcd1d5Sdan} -body { 145e6fcd1d5Sdan execsql { 146e6fcd1d5Sdan SELECT percent_rank() OVER (), cume_dist() OVER () FROM t1 147e6fcd1d5Sdan } 148e6fcd1d5Sdan} -test { 149e6fcd1d5Sdan faultsim_test_result {0 {0.0 1.0 0.0 1.0 0.0 1.0}} 150e6fcd1d5Sdan} 151e6fcd1d5Sdan 152e6fcd1d5Sdando_faultsim_test 8 -faults oom-t* -prep { 153e6fcd1d5Sdan faultsim_restore_and_reopen 154e6fcd1d5Sdan} -body { 155e6fcd1d5Sdan execsql { 156e6fcd1d5Sdan SELECT a, sum(b) OVER win1 FROM t1 157e6fcd1d5Sdan WINDOW win1 AS (PARTITION BY a ), 158e6fcd1d5Sdan win2 AS (PARTITION BY b ) 159e6fcd1d5Sdan ORDER BY a; 160e6fcd1d5Sdan } 161e6fcd1d5Sdan} -test { 162e6fcd1d5Sdan faultsim_test_result {0 {1 2 5 6 9 10}} 163e6fcd1d5Sdan} 164e6fcd1d5Sdan 16507080545Sdan#------------------------------------------------------------------------- 16607080545Sdan# The following test causes a cursor in REQURESEEK state to be passed 16707080545Sdan# to sqlite3BtreeDelete(). An error is simulated within the seek operation 16807080545Sdan# to restore the cursors position. 16907080545Sdan# 17007080545Sdanreset_db 17107080545Sdanset big [string repeat x 900] 17207080545Sdando_execsql_test 9.0 { 17307080545Sdan PRAGMA page_size = 512; 17407080545Sdan PRAGMA cache_size = 2; 17507080545Sdan CREATE TABLE t(x INTEGER PRIMARY KEY, y TEXT); 17607080545Sdan WITH s(i) AS ( 17707080545Sdan VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1900 17807080545Sdan ) 17907080545Sdan INSERT INTO t(y) SELECT $big FROM s; 18007080545Sdan} 18107080545Sdandb close 18207080545Sdan 18307080545Sdantestvfs tvfs -default 1 18407080545Sdantvfs script vfs_callback 18507080545Sdantvfs filter xRead 18607080545Sdan 18707080545Sdansqlite3 db test.db 18807080545Sdanproc vfs_callback {method file args} { 18907080545Sdan if {$file=="" && [info exists ::tmp_read_fail]} { 19007080545Sdan incr ::tmp_read_fail -1 19107080545Sdan if {$::tmp_read_fail<=0} { 19207080545Sdan return "SQLITE_IOERR" 19307080545Sdan } 19407080545Sdan } 19507080545Sdan return "SQLITE_OK" 19607080545Sdan} 19707080545Sdan 19807080545Sdanset FAULTSIM(tmpread) [list \ 19907080545Sdan -injectstart tmpread_injectstart \ 20007080545Sdan -injectstop tmpread_injectstop \ 20107080545Sdan -injecterrlist {{1 {disk I/O error}}} \ 20207080545Sdan] 20307080545Sdanproc tmpread_injectstart {iFail} { 20407080545Sdan set ::tmp_read_fail $iFail 20507080545Sdan} 20607080545Sdanproc tmpread_injectstop {} { 20707080545Sdan set ret [expr $::tmp_read_fail<=0] 20807080545Sdan unset -nocomplain ::tmp_read_fail 20907080545Sdan return $ret 21007080545Sdan} 21107080545Sdan 212e0155b7aSdanset L [db eval {SELECT 0.0 FROM t}] 21307080545Sdando_faultsim_test 9 -end 25 -faults tmpread -body { 21407080545Sdan execsql { 21507080545Sdan SELECT sum(y) OVER win FROM t 21607080545Sdan WINDOW win AS ( 21707080545Sdan ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND 1800 FOLLOWING 21807080545Sdan ) 21907080545Sdan } 22007080545Sdan} -test { 221e0155b7aSdan faultsim_test_result [list 0 $::L] 22207080545Sdan} 22307080545Sdan 22407080545Sdancatch {db close} 22507080545Sdantvfs delete 22607080545Sdan 2274780b9adSdanreset_db 2284780b9adSdando_execsql_test 10.0 { 2294780b9adSdan CREATE TABLE t1(a, b, c, d); 2304780b9adSdan CREATE TABLE t2(a, b, c, d); 2314780b9adSdan} 2324780b9adSdan 23369843342Sdando_faultsim_test 10 -faults oom* -prep { 2344780b9adSdan} -body { 2354780b9adSdan execsql { 2364780b9adSdan SELECT row_number() OVER win 2374780b9adSdan FROM t1 2384780b9adSdan WINDOW win AS ( 2394780b9adSdan ORDER BY ( 2404780b9adSdan SELECT percent_rank() OVER win2 FROM t2 2414780b9adSdan WINDOW win2 AS (ORDER BY a) 2424780b9adSdan ) 2434780b9adSdan ) 2444780b9adSdan } 2454780b9adSdan} -test { 2464780b9adSdan faultsim_test_result {0 {}} 2474780b9adSdan} 2484780b9adSdan 24934a224a1Sdan#------------------------------------------------------------------------- 25069843342Sdanreset_db 25169843342Sdando_execsql_test 11.0 { 25269843342Sdan DROP TABLE IF EXISTS t0; 25369843342Sdan CREATE TABLE t0(c0 INTEGER UNIQUE); 25469843342Sdan INSERT INTO t0 VALUES(0); 25569843342Sdan} {} 25669843342Sdan 25734a224a1Sdando_faultsim_test 11.1 -faults oom* -prep { 25869843342Sdan} -body { 25969843342Sdan execsql { 26069843342Sdan SELECT * FROM t0 WHERE 26169843342Sdan (0, t0.c0) IN (SELECT DENSE_RANK() OVER(), LAG(0) OVER() FROM t0); 26269843342Sdan } 26369843342Sdan} -test { 26469843342Sdan faultsim_test_result {0 {}} 26569843342Sdan} 26669843342Sdan 26734a224a1Sdando_faultsim_test 11.2 -faults oom* -prep { 2688a64d62dSdan} -body { 2698a64d62dSdan execsql { 2708a64d62dSdan VALUES(false),(current_date collate binary) 2718a64d62dSdan intersect 2728a64d62dSdan values(count() not like group_concat(cast(cast(0e00 as text) as integer) <= NULL || 0.4e-0 || 0x8 & true ) over () collate rtrim); 2738a64d62dSdan } 2748a64d62dSdan} -test { 2758a64d62dSdan faultsim_test_result {0 {}} 2768a64d62dSdan} 2778a64d62dSdan 27834a224a1Sdan#------------------------------------------------------------------------- 27934a224a1Sdanreset_db 28034a224a1Sdando_execsql_test 12.0 { 28134a224a1Sdan CREATE TABLE t1(a, b, c); 28234a224a1Sdan} {} 28334a224a1Sdando_faultsim_test 12 -faults oom* -prep { 28434a224a1Sdan} -body { 28534a224a1Sdan execsql { 28634a224a1Sdan WITH v(a, b, row_number) AS ( 28757f90189Sdrh SELECT a, b, row_number() OVER (PARTITION BY a COLLATE nocase ORDER BY b) FROM t1 28834a224a1Sdan ) 28934a224a1Sdan SELECT * FROM v WHERE a=2 29034a224a1Sdan } 29134a224a1Sdan} -test { 29234a224a1Sdan faultsim_test_result {0 {}} 29334a224a1Sdan} 29434a224a1Sdan 295*a92f9586Sdan#------------------------------------------------------------------------- 296*a92f9586Sdanreset_db 297*a92f9586Sdando_execsql_test 13.0 { 298*a92f9586Sdan CREATE TABLE t1(id INTEGER PRIMARY KEY, a, b); 299*a92f9586Sdan INSERT INTO t1 VALUES(1, '1', 'a'); 300*a92f9586Sdan INSERT INTO t1 VALUES(2, '22', 'b'); 301*a92f9586Sdan INSERT INTO t1 VALUES(3, '333', 'c'); 302*a92f9586Sdan INSERT INTO t1 VALUES(4, '4444', 'dddd'); 303*a92f9586Sdan INSERT INTO t1 VALUES(5, '55555', 'e'); 304*a92f9586Sdan INSERT INTO t1 VALUES(6, '666666', 'f'); 305*a92f9586Sdan INSERT INTO t1 VALUES(7, '7777777', 'gggggggggg'); 306*a92f9586Sdan} {} 307*a92f9586Sdan 308*a92f9586Sdanset queryres [list {*}{ 309*a92f9586Sdan 1b22 310*a92f9586Sdan 1b22c333 311*a92f9586Sdan 22c333dddd4444 312*a92f9586Sdan 333dddd4444e55555 313*a92f9586Sdan 4444e55555f666666 314*a92f9586Sdan 55555f666666gggggggggg7777777 315*a92f9586Sdan 666666gggggggggg7777777 316*a92f9586Sdan}] 317*a92f9586Sdando_execsql_test 13.1 { 318*a92f9586Sdan SELECT group_concat(a, b) OVER ( 319*a92f9586Sdan ORDER BY id RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING 320*a92f9586Sdan ) FROM t1 321*a92f9586Sdan} $queryres 322*a92f9586Sdan 323*a92f9586Sdando_faultsim_test 13 -faults oom* -prep { 324*a92f9586Sdan} -body { 325*a92f9586Sdan execsql { 326*a92f9586Sdan SELECT group_concat(a, b) OVER ( 327*a92f9586Sdan ORDER BY id RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING 328*a92f9586Sdan ) FROM t1 329*a92f9586Sdan } 330*a92f9586Sdan} -test { 331*a92f9586Sdan faultsim_test_result [list 0 $::queryres] 332*a92f9586Sdan} 333*a92f9586Sdan 3346fde1799Sdanfinish_test 335