Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0622465

Browse files
committed
Add docs and regression test about sorting the output of a recursive query in
depth-first search order. Upon close reading of SQL:2008, it seems that thespec's SEARCH DEPTH FIRST and SEARCH BREADTH FIRST options do not actuallyguarantee any particular result order: what they do is provide a constructedcolumn that the user can then sort on in the outer query. So this is actuallyjust as much functionality ...
1 parent1f238e5 commit0622465

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

‎doc/src/sgml/queries.sgml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.49 2008/10/14 00:12:44 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.50 2008/10/14 00:41:34 tgl Exp $ -->
22

33
<chapter id="queries">
44
<title>Queries</title>
@@ -1681,6 +1681,15 @@ SELECT * FROM search_graph;
16811681
</para>
16821682
</tip>
16831683

1684+
<tip>
1685+
<para>
1686+
The recursive query evaluation algorithm produces its output in
1687+
breadth-first search order. You can display the results in depth-first
1688+
search order by making the outer query <literal>ORDER BY</> a
1689+
<quote>path</> column constructed in this way.
1690+
</para>
1691+
</tip>
1692+
16841693
<para>
16851694
A helpful trick for testing queries
16861695
when you are not certain if they might loop is to place a <literal>LIMIT</>
@@ -1699,7 +1708,9 @@ SELECT n FROM t LIMIT 100;
16991708
This works because <productname>PostgreSQL</productname>'s implementation
17001709
evaluates only as many rows of a <literal>WITH</> query as are actually
17011710
fetched by the parent query. Using this trick in production is not
1702-
recommended, because other systems might work differently.
1711+
recommended, because other systems might work differently. Also, it
1712+
usually won't work if you make the outer query sort the recursive query's
1713+
results or join them to some other table.
17031714
</para>
17041715

17051716
<para>

‎src/test/regress/expected/with.out

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,44 @@ select * from search_graph;
499499
2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f
500500
(25 rows)
501501

502+
-- ordering by the path column has same effect as SEARCH DEPTH FIRST
503+
with recursive search_graph(f, t, label, path, cycle) as (
504+
select *, array[row(g.f, g.t)], false from graph g
505+
union all
506+
select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path)
507+
from graph g, search_graph sg
508+
where g.f = sg.t and not cycle
509+
)
510+
select * from search_graph order by path;
511+
f | t | label | path | cycle
512+
---+---+------------+-------------------------------------------+-------
513+
1 | 2 | arc 1 -> 2 | {"(1,2)"} | f
514+
2 | 3 | arc 2 -> 3 | {"(1,2)","(2,3)"} | f
515+
1 | 3 | arc 1 -> 3 | {"(1,3)"} | f
516+
1 | 4 | arc 1 -> 4 | {"(1,4)"} | f
517+
4 | 5 | arc 4 -> 5 | {"(1,4)","(4,5)"} | f
518+
5 | 1 | arc 5 -> 1 | {"(1,4)","(4,5)","(5,1)"} | f
519+
1 | 2 | arc 1 -> 2 | {"(1,4)","(4,5)","(5,1)","(1,2)"} | f
520+
2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f
521+
1 | 3 | arc 1 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,3)"} | f
522+
1 | 4 | arc 1 -> 4 | {"(1,4)","(4,5)","(5,1)","(1,4)"} | t
523+
2 | 3 | arc 2 -> 3 | {"(2,3)"} | f
524+
4 | 5 | arc 4 -> 5 | {"(4,5)"} | f
525+
5 | 1 | arc 5 -> 1 | {"(4,5)","(5,1)"} | f
526+
1 | 2 | arc 1 -> 2 | {"(4,5)","(5,1)","(1,2)"} | f
527+
2 | 3 | arc 2 -> 3 | {"(4,5)","(5,1)","(1,2)","(2,3)"} | f
528+
1 | 3 | arc 1 -> 3 | {"(4,5)","(5,1)","(1,3)"} | f
529+
1 | 4 | arc 1 -> 4 | {"(4,5)","(5,1)","(1,4)"} | f
530+
4 | 5 | arc 4 -> 5 | {"(4,5)","(5,1)","(1,4)","(4,5)"} | t
531+
5 | 1 | arc 5 -> 1 | {"(5,1)"} | f
532+
1 | 2 | arc 1 -> 2 | {"(5,1)","(1,2)"} | f
533+
2 | 3 | arc 2 -> 3 | {"(5,1)","(1,2)","(2,3)"} | f
534+
1 | 3 | arc 1 -> 3 | {"(5,1)","(1,3)"} | f
535+
1 | 4 | arc 1 -> 4 | {"(5,1)","(1,4)"} | f
536+
4 | 5 | arc 4 -> 5 | {"(5,1)","(1,4)","(4,5)"} | f
537+
5 | 1 | arc 5 -> 1 | {"(5,1)","(1,4)","(4,5)","(5,1)"} | t
538+
(25 rows)
539+
502540
--
503541
-- test multiple WITH queries
504542
--

‎src/test/regress/sql/with.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,16 @@ with recursive search_graph(f, t, label, path, cycle) as (
272272
)
273273
select*from search_graph;
274274

275+
-- ordering by the path column has same effect as SEARCH DEPTH FIRST
276+
with recursive search_graph(f, t, label,path, cycle)as (
277+
select*, array[row(g.f,g.t)], falsefrom graph g
278+
union all
279+
select g.*,path|| row(g.f,g.t), row(g.f,g.t)= any(path)
280+
from graph g, search_graph sg
281+
whereg.f=sg.tand not cycle
282+
)
283+
select*from search_graphorder bypath;
284+
275285
--
276286
-- test multiple WITH queries
277287
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp