123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- # 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 { finish_test ; return }
- load_static_extension db closure
- do_execsql_test 1.0 {
- BEGIN;
- CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER);
- CREATE INDEX t1y ON t1(y);
- INSERT INTO t1(x) VALUES(1),(2);
- INSERT INTO t1(x) SELECT x+2 FROM t1;
- INSERT INTO t1(x) SELECT x+4 FROM t1;
- INSERT INTO t1(x) SELECT x+8 FROM t1;
- INSERT INTO t1(x) SELECT x+16 FROM t1;
- INSERT INTO t1(x) SELECT x+32 FROM t1;
- INSERT INTO t1(x) SELECT x+64 FROM t1;
- INSERT INTO t1(x) SELECT x+128 FROM t1;
- INSERT INTO t1(x) SELECT x+256 FROM t1;
- INSERT INTO t1(x) SELECT x+512 FROM t1;
- INSERT INTO t1(x) SELECT x+1024 FROM t1;
- INSERT INTO t1(x) SELECT x+2048 FROM t1;
- INSERT INTO t1(x) SELECT x+4096 FROM t1;
- INSERT INTO t1(x) SELECT x+8192 FROM t1;
- INSERT INTO t1(x) SELECT x+16384 FROM t1;
- INSERT INTO t1(x) SELECT x+32768 FROM t1;
- INSERT INTO t1(x) SELECT x+65536 FROM t1;
- UPDATE t1 SET y=x/2 WHERE x>1;
- COMMIT;
- CREATE VIRTUAL TABLE cx
- USING transitive_closure(tablename=t1, idcolumn=x, parentcolumn=y);
- } {}
- # The entire table
- do_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/}
- # descendents of 32768
- do_execsql_test 1.2 {
- SELECT * FROM cx WHERE root=32768 ORDER BY id;
- } {32768 0 65536 1 65537 1 131072 2}
- # descendents of 16384
- do_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}
- # 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_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}
- # depth<5
- do_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}
- # 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_execsql_test 1.10 {
- SELECT count(*), min(id), max(id) FROM cx WHERE root=1 AND 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}
- finish_test
|