From: dan Date: Fri, 24 Jan 2014 16:57:42 +0000 (+0000) Subject: Add test cases for LIMIT and ORDER BY on recursive CTEs. X-Git-Tag: version-3.8.3~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=05d3dc29c5fa8f5e404079493e7e02fc8b033da1;p=thirdparty%2Fsqlite.git Add test cases for LIMIT and ORDER BY on recursive CTEs. FossilOrigin-Name: 67d6c42d44cb191368ce20f553b32fcb14bfc4d7 --- diff --git a/manifest b/manifest index e446313c60..f46cfae2f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\san\sunsigned\sinteger\sto\saccumulate\sthe\sstring\shash.\s\sAvoids\scompiler\nwarnings. -D 2014-01-24T16:36:18.370 +C Add\stest\scases\sfor\sLIMIT\sand\sORDER\sBY\son\srecursive\sCTEs. +D 2014-01-24T16:57:42.837 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 9d3537372c8cf6d5e0a5e9af037a52f3375fb704 +F test/with1.test 6c9c27b76e320d0ae3a3fc9ff6b236018201470d F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1b6405d9788c1bb89761b2bcdce560a5020ff503 -R f7e02965abaaba2b2c591f1141f3d7cf -U drh -Z 197e448152d1aa82b77763ec048456c7 +P b1824344ea4918a13abbda4a3b7134d35fd867c4 +R 9a46b9863f9dd82900d571672109f9d1 +U dan +Z c5f919f56b9fa0112bb7211064a506d1 diff --git a/manifest.uuid b/manifest.uuid index 710b1dce96..44c9c799f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1824344ea4918a13abbda4a3b7134d35fd867c4 \ No newline at end of file +67d6c42d44cb191368ce20f553b32fcb14bfc4d7 \ No newline at end of file diff --git a/test/with1.test b/test/with1.test index 6dd67d1690..486f025c64 100644 --- a/test/with1.test +++ b/test/with1.test @@ -452,11 +452,165 @@ do_execsql_test 8.2-soduko { SELECT s FROM x WHERE ind=0; } {534678912672195348198342567859761423426853791713924856961537284287419635345286179} +#-------------------------------------------------------------------------- +# Some tests that use LIMIT and OFFSET in the definition of recursive CTEs. +# +set I [list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] +proc limit_test {tn iLimit iOffset} { + if {$iOffset < 0} { set iOffset 0 } + if {$iLimit < 0 } { + set result [lrange $::I $iOffset end] + } else { + set result [lrange $::I $iOffset [expr $iLimit+$iOffset-1]] + } + uplevel [list do_execsql_test $tn [subst -nocommands { + WITH ii(a) AS ( + VALUES(1) + UNION ALL + SELECT a+1 FROM ii WHERE a<20 + LIMIT $iLimit OFFSET $iOffset + ) + SELECT * FROM ii + }] $result] +} + +limit_test 9.1 20 0 +limit_test 9.2 0 0 +limit_test 9.3 19 1 +limit_test 9.4 20 -1 +limit_test 9.5 5 5 +limit_test 9.6 0 -1 +limit_test 9.7 40 -1 +limit_test 9.8 -1 -1 +limit_test 9.9 -1 -1 + +#-------------------------------------------------------------------------- +# Test the ORDER BY clause on recursive tables. +# + +do_execsql_test 10.1 { + DROP TABLE IF EXISTS tree; + CREATE TABLE tree(id INTEGER PRIMARY KEY, parentid, payload); +} + +proc insert_into_tree {L} { + db eval { DELETE FROM tree } + foreach key $L { + unset -nocomplain parentid + foreach seg [split $key /] { + if {$seg==""} continue + set id [db one { + SELECT id FROM tree WHERE parentid IS $parentid AND payload=$seg + }] + if {$id==""} { + db eval { INSERT INTO tree VALUES(NULL, $parentid, $seg) } + set parentid [db last_insert_rowid] + } else { + set parentid $id + } + } + } +} + +insert_into_tree { + /a/a/a + /a/b/c + /a/b/c/d + /a/b/d +} +do_execsql_test 10.2 { + WITH flat(fid, p) AS ( + SELECT id, '/' || payload FROM tree WHERE parentid IS NULL + UNION ALL + SELECT id, p || '/' || payload FROM flat, tree WHERE parentid=fid + ) + SELECT p FROM flat ORDER BY p; +} { + /a /a/a /a/a/a + /a/b /a/b/c /a/b/c/d + /a/b/d +} + +# Scan the tree-structure currently stored in table tree. Return a list +# of nodes visited. +# +proc scan_tree {bDepthFirst bReverse} { + + set order "ORDER BY " + if {$bDepthFirst==0} { append order "2 ASC," } + if {$bReverse==0} { + append order " 3 ASC" + } else { + append order " 3 DESC" + } + + db eval " + WITH flat(fid, depth, p) AS ( + SELECT id, 1, '/' || payload FROM tree WHERE parentid IS NULL + UNION ALL + SELECT id, depth+1, p||'/'||payload FROM flat, tree WHERE parentid=fid + $order + ) + SELECT p FROM flat; + " +} + +insert_into_tree { + /a/b + /a/b/c + /a/d + /a/d/e + /a/d/f + /g/h +} + +# Breadth first, siblings in ascending order. +# +do_test 10.3 { + scan_tree 0 0 +} [list {*}{ + /a /g + /a/b /a/d /g/h + /a/b/c /a/d/e /a/d/f +}] + +# Depth first, siblings in ascending order. +# +do_test 10.4 { + scan_tree 1 0 +} [list {*}{ + /a /a/b /a/b/c + /a/d /a/d/e + /a/d/f + /g /g/h +}] + +# Breadth first, siblings in descending order. +# +do_test 10.5 { + scan_tree 0 1 +} [list {*}{ + /g /a + /g/h /a/d /a/b + /a/d/f /a/d/e /a/b/c +}] + +# Depth first, siblings in ascending order. +# +do_test 10.6 { + scan_tree 1 1 +} [list {*}{ + /g /g/h + /a /a/d /a/d/f + /a/d/e + /a/b /a/b/c +}] + # Test cases to illustrate on the ORDER BY clause on a recursive query can be # used to control depth-first versus breath-first search in a tree. # -do_execsql_test 9.1 { +do_execsql_test 11.1 { CREATE TABLE org( name TEXT PRIMARY KEY, boss TEXT REFERENCES org @@ -513,7 +667,7 @@ do_execsql_test 9.1 { # The previous query used "ORDER BY level" to yield a breath-first search. # Change that to "ORDER BY level DESC" for a depth-first search. # -do_execsql_test 9.2 { +do_execsql_test 11.2 { WITH RECURSIVE under_alice(name,level) AS ( VALUES('Alice','0') @@ -544,7 +698,7 @@ do_execsql_test 9.2 { # Without an ORDER BY clause, the recursive query should use a FIFO, # resulting in a breath-first search. # -do_execsql_test 9.3 { +do_execsql_test 11.3 { WITH RECURSIVE under_alice(name,level) AS ( VALUES('Alice','0') @@ -572,3 +726,4 @@ do_execsql_test 9.3 { .........Olivia}} finish_test +