You can subscribe to this list here.
2010 |
Jan
|
Feb
|
Mar
|
Apr
(4) |
May
(28) |
Jun
(12) |
Jul
(11) |
Aug
(12) |
Sep
(5) |
Oct
(19) |
Nov
(14) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
(18) |
Feb
(30) |
Mar
(115) |
Apr
(89) |
May
(50) |
Jun
(44) |
Jul
(22) |
Aug
(13) |
Sep
(11) |
Oct
(30) |
Nov
(28) |
Dec
(39) |
2012 |
Jan
(38) |
Feb
(18) |
Mar
(43) |
Apr
(91) |
May
(108) |
Jun
(46) |
Jul
(37) |
Aug
(44) |
Sep
(33) |
Oct
(29) |
Nov
(36) |
Dec
(15) |
2013 |
Jan
(35) |
Feb
(611) |
Mar
(5) |
Apr
(55) |
May
(30) |
Jun
(28) |
Jul
(458) |
Aug
(34) |
Sep
(9) |
Oct
(39) |
Nov
(22) |
Dec
(32) |
2014 |
Jan
(16) |
Feb
(16) |
Mar
(42) |
Apr
(179) |
May
(7) |
Jun
(6) |
Jul
(9) |
Aug
|
Sep
(4) |
Oct
|
Nov
(3) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
|
|
|
1
(2) |
2
(3) |
3
|
4
(2) |
5
(3) |
6
(2) |
7
(8) |
8
(12) |
9
|
10
|
11
(17) |
12
(16) |
13
(4) |
14
(3) |
15
(5) |
16
|
17
|
18
(1) |
19
(3) |
20
(2) |
21
(1) |
22
(1) |
23
|
24
|
25
(3) |
26
(1) |
27
|
28
|
29
|
30
|
From: Michael P. <mic...@us...> - 2011-04-19 06:21:57
|
Project "Postgres-XC". The branch, master has been updated via 2610315b335ac97ed88ff532c58239c3a8685206 (commit) from e12ca2d640d6c9d09aefeb05bbce1fba01e9549a (commit) - Log ----------------------------------------------------------------- commit 2610315b335ac97ed88ff532c58239c3a8685206 Author: Michael P <mic...@us...> Date: Tue Apr 19 15:17:28 2011 +0900 Fix for regression test with Due to Postgres-XC restrictions (TEMP tables), this output is correct. diff --git a/src/test/regress/expected/with_1.out b/src/test/regress/expected/with_1.out new file mode 100644 index 0000000..5ae3440 --- /dev/null +++ b/src/test/regress/expected/with_1.out @@ -0,0 +1,879 @@ +-- +-- Tests for common table expressions (WITH query, ... SELECT ...) +-- +-- Basic WITH +WITH q1(x,y) AS (SELECT 1,2) +SELECT * FROM q1, q1 AS q2; + x | y | x | y +---+---+---+--- + 1 | 2 | 1 | 2 +(1 row) + +-- Multiple uses are evaluated only once +SELECT count(*) FROM ( + WITH q1(x) AS (SELECT random() FROM generate_series(1, 5)) + SELECT * FROM q1 + UNION + SELECT * FROM q1 +) ss; + count +------- + 5 +(1 row) + +-- WITH RECURSIVE +-- sum of 1..100 +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t; + sum +------ + 5050 +(1 row) + +WITH RECURSIVE t(n) AS ( + SELECT (VALUES(1)) +UNION ALL + SELECT n+1 FROM t WHERE n < 5 +) +SELECT * FROM t ORDER BY n; + n +--- + 1 + 2 + 3 + 4 + 5 +(5 rows) + +-- This is an infinite loop with UNION ALL, but not with UNION +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT 10-n FROM t) +SELECT * FROM t ORDER BY n; + n +--- + 1 + 9 +(2 rows) + +-- This'd be an infinite loop, but outside query reads only as much as needed +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10; + n +---- + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 +(10 rows) + +-- UNION case should have same property +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10; + n +---- + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 +(10 rows) + +-- Test behavior with an unknown-type literal in the WITH +WITH q AS (SELECT 'foo' AS x) +SELECT x, x IS OF (unknown) as is_unknown FROM q; + x | is_unknown +-----+------------ + foo | t +(1 row) + +WITH RECURSIVE t(n) AS ( + SELECT 'foo' +UNION ALL + SELECT n || ' bar' FROM t WHERE length(n) < 20 +) +SELECT n, n IS OF (text) as is_text FROM t ORDER BY n; + n | is_text +-------------------------+--------- + foo | t + foo bar | t + foo bar bar | t + foo bar bar bar | t + foo bar bar bar bar | t + foo bar bar bar bar bar | t +(6 rows) + +-- +-- Some examples with a tree +-- +-- department structure represented here is as follows: +-- +-- ROOT-+->A-+->B-+->C +-- | | +-- | +->D-+->F +-- +->E-+->G +CREATE TEMP TABLE department ( + id INTEGER PRIMARY KEY, -- department ID + parent_department INTEGER REFERENCES department, -- upper department ID + name TEXT -- department name +); +ERROR: PG-XC does not yet support temporary tables +INSERT INTO department VALUES (0, NULL, 'ROOT'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (0, NULL, 'ROOT'); + ^ +INSERT INTO department VALUES (1, 0, 'A'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (1, 0, 'A'); + ^ +INSERT INTO department VALUES (2, 1, 'B'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (2, 1, 'B'); + ^ +INSERT INTO department VALUES (3, 2, 'C'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (3, 2, 'C'); + ^ +INSERT INTO department VALUES (4, 2, 'D'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (4, 2, 'D'); + ^ +INSERT INTO department VALUES (5, 0, 'E'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (5, 0, 'E'); + ^ +INSERT INTO department VALUES (6, 4, 'F'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (6, 4, 'F'); + ^ +INSERT INTO department VALUES (7, 5, 'G'); +ERROR: relation "department" does not exist +LINE 1: INSERT INTO department VALUES (7, 5, 'G'); + ^ +-- extract all departments under 'A'. Result should be A, B, C, D and F +WITH RECURSIVE subdepartment AS +( + -- non recursive term + SELECT name as root_name, * FROM department WHERE name = 'A' + UNION ALL + -- recursive term + SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name; +ERROR: relation "department" does not exist +LINE 4: SELECT name as root_name, * FROM department WHERE name = 'A... + ^ +-- extract all departments under 'A' with "level" number +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + UNION ALL + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name; +ERROR: relation "department" does not exist +LINE 4: SELECT 1, * FROM department WHERE name = 'A' + ^ +-- extract all departments under 'A' with "level" number. +-- Only shows level 2 or more +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + UNION ALL + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment WHERE level >= 2 ORDER BY name; +ERROR: relation "department" does not exist +LINE 4: SELECT 1, * FROM department WHERE name = 'A' + ^ +-- "RECURSIVE" is ignored if the query has no self-reference +WITH RECURSIVE subdepartment AS +( + -- note lack of recursive UNION structure + SELECT * FROM department WHERE name = 'A' +) +SELECT * FROM subdepartment ORDER BY name; +ERROR: relation "department" does not exist +LINE 4: SELECT * FROM department WHERE name = 'A' + ^ +-- inside subqueries +SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 500 + ) + SELECT * FROM t) AS t WHERE n < ( + SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 100 + ) + SELECT * FROM t WHERE n < 50000 + ) AS t WHERE n < 100); + count +------- + 98 +(1 row) + +-- use same CTE twice at different subquery levels +WITH q1(x,y) AS ( + SELECT hundred, sum(ten) FROM tenk1 GROUP BY hundred + ) +SELECT count(*) FROM q1 WHERE y > (SELECT sum(y)/100 FROM q1 qsub); +ERROR: GROUP BY clause is not yet supported +-- via a VIEW +CREATE TEMPORARY VIEW vsubdepartment AS + WITH RECURSIVE subdepartment AS + ( + -- non recursive term + SELECT * FROM department WHERE name = 'A' + UNION ALL + -- recursive term + SELECT d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id + ) + SELECT * FROM subdepartment; +ERROR: relation "department" does not exist +LINE 5: SELECT * FROM department WHERE name = 'A' + ^ +SELECT * FROM vsubdepartment ORDER BY name; +ERROR: relation "vsubdepartment" does not exist +LINE 1: SELECT * FROM vsubdepartment ORDER BY name; + ^ +-- Check reverse listing +SELECT pg_get_viewdef('vsubdepartment'::regclass); +ERROR: relation "vsubdepartment" does not exist +LINE 1: SELECT pg_get_viewdef('vsubdepartment'::regclass); + ^ +SELECT pg_get_viewdef('vsubdepartment'::regclass, true); +ERROR: relation "vsubdepartment" does not exist +LINE 1: SELECT pg_get_viewdef('vsubdepartment'::regclass, true); + ^ +-- corner case in which sub-WITH gets initialized first +with recursive q as ( + (select * from department order by id) + union all + (with x as (select * from q) + select * from x) + ) +select * from q limit 24; +ERROR: relation "department" does not exist +LINE 2: (select * from department order by id) + ^ +with recursive q as ( + (select * from department order by id) + union all + (with recursive x as ( + select * from department + union all + (select * from q union all select * from x) + ) + select * from x) + ) +select * from q limit 32; +ERROR: relation "department" does not exist +LINE 2: (select * from department order by id) + ^ +-- recursive term has sub-UNION +WITH RECURSIVE t(i,j) AS ( + VALUES (1,2) + UNION ALL + SELECT t2.i, t.j+1 FROM + (SELECT 2 AS i UNION ALL SELECT 3 AS i) AS t2 + JOIN t ON (t2.i = t.i+1)) + SELECT * FROM t order by i; + i | j +---+--- + 1 | 2 + 2 | 3 + 3 | 4 +(3 rows) + +-- +-- different tree example +-- +CREATE TEMPORARY TABLE tree( + id INTEGER PRIMARY KEY, + parent_id INTEGER REFERENCES tree(id) +); +ERROR: PG-XC does not yet support temporary tables +INSERT INTO tree +VALUES (1, NULL), (2, 1), (3,1), (4,2), (5,2), (6,2), (7,3), (8,3), + (9,4), (10,4), (11,7), (12,7), (13,7), (14, 9), (15,11), (16,11); +ERROR: relation "tree" does not exist +LINE 1: INSERT INTO tree + ^ +-- +-- get all paths from "second level" nodes to leaf nodes +-- +WITH RECURSIVE t(id, path) AS ( + VALUES(1,ARRAY[]::integer[]) +UNION ALL + SELECT tree.id, t.path || tree.id + FROM tree JOIN t ON (tree.parent_id = t.id) +) +SELECT t1.*, t2.* FROM t AS t1 JOIN t AS t2 ON + (t1.path[1] = t2.path[1] AND + array_upper(t1.path,1) = 1 AND + array_upper(t2.path,1) > 1) + ORDER BY t1.id, t2.id; +ERROR: relation "tree" does not exist +LINE 5: FROM tree JOIN t ON (tree.parent_id = t.id) + ^ +-- just count 'em +WITH RECURSIVE t(id, path) AS ( + VALUES(1,ARRAY[]::integer[]) +UNION ALL + SELECT tree.id, t.path || tree.id + FROM tree JOIN t ON (tree.parent_id = t.id) +) +SELECT t1.id, count(t2.*) FROM t AS t1 JOIN t AS t2 ON + (t1.path[1] = t2.path[1] AND + array_upper(t1.path,1) = 1 AND + array_upper(t2.path,1) > 1) + GROUP BY t1.id + ORDER BY t1.id; +ERROR: relation "tree" does not exist +LINE 5: FROM tree JOIN t ON (tree.parent_id = t.id) + ^ +-- this variant tickled a whole-row-variable bug in 8.4devel +WITH RECURSIVE t(id, path) AS ( + VALUES(1,ARRAY[]::integer[]) +UNION ALL + SELECT tree.id, t.path || tree.id + FROM tree JOIN t ON (tree.parent_id = t.id) +) +SELECT t1.id, t2.path, t2 FROM t AS t1 JOIN t AS t2 ON +(t1.id=t2.id) ORDER BY id; +ERROR: relation "tree" does not exist +LINE 5: FROM tree JOIN t ON (tree.parent_id = t.id) + ^ +-- +-- test cycle detection +-- +create temp table graph( f int, t int, label text ); +ERROR: PG-XC does not yet support temporary tables +insert into graph values + (1, 2, 'arc 1 -> 2'), + (1, 3, 'arc 1 -> 3'), + (2, 3, 'arc 2 -> 3'), + (1, 4, 'arc 1 -> 4'), + (4, 5, 'arc 4 -> 5'), + (5, 1, 'arc 5 -> 1'); +ERROR: relation "graph" does not exist +LINE 1: insert into graph values + ^ +with recursive search_graph(f, t, label, path, cycle) as ( + select *, array[row(g.f, g.t)], false from graph g + union all + select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path) + from graph g, search_graph sg + where g.f = sg.t and not cycle +) +select * from search_graph order by path; +ERROR: relation "graph" does not exist +LINE 2: select *, array[row(g.f, g.t)], false from graph g + ^ +-- ordering by the path column has same effect as SEARCH DEPTH FIRST +with recursive search_graph(f, t, label, path, cycle) as ( + select *, array[row(g.f, g.t)], false from graph g + union all + select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path) + from graph g, search_graph sg + where g.f = sg.t and not cycle +) +select * from search_graph order by path; +ERROR: relation "graph" does not exist +LINE 2: select *, array[row(g.f, g.t)], false from graph g + ^ +-- +-- test multiple WITH queries +-- +WITH RECURSIVE + y (id) AS (VALUES (1)), + x (id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5) +SELECT * FROM x ORDER BY id; + id +---- + 1 + 2 + 3 + 4 + 5 +(5 rows) + +-- forward reference OK +WITH RECURSIVE + x(id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5), + y(id) AS (values (1)) + SELECT * FROM x ORDER BY id; + id +---- + 1 + 2 + 3 + 4 + 5 +(5 rows) + +WITH RECURSIVE + x(id) AS + (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5), + y(id) AS + (VALUES (1) UNION ALL SELECT id+1 FROM y WHERE id < 10) + SELECT y.*, x.* FROM y LEFT JOIN x USING (id) ORDER BY 1; + id | id +----+---- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | + 7 | + 8 | + 9 | + 10 | +(10 rows) + +WITH RECURSIVE + x(id) AS + (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5), + y(id) AS + (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 10) + SELECT y.*, x.* FROM y LEFT JOIN x USING (id) ORDER BY 1; + id | id +----+---- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | +(6 rows) + +WITH RECURSIVE + x(id) AS + (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ), + y(id) AS + (SELECT * FROM x UNION ALL SELECT * FROM x), + z(id) AS + (SELECT * FROM x UNION ALL SELECT id+1 FROM z WHERE id < 10) + SELECT * FROM z ORDER BY id; + id +---- + 1 + 2 + 2 + 3 + 3 + 3 + 4 + 4 + 4 + 5 + 5 + 5 + 6 + 6 + 6 + 7 + 7 + 7 + 8 + 8 + 8 + 9 + 9 + 9 + 10 + 10 + 10 +(27 rows) + +WITH RECURSIVE + x(id) AS + (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ), + y(id) AS + (SELECT * FROM x UNION ALL SELECT * FROM x), + z(id) AS + (SELECT * FROM y UNION ALL SELECT id+1 FROM z WHERE id < 10) + SELECT * FROM z ORDER BY id; + id +---- + 1 + 1 + 2 + 2 + 2 + 2 + 3 + 3 + 3 + 3 + 3 + 3 + 4 + 4 + 4 + 4 + 4 + 4 + 5 + 5 + 5 + 5 + 5 + 5 + 6 + 6 + 6 + 6 + 6 + 6 + 7 + 7 + 7 + 7 + 7 + 7 + 8 + 8 + 8 + 8 + 8 + 8 + 9 + 9 + 9 + 9 + 9 + 9 + 10 + 10 + 10 + 10 + 10 + 10 +(54 rows) + +-- +-- error cases +-- +-- INTERSECT +WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x) + SELECT * FROM x; +ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term +LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x... + ^ +WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x) + SELECT * FROM x; +ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term +LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FR... + ^ +-- EXCEPT +WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x) + SELECT * FROM x; +ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term +LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x) + ^ +WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x) + SELECT * FROM x; +ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term +LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM ... + ^ +-- no non-recursive term +WITH RECURSIVE x(n) AS (SELECT n FROM x) + SELECT * FROM x; +ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term +LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x) + ^ +-- recursive term in the left hand side (strictly speaking, should allow this) +WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1) + SELECT * FROM x; +ERROR: recursive reference to query "x" must not appear within its non-recursive term +LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1) + ^ +CREATE TEMPORARY TABLE y (a INTEGER); +ERROR: PG-XC does not yet support temporary tables +INSERT INTO y SELECT generate_series(1, 10); +ERROR: relation "y" does not exist +LINE 1: INSERT INTO y SELECT generate_series(1, 10); + ^ +-- LEFT JOIN +WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1 + UNION ALL + SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10) +SELECT * FROM x; +ERROR: recursive reference to query "x" must not appear within an outer join +LINE 3: SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10) + ^ +-- RIGHT JOIN +WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1 + UNION ALL + SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10) +SELECT * FROM x; +ERROR: recursive reference to query "x" must not appear within an outer join +LINE 3: SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10) + ^ +-- FULL JOIN +WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1 + UNION ALL + SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10) +SELECT * FROM x; +ERROR: recursive reference to query "x" must not appear within an outer join +LINE 3: SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10) + ^ +-- subquery +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x + WHERE n IN (SELECT * FROM x)) + SELECT * FROM x; +ERROR: recursive reference to query "x" must not appear within a subquery +LINE 2: WHERE n IN (SELECT * FROM x)) + ^ +-- aggregate functions +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x) + SELECT * FROM x; +ERROR: aggregate functions not allowed in a recursive query's recursive term +LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) F... + ^ +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x) + SELECT * FROM x; +ERROR: aggregate functions not allowed in a recursive query's recursive term +LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FRO... + ^ +-- ORDER BY +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1) + SELECT * FROM x; +ERROR: ORDER BY in a recursive query is not implemented +LINE 1: ...VE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1) + ^ +-- LIMIT/OFFSET +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1) + SELECT * FROM x; +ERROR: OFFSET in a recursive query is not implemented +LINE 1: ... AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1) + ^ +-- FOR UPDATE +WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE) + SELECT * FROM x; +ERROR: FOR UPDATE/SHARE in a recursive query is not implemented +-- target list has a recursive query name +WITH RECURSIVE x(id) AS (values (1) + UNION ALL + SELECT (SELECT * FROM x) FROM x WHERE id < 5 +) SELECT * FROM x; +ERROR: recursive reference to query "x" must not appear within a subquery +LINE 3: SELECT (SELECT * FROM x) FROM x WHERE id < 5 + ^ +-- mutual recursive query (not implemented) +WITH RECURSIVE + x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id < 5), + y (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 5) +SELECT * FROM x; +ERROR: mutual recursion between WITH items is not implemented +LINE 2: x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id ... + ^ +-- non-linear recursion is not allowed +WITH RECURSIVE foo(i) AS + (values (1) + UNION ALL + (SELECT i+1 FROM foo WHERE i < 10 + UNION ALL + SELECT i+1 FROM foo WHERE i < 5) +) SELECT * FROM foo; +ERROR: recursive reference to query "foo" must not appear more than once +LINE 6: SELECT i+1 FROM foo WHERE i < 5) + ^ +WITH RECURSIVE foo(i) AS + (values (1) + UNION ALL + SELECT * FROM + (SELECT i+1 FROM foo WHERE i < 10 + UNION ALL + SELECT i+1 FROM foo WHERE i < 5) AS t +) SELECT * FROM foo; +ERROR: recursive reference to query "foo" must not appear more than once +LINE 7: SELECT i+1 FROM foo WHERE i < 5) AS t + ^ +WITH RECURSIVE foo(i) AS + (values (1) + UNION ALL + (SELECT i+1 FROM foo WHERE i < 10 + EXCEPT + SELECT i+1 FROM foo WHERE i < 5) +) SELECT * FROM foo; +ERROR: recursive reference to query "foo" must not appear within EXCEPT +LINE 6: SELECT i+1 FROM foo WHERE i < 5) + ^ +WITH RECURSIVE foo(i) AS + (values (1) + UNION ALL + (SELECT i+1 FROM foo WHERE i < 10 + INTERSECT + SELECT i+1 FROM foo WHERE i < 5) +) SELECT * FROM foo; +ERROR: recursive reference to query "foo" must not appear more than once +LINE 6: SELECT i+1 FROM foo WHERE i < 5) + ^ +-- Wrong type induced from non-recursive term +WITH RECURSIVE foo(i) AS + (SELECT i FROM (VALUES(1),(2)) t(i) + UNION ALL + SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10) +SELECT * FROM foo; +ERROR: recursive query "foo" column 1 has type integer in non-recursive term but type numeric overall +LINE 2: (SELECT i FROM (VALUES(1),(2)) t(i) + ^ +HINT: Cast the output of the non-recursive term to the correct type. +-- rejects different typmod, too (should we allow this?) +WITH RECURSIVE foo(i) AS + (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i) + UNION ALL + SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10) +SELECT * FROM foo; +ERROR: recursive query "foo" column 1 has type numeric(3,0) in non-recursive term but type numeric overall +LINE 2: (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i) + ^ +HINT: Cast the output of the non-recursive term to the correct type. +-- +-- test for bug #4902 +-- +with cte(foo) as ( values(42) ) values((select foo from cte)); + column1 +--------- + 42 +(1 row) + +with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q; + foo +----- + 42 +(1 row) + +-- test CTE referencing an outer-level variable (to see that changed-parameter +-- signaling still works properly after fixing this bug) +select ( with cte(foo) as ( values(f1) ) + select (select foo from cte) ) +from int4_tbl order by 1; + ?column? +------------- + -2147483647 + -123456 + 0 + 123456 + 2147483647 +(5 rows) + +select ( with cte(foo) as ( values(f1) ) + values((select foo from cte)) ) +from int4_tbl order by 1; + ?column? +------------- + -2147483647 + -123456 + 0 + 123456 + 2147483647 +(5 rows) + +-- +-- test for nested-recursive-WITH bug +-- +WITH RECURSIVE t(j) AS ( + WITH RECURSIVE s(i) AS ( + VALUES (1) + UNION ALL + SELECT i+1 FROM s WHERE i < 10 + ) + SELECT i FROM s + UNION ALL + SELECT j+1 FROM t WHERE j < 10 +) +SELECT * FROM t order by 1; + j +---- + 1 + 2 + 2 + 3 + 3 + 3 + 4 + 4 + 4 + 4 + 5 + 5 + 5 + 5 + 5 + 6 + 6 + 6 + 6 + 6 + 6 + 7 + 7 + 7 + 7 + 7 + 7 + 7 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 9 + 9 + 9 + 9 + 9 + 9 + 9 + 9 + 9 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 +(55 rows) + diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql index e40d90d..687c035 100644 --- a/src/test/regress/sql/with.sql +++ b/src/test/regress/sql/with.sql @@ -43,14 +43,14 @@ WITH RECURSIVE t(n) AS ( VALUES (1) UNION ALL SELECT n+1 FROM t) -SELECT * FROM t LIMIT 10 ; +SELECT * FROM t LIMIT 10; -- UNION case should have same property WITH RECURSIVE t(n) AS ( SELECT 1 UNION SELECT n+1 FROM t) -SELECT * FROM t LIMIT 10; +SELECT * FROM t LIMIT 10; -- Test behavior with an unknown-type literal in the WITH WITH q AS (SELECT 'foo' AS x) ----------------------------------------------------------------------- Summary of changes: src/test/regress/expected/{with.out => with_1.out} | 317 +++++-------------- src/test/regress/sql/with.sql | 4 +- 2 files changed, 86 insertions(+), 235 deletions(-) copy src/test/regress/expected/{with.out => with_1.out} (65%) hooks/post-receive -- Postgres-XC |
From: Pavan D. <pa...@us...> - 2011-04-19 05:51:25
|
Project "Postgres-XC". The branch, master has been updated via e12ca2d640d6c9d09aefeb05bbce1fba01e9549a (commit) from e734d31c84a0a557bdfb172ee097a4b46d3868a7 (commit) - Log ----------------------------------------------------------------- commit e12ca2d640d6c9d09aefeb05bbce1fba01e9549a Author: Pavan Deolasee <pav...@gm...> Date: Tue Apr 19 11:18:59 2011 +0530 Fix a bug where we had used a assignment operator instead of a comparison diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c index 700268a..06c971e 100644 --- a/src/backend/pgxc/pool/execRemote.c +++ b/src/backend/pgxc/pool/execRemote.c @@ -1258,7 +1258,7 @@ FetchTuple(RemoteQueryState *combiner, TupleTableSlot *slot) else combiner->current_conn = 0; } - else if (res = RESPONSE_DATAROW && have_tuple) + else if (res == RESPONSE_DATAROW && have_tuple) { /* * We already have a tuple and received another one, leave it till ----------------------------------------------------------------------- Summary of changes: src/backend/pgxc/pool/execRemote.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) hooks/post-receive -- Postgres-XC |
From: Pavan D. <pa...@us...> - 2011-04-19 05:10:44
|
Project "Postgres-XC". The branch, pgxc-barrier has been updated via 1e74fe24bd50b8e1c8244e2e8f999e10964484dd (commit) from df86ba5f78e6f0a350a229ef565536ca4b5826f8 (commit) - Log ----------------------------------------------------------------- commit 1e74fe24bd50b8e1c8244e2e8f999e10964484dd Author: Pavan Deolasee <pav...@gm...> Date: Mon Apr 18 13:41:47 2011 +0530 Add synchrnization at the commit time diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c index 849f36b..b07753f 100644 --- a/src/backend/pgxc/pool/execRemote.c +++ b/src/backend/pgxc/pool/execRemote.c @@ -17,6 +17,7 @@ #include <time.h> #include "postgres.h" +#include "access/twophase.h" #include "access/gtm.h" #include "access/xact.h" #include "catalog/pg_type.h" @@ -1834,9 +1835,23 @@ PGXCNodeImplicitCommitPrepared(GlobalTransactionId prepare_xid, goto finish; } + /* + * Barrier: + * + * We should acquire the BarrierLock in SHARE mode here to ensure that + * there are no in-progress barrier at this point. This mechanism would + * work as long as LWLock mechanism does not starve a EXCLUSIVE lock + * requesster + */ + LWLockAcquire(BarrierLock, LW_SHARED); res = pgxc_node_implicit_commit_prepared(prepare_xid, commit_xid, pgxc_connections, gid, is_commit); + /* + * Release the BarrierLock. + */ + LWLockRelease(BarrierLock); + finish: /* Clear nodes, signals are clear */ if (!autocommit) @@ -1920,8 +1935,8 @@ finish: * or not but send the message to all of them. * This avoid to have any additional interaction with GTM when making a 2PC transaction. */ -bool -PGXCNodeCommitPrepared(char *gid) +void +PGXCNodeCommitPrepared(char *gid, bool isTopLevel) { int res = 0; int res_gtm = 0; @@ -1971,7 +1986,15 @@ PGXCNodeCommitPrepared(char *gid) /* * Commit here the prepared transaction to all Datanodes and Coordinators * If necessary, local Coordinator Commit is performed after this DataNodeCommitPrepared. + * + * BARRIER: + * + * Take the BarrierLock in SHARE mode to synchronize on in-progress + * barriers. We should hold on to the lock until the local prepared + * transaction is also committed */ + LWLockAcquire(BarrierLock, LW_SHARED); + res = pgxc_node_commit_prepared(gxid, prepared_gxid, pgxc_handles, gid); finish: @@ -1991,16 +2014,34 @@ finish: free(coordinators); pfree_pgxc_all_handles(pgxc_handles); + if (res_gtm < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("Could not get GID data from GTM"))); + if (res != 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("Could not commit prepared transaction on data nodes"))); - return operation_local; + /* + * A local Coordinator always commits if involved in Prepare. + * 2PC file is created and flushed if a DDL has been involved in the transaction. + * If remote connection is a Coordinator type, the commit prepared has to be done locally + * if and only if the Coordinator number was in the node list received from GTM. + */ + if (operation_local || IsConnFromCoord()) + { + PreventTransactionChain(isTopLevel, "COMMIT PREPARED"); + FinishPreparedTransaction(gid, true); + } + + /* + * Release the barrier lock now so that pending barriers can get moving + */ + LWLockRelease(BarrierLock); + return; } /* @@ -2045,11 +2086,9 @@ finish: /* * Rollback prepared transaction on Datanodes involved in the current transaction - * - * Return whether or not a local operation required. */ -bool -PGXCNodeRollbackPrepared(char *gid) +void +PGXCNodeRollbackPrepared(char *gid, bool isTopLevel) { int res = 0; int res_gtm = 0; @@ -2122,7 +2161,17 @@ finish: (errcode(ERRCODE_INTERNAL_ERROR), errmsg("Could not rollback prepared transaction on Datanodes"))); - return operation_local; + /* + * Local coordinator rollbacks if involved in PREPARE + * If remote connection is a Coordinator type, the commit prepared has to be done locally also. + * This works for both Datanodes and Coordinators. + */ + if (operation_local || IsConnFromCoord()) + { + PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED"); + FinishPreparedTransaction(gid, false); + } + return; } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index bd13ce3..6b3c138 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -400,22 +400,10 @@ ProcessUtility(Node *parsetree, * Don't send it down to Datanodes. */ if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) - operation_local = PGXCNodeCommitPrepared(stmt->gid); -#endif + PGXCNodeCommitPrepared(stmt->gid, isTopLevel); +#else PreventTransactionChain(isTopLevel, "COMMIT PREPARED"); -#ifdef PGXC - /* - * A local Coordinator always commits if involved in Prepare. - * 2PC file is created and flushed if a DDL has been involved in the transaction. - * If remote connection is a Coordinator type, the commit prepared has to be done locally - * if and only if the Coordinator number was in the node list received from GTM. - */ - if (operation_local || IsConnFromCoord()) - { -#endif FinishPreparedTransaction(stmt->gid, true); -#ifdef PGXC - } #endif break; @@ -426,21 +414,10 @@ ProcessUtility(Node *parsetree, * Don't send it down to Datanodes. */ if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) - operation_local = PGXCNodeRollbackPrepared(stmt->gid); -#endif + PGXCNodeRollbackPrepared(stmt->gid, isTopLevel); +#else PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED"); -#ifdef PGXC - /* - * Local coordinator rollbacks if involved in PREPARE - * If remote connection is a Coordinator type, the commit prepared has to be done locally also. - * This works for both Datanodes and Coordinators. - */ - if (operation_local || IsConnFromCoord()) - { -#endif - FinishPreparedTransaction(stmt->gid, false); -#ifdef PGXC - } + FinishPreparedTransaction(gid, false); #endif break; diff --git a/src/include/pgxc/execRemote.h b/src/include/pgxc/execRemote.h index e9f000f..a50c40c 100644 --- a/src/include/pgxc/execRemote.h +++ b/src/include/pgxc/execRemote.h @@ -120,8 +120,8 @@ extern void PGXCNodeBegin(void); extern void PGXCNodeCommit(void); extern int PGXCNodeRollback(void); extern bool PGXCNodePrepare(char *gid); -extern bool PGXCNodeRollbackPrepared(char *gid); -extern bool PGXCNodeCommitPrepared(char *gid); +extern void PGXCNodeRollbackPrepared(char *gid, bool isTopLevel); +extern void PGXCNodeCommitPrepared(char *gid, bool isTopLevel); extern bool PGXCNodeIsImplicit2PC(bool *prepare_local_coord); extern int PGXCNodeImplicitPrepare(GlobalTransactionId prepare_xid, char *gid); extern void PGXCNodeImplicitCommitPrepared(GlobalTransactionId prepare_xid, ----------------------------------------------------------------------- Summary of changes: src/backend/pgxc/pool/execRemote.c | 65 +++++++++++++++++++++++++++++++---- src/backend/tcop/utility.c | 33 +++--------------- src/include/pgxc/execRemote.h | 4 +- 3 files changed, 64 insertions(+), 38 deletions(-) hooks/post-receive -- Postgres-XC |