diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:28:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:28:19 +0000 |
commit | 18657a960e125336f704ea058e25c27bd3900dcb (patch) | |
tree | 17b438b680ed45a996d7b59951e6aa34023783f2 /test/closure01.test | |
parent | Initial commit. (diff) | |
download | sqlite3-18657a960e125336f704ea058e25c27bd3900dcb.tar.xz sqlite3-18657a960e125336f704ea058e25c27bd3900dcb.zip |
Adding upstream version 3.40.1.upstream/3.40.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/closure01.test')
-rw-r--r-- | test/closure01.test | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/test/closure01.test b/test/closure01.test new file mode 100644 index 0000000..ee3f2dd --- /dev/null +++ b/test/closure01.test @@ -0,0 +1,295 @@ +# 2013-04-25 +# +# 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. +# +#*********************************************************************** +# +# Test cases for transitive_closure virtual table. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix closure01 + +ifcapable !vtab||!cte { finish_test ; return } + +load_static_extension db closure + +do_execsql_test 1.0 { + BEGIN; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER); + WITH RECURSIVE + cnt(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM cnt LIMIT 131072) + INSERT INTO t1(x, y) SELECT i, nullif(i,1)/2 FROM cnt; + CREATE INDEX t1y ON t1(y); + COMMIT; + CREATE VIRTUAL TABLE cx + USING transitive_closure(tablename=t1, idcolumn=x, parentcolumn=y); +} {} + +# The entire table +do_timed_execsql_test 1.1 { + SELECT count(*), depth FROM cx WHERE root=1 GROUP BY depth ORDER BY 1; +} {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/} +do_timed_execsql_test 1.1-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(1,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below on t1.y=below.id + ) + SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1; +} {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/} + +# descendents of 32768 +do_timed_execsql_test 1.2 { + SELECT * FROM cx WHERE root=32768 ORDER BY id; +} {32768 0 65536 1 65537 1 131072 2} +do_timed_execsql_test 1.2-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(32768,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below on t1.y=below.id + WHERE below.depth<2 + ) + SELECT id, depth FROM below ORDER BY id; +} {32768 0 65536 1 65537 1 131072 2} + +# descendents of 16384 +do_timed_execsql_test 1.3 { + SELECT * FROM cx WHERE root=16384 AND depth<=2 ORDER BY id; +} {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2} +do_timed_execsql_test 1.3-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(16384,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below on t1.y=below.id + WHERE below.depth<2 + ) + SELECT id, depth FROM below ORDER BY id; +} {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2} + +# children of 16384 +do_execsql_test 1.4 { + SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx + WHERE root=16384 + AND depth=1 + ORDER BY id; +} {32768 1 {} t1 x y 32769 1 {} t1 x y} + +# great-grandparent of 16384 +do_timed_execsql_test 1.5 { + SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx + WHERE root=16384 + AND depth=3 + AND idcolumn='Y' + AND parentcolumn='X'; +} {2048 3 {} t1 Y X} +do_timed_execsql_test 1.5-cte { + WITH RECURSIVE + above(id,depth) AS ( + VALUES(16384,0) + UNION ALL + SELECT t1.y, above.depth+1 + FROM t1 JOIN above ON t1.x=above.id + WHERE above.depth<3 + ) + SELECT id FROM above WHERE depth=3; +} {2048} + +# depth<5 +do_timed_execsql_test 1.6 { + SELECT count(*), depth FROM cx WHERE root=1 AND depth<5 + GROUP BY depth ORDER BY 1; +} {1 0 2 1 4 2 8 3 16 4} +do_timed_execsql_test 1.6-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(1,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below ON t1.y=below.id + WHERE below.depth<4 + ) + SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1; +} {1 0 2 1 4 2 8 3 16 4} + +# depth<=5 +do_execsql_test 1.7 { + SELECT count(*), depth FROM cx WHERE root=1 AND depth<=5 + GROUP BY depth ORDER BY 1; +} {1 0 2 1 4 2 8 3 16 4 32 5} + +# depth==5 +do_execsql_test 1.8 { + SELECT count(*), depth FROM cx WHERE root=1 AND depth=5 + GROUP BY depth ORDER BY 1; +} {32 5} + +# depth BETWEEN 3 AND 5 +do_execsql_test 1.9 { + SELECT count(*), depth FROM cx WHERE root=1 AND depth BETWEEN 3 AND 5 + GROUP BY depth ORDER BY 1; +} {8 3 16 4 32 5} + +# depth==5 with min() and max() +do_timed_execsql_test 1.10 { + SELECT count(*), min(id), max(id) FROM cx WHERE root=1 AND depth=5; +} {32 32 63} +do_timed_execsql_test 1.10-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(1,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below ON t1.y=below.id + WHERE below.depth<5 + ) + SELECT count(*), min(id), max(id) FROM below WHERE depth=5; +} {32 32 63} + +# Create a much smaller table t2 with only 32 elements +db eval { + CREATE TABLE t2(x INTEGER PRIMARY KEY, y INTEGER); + INSERT INTO t2 SELECT x, y FROM t1 WHERE x<32; + CREATE INDEX t2y ON t2(y); + CREATE VIRTUAL TABLE c2 + USING transitive_closure(tablename=t2, idcolumn=x, parentcolumn=y); +} + +# t2 full-table +do_execsql_test 2.1 { + SELECT count(*), min(id), max(id) FROM c2 WHERE root=1; +} {31 1 31} +# t2 root=10 +do_execsql_test 2.2 { + SELECT id FROM c2 WHERE root=10; +} {10 20 21} +# t2 root=11 +do_execsql_test 2.3 { + SELECT id FROM c2 WHERE root=12; +} {12 24 25} +# t2 root IN [10,12] +do_execsql_test 2.4 { + SELECT id FROM c2 WHERE root IN (10,12) ORDER BY id; +} {10 12 20 21 24 25} +# t2 root IN [10,12] (sorted) +do_execsql_test 2.5 { + SELECT id FROM c2 WHERE root IN (10,12) ORDER BY +id; +} {10 12 20 21 24 25} + +# t2 c2up from 20 +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE c2up USING transitive_closure( + tablename = t2, + idcolumn = y, + parentcolumn = x + ); + SELECT id FROM c2up WHERE root=20; +} {1 2 5 10 20} + +# cx as c2up +do_execsql_test 3.1 { + SELECT id FROM cx + WHERE root=20 + AND tablename='t2' + AND idcolumn='y' + AND parentcolumn='x'; +} {1 2 5 10 20} + +# t2 first cousins of 20 +do_execsql_test 3.2 { + SELECT DISTINCT id FROM c2 + WHERE root IN (SELECT id FROM c2up + WHERE root=20 AND depth<=2) + ORDER BY id; +} {5 10 11 20 21 22 23} + +# t2 first cousins of 20 +do_execsql_test 3.3 { + SELECT id FROM c2 + WHERE root=(SELECT id FROM c2up + WHERE root=20 AND depth=2) + AND depth=2 + EXCEPT + SELECT id FROM c2 + WHERE root=(SELECT id FROM c2up + WHERE root=20 AND depth=1) + AND depth<=1 + ORDER BY id; +} {22 23} + +# missing tablename. +do_test 4.1 { + catchsql { + SELECT id FROM cx + WHERE root=20 + AND tablename='t3' + AND idcolumn='y' + AND parentcolumn='x'; + } +} {1 {no such table: t3}} + +# missing idcolumn +do_test 4.2 { + catchsql { + SELECT id FROM cx + WHERE root=20 + AND tablename='t2' + AND idcolumn='xyz' + AND parentcolumn='x'; + } +} {1 {no such column: t2.xyz}} + +# missing parentcolumn +do_test 4.3 { + catchsql { + SELECT id FROM cx + WHERE root=20 + AND tablename='t2' + AND idcolumn='x' + AND parentcolumn='pqr'; + } +} {1 {no such column: t2.pqr}} + +# generic closure +do_execsql_test 5.1 { + CREATE VIRTUAL TABLE temp.closure USING transitive_closure; + SELECT id FROM closure + WHERE root=1 + AND depth=3 + AND tablename='t1' + AND idcolumn='x' + AND parentcolumn='y' + ORDER BY id; +} {8 9 10 11 12 13 14 15} + +#------------------------------------------------------------------------- +# At one point the following join query was causing a malfunction in +# xBestIndex. +# +do_execsql_test 6.0 { + CREATE TABLE t4 ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + parent_id INTEGER + ); + CREATE VIRTUAL TABLE vt4 USING transitive_closure ( + idcolumn=id, parentcolumn=parent_id, tablename=t4 + ); +} + +do_execsql_test 6.1 { + SELECT * FROM t4, vt4 WHERE t4.id = vt4.root AND vt4.id=4 AND vt4.depth=2; +} + +finish_test |