Commit 41de93c5 authored by Tom Lane's avatar Tom Lane

Reduce indentation/parenthesization of set operations in rule/view dumps.

A query such as "SELECT x UNION SELECT y UNION SELECT z UNION ..."
produces a left-deep nested parse tree, which we formerly showed in its
full nested glory and with all the possible parentheses.  This does little
for readability, though, and long UNION lists resulting in excessive
indentation are common.  Instead, let's omit parentheses and indent all
the subqueries at the same level in such cases.

This patch skips indentation/parenthesization whenever the lefthand input
of a SetOperationStmt is another SetOperationStmt of the same kind and
ALL/DISTINCT property.  We could teach the code the exact syntactic
precedence of set operations and thereby avoid parenthesization in some
more cases, but it's not clear that that'd be a readability win: it seems
better to parenthesize if the set operation changes.  (As an example,
if there's one UNION in a long list of UNION ALL, it now stands out like
a sore thumb, which seems like a good thing.)

Back-patch to 9.3.  This completes our response to a complaint from Greg
Stark that since commit 62e66640 there's a performance problem in pg_dump
for views containing long UNION sequences (or other types of deeply nested
constructs).  The previous commit 0601cb54
handles the general problem, but this one makes the specific case of UNION
lists look a lot nicer.
parent 0601cb54
...@@ -4714,42 +4714,59 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context, ...@@ -4714,42 +4714,59 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context,
else if (IsA(setOp, SetOperationStmt)) else if (IsA(setOp, SetOperationStmt))
{ {
SetOperationStmt *op = (SetOperationStmt *) setOp; SetOperationStmt *op = (SetOperationStmt *) setOp;
int subindent;
if (PRETTY_INDENT(context))
{
context->indentLevel += PRETTYINDENT_STD;
appendStringInfoSpaces(buf, PRETTYINDENT_STD);
}
/* /*
* We force parens whenever nesting two SetOperationStmts. There are * We force parens when nesting two SetOperationStmts, except when the
* some cases in which parens are needed around a leaf query too, but * lefthand input is another setop of the same kind. Syntactically,
* those are more easily handled at the next level down (see code * we could omit parens in rather more cases, but it seems best to use
* above). * parens to flag cases where the setop operator changes. If we use
* parens, we also increase the indentation level for the child query.
*
* There are some cases in which parens are needed around a leaf query
* too, but those are more easily handled at the next level down (see
* code above).
*/ */
need_paren = !IsA(op->larg, RangeTblRef); if (IsA(op->larg, SetOperationStmt))
{
SetOperationStmt *lop = (SetOperationStmt *) op->larg;
if (op->op == lop->op && op->all == lop->all)
need_paren = false;
else
need_paren = true;
}
else
need_paren = false;
if (need_paren) if (need_paren)
{
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
subindent = PRETTYINDENT_STD;
appendContextKeyword(context, "", subindent, 0, 0);
}
else
subindent = 0;
get_setop_query(op->larg, query, context, resultDesc); get_setop_query(op->larg, query, context, resultDesc);
if (need_paren)
appendStringInfoChar(buf, ')');
if (!PRETTY_INDENT(context)) if (need_paren)
appendContextKeyword(context, ") ", -subindent, 0, 0);
else if (PRETTY_INDENT(context))
appendContextKeyword(context, "", -subindent, 0, 0);
else
appendStringInfoChar(buf, ' '); appendStringInfoChar(buf, ' ');
switch (op->op) switch (op->op)
{ {
case SETOP_UNION: case SETOP_UNION:
appendContextKeyword(context, "UNION ", appendStringInfoString(buf, "UNION ");
-PRETTYINDENT_STD, PRETTYINDENT_STD, 0);
break; break;
case SETOP_INTERSECT: case SETOP_INTERSECT:
appendContextKeyword(context, "INTERSECT ", appendStringInfoString(buf, "INTERSECT ");
-PRETTYINDENT_STD, PRETTYINDENT_STD, 0);
break; break;
case SETOP_EXCEPT: case SETOP_EXCEPT:
appendContextKeyword(context, "EXCEPT ", appendStringInfoString(buf, "EXCEPT ");
-PRETTYINDENT_STD, PRETTYINDENT_STD, 0);
break; break;
default: default:
elog(ERROR, "unrecognized set op: %d", elog(ERROR, "unrecognized set op: %d",
...@@ -4758,19 +4775,29 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context, ...@@ -4758,19 +4775,29 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context,
if (op->all) if (op->all)
appendStringInfoString(buf, "ALL "); appendStringInfoString(buf, "ALL ");
if (PRETTY_INDENT(context)) /* Always parenthesize if RHS is another setop */
appendContextKeyword(context, "", 0, 0, 0); need_paren = IsA(op->rarg, SetOperationStmt);
need_paren = !IsA(op->rarg, RangeTblRef);
/*
* The indentation code here is deliberately a bit different from that
* for the lefthand input, because we want the line breaks in
* different places.
*/
if (need_paren) if (need_paren)
{
appendStringInfoChar(buf, '('); appendStringInfoChar(buf, '(');
subindent = PRETTYINDENT_STD;
}
else
subindent = 0;
appendContextKeyword(context, "", subindent, 0, 0);
get_setop_query(op->rarg, query, context, resultDesc); get_setop_query(op->rarg, query, context, resultDesc);
if (need_paren)
appendStringInfoChar(buf, ')');
if (PRETTY_INDENT(context)) if (PRETTY_INDENT(context))
context->indentLevel -= PRETTYINDENT_STD; context->indentLevel -= subindent;
if (need_paren)
appendContextKeyword(context, ")", 0, 0, 0);
} }
else else
{ {
......
...@@ -1090,23 +1090,23 @@ select * from (values(1,2,3,4,5)) v(a,b,c,d,e) ...@@ -1090,23 +1090,23 @@ select * from (values(1,2,3,4,5)) v(a,b,c,d,e)
union all union all
select * from tt7 full join tt8 using (x), tt8 tt8x; select * from tt7 full join tt8 using (x), tt8 tt8x;
select pg_get_viewdef('vv2', true); select pg_get_viewdef('vv2', true);
pg_get_viewdef pg_get_viewdef
-------------------------------------------------------- ------------------------------------------------
SELECT v.a, + SELECT v.a, +
v.b, + v.b, +
v.c, + v.c, +
v.d, + v.d, +
v.e + v.e +
FROM ( VALUES (1,2,3,4,5)) v(a, b, c, d, e)+ FROM ( VALUES (1,2,3,4,5)) v(a, b, c, d, e)+
UNION ALL + UNION ALL +
SELECT x AS a, + SELECT x AS a, +
tt7.y AS b, + tt7.y AS b, +
tt8.z AS c, + tt8.z AS c, +
tt8x.x_1 AS d, + tt8x.x_1 AS d, +
tt8x.z AS e + tt8x.z AS e +
FROM tt7 + FROM tt7 +
FULL JOIN tt8 USING (x), + FULL JOIN tt8 USING (x), +
tt8 tt8x(x_1, z); tt8 tt8x(x_1, z);
(1 row) (1 row)
create view vv3 as create view vv3 as
...@@ -1116,26 +1116,26 @@ select * from ...@@ -1116,26 +1116,26 @@ select * from
tt7 full join tt8 using (x), tt7 full join tt8 using (x),
tt7 tt7x full join tt8 tt8x using (x); tt7 tt7x full join tt8 tt8x using (x);
select pg_get_viewdef('vv3', true); select pg_get_viewdef('vv3', true);
pg_get_viewdef pg_get_viewdef
------------------------------------------------------------- -----------------------------------------------------
SELECT v.a, + SELECT v.a, +
v.b, + v.b, +
v.c, + v.c, +
v.x, + v.x, +
v.e, + v.e, +
v.f + v.f +
FROM ( VALUES (1,2,3,4,5,6)) v(a, b, c, x, e, f)+ FROM ( VALUES (1,2,3,4,5,6)) v(a, b, c, x, e, f)+
UNION ALL + UNION ALL +
SELECT x AS a, + SELECT x AS a, +
tt7.y AS b, + tt7.y AS b, +
tt8.z AS c, + tt8.z AS c, +
x_1 AS x, + x_1 AS x, +
tt7x.y AS e, + tt7x.y AS e, +
tt8x.z AS f + tt8x.z AS f +
FROM tt7 + FROM tt7 +
FULL JOIN tt8 USING (x), + FULL JOIN tt8 USING (x), +
tt7 tt7x(x_1, y) + tt7 tt7x(x_1, y) +
FULL JOIN tt8 tt8x(x_1, z) USING (x_1); FULL JOIN tt8 tt8x(x_1, z) USING (x_1);
(1 row) (1 row)
create view vv4 as create view vv4 as
...@@ -1145,29 +1145,29 @@ select * from ...@@ -1145,29 +1145,29 @@ select * from
tt7 full join tt8 using (x), tt7 full join tt8 using (x),
tt7 tt7x full join tt8 tt8x using (x) full join tt8 tt8y using (x); tt7 tt7x full join tt8 tt8x using (x) full join tt8 tt8y using (x);
select pg_get_viewdef('vv4', true); select pg_get_viewdef('vv4', true);
pg_get_viewdef pg_get_viewdef
------------------------------------------------------------------ ----------------------------------------------------------
SELECT v.a, + SELECT v.a, +
v.b, + v.b, +
v.c, + v.c, +
v.x, + v.x, +
v.e, + v.e, +
v.f, + v.f, +
v.g + v.g +
FROM ( VALUES (1,2,3,4,5,6,7)) v(a, b, c, x, e, f, g)+ FROM ( VALUES (1,2,3,4,5,6,7)) v(a, b, c, x, e, f, g)+
UNION ALL + UNION ALL +
SELECT x AS a, + SELECT x AS a, +
tt7.y AS b, + tt7.y AS b, +
tt8.z AS c, + tt8.z AS c, +
x_1 AS x, + x_1 AS x, +
tt7x.y AS e, + tt7x.y AS e, +
tt8x.z AS f, + tt8x.z AS f, +
tt8y.z AS g + tt8y.z AS g +
FROM tt7 + FROM tt7 +
FULL JOIN tt8 USING (x), + FULL JOIN tt8 USING (x), +
tt7 tt7x(x_1, y) + tt7 tt7x(x_1, y) +
FULL JOIN tt8 tt8x(x_1, z) USING (x_1) + FULL JOIN tt8 tt8x(x_1, z) USING (x_1) +
FULL JOIN tt8 tt8y(x_1, z) USING (x_1); FULL JOIN tt8 tt8y(x_1, z) USING (x_1);
(1 row) (1 row)
alter table tt7 add column zz int; alter table tt7 add column zz int;
...@@ -1175,72 +1175,72 @@ alter table tt7 add column z int; ...@@ -1175,72 +1175,72 @@ alter table tt7 add column z int;
alter table tt7 drop column zz; alter table tt7 drop column zz;
alter table tt8 add column z2 int; alter table tt8 add column z2 int;
select pg_get_viewdef('vv2', true); select pg_get_viewdef('vv2', true);
pg_get_viewdef pg_get_viewdef
-------------------------------------------------------- ------------------------------------------------
SELECT v.a, + SELECT v.a, +
v.b, + v.b, +
v.c, + v.c, +
v.d, + v.d, +
v.e + v.e +
FROM ( VALUES (1,2,3,4,5)) v(a, b, c, d, e)+ FROM ( VALUES (1,2,3,4,5)) v(a, b, c, d, e)+
UNION ALL + UNION ALL +
SELECT x AS a, + SELECT x AS a, +
tt7.y AS b, + tt7.y AS b, +
tt8.z AS c, + tt8.z AS c, +
tt8x.x_1 AS d, + tt8x.x_1 AS d, +
tt8x.z AS e + tt8x.z AS e +
FROM tt7 + FROM tt7 +
FULL JOIN tt8 USING (x), + FULL JOIN tt8 USING (x), +
tt8 tt8x(x_1, z, z2); tt8 tt8x(x_1, z, z2);
(1 row) (1 row)
select pg_get_viewdef('vv3', true); select pg_get_viewdef('vv3', true);
pg_get_viewdef pg_get_viewdef
------------------------------------------------------------- -----------------------------------------------------
SELECT v.a, + SELECT v.a, +
v.b, + v.b, +
v.c, + v.c, +
v.x, + v.x, +
v.e, + v.e, +
v.f + v.f +
FROM ( VALUES (1,2,3,4,5,6)) v(a, b, c, x, e, f)+ FROM ( VALUES (1,2,3,4,5,6)) v(a, b, c, x, e, f)+
UNION ALL + UNION ALL +
SELECT x AS a, + SELECT x AS a, +
tt7.y AS b, + tt7.y AS b, +
tt8.z AS c, + tt8.z AS c, +
x_1 AS x, + x_1 AS x, +
tt7x.y AS e, + tt7x.y AS e, +
tt8x.z AS f + tt8x.z AS f +
FROM tt7 + FROM tt7 +
FULL JOIN tt8 USING (x), + FULL JOIN tt8 USING (x), +
tt7 tt7x(x_1, y, z) + tt7 tt7x(x_1, y, z) +
FULL JOIN tt8 tt8x(x_1, z, z2) USING (x_1); FULL JOIN tt8 tt8x(x_1, z, z2) USING (x_1);
(1 row) (1 row)
select pg_get_viewdef('vv4', true); select pg_get_viewdef('vv4', true);
pg_get_viewdef pg_get_viewdef
------------------------------------------------------------------ ----------------------------------------------------------
SELECT v.a, + SELECT v.a, +
v.b, + v.b, +
v.c, + v.c, +
v.x, + v.x, +
v.e, + v.e, +
v.f, + v.f, +
v.g + v.g +
FROM ( VALUES (1,2,3,4,5,6,7)) v(a, b, c, x, e, f, g)+ FROM ( VALUES (1,2,3,4,5,6,7)) v(a, b, c, x, e, f, g)+
UNION ALL + UNION ALL +
SELECT x AS a, + SELECT x AS a, +
tt7.y AS b, + tt7.y AS b, +
tt8.z AS c, + tt8.z AS c, +
x_1 AS x, + x_1 AS x, +
tt7x.y AS e, + tt7x.y AS e, +
tt8x.z AS f, + tt8x.z AS f, +
tt8y.z AS g + tt8y.z AS g +
FROM tt7 + FROM tt7 +
FULL JOIN tt8 USING (x), + FULL JOIN tt8 USING (x), +
tt7 tt7x(x_1, y, z) + tt7 tt7x(x_1, y, z) +
FULL JOIN tt8 tt8x(x_1, z, z2) USING (x_1) + FULL JOIN tt8 tt8x(x_1, z, z2) USING (x_1) +
FULL JOIN tt8 tt8y(x_1, z, z2) USING (x_1); FULL JOIN tt8 tt8y(x_1, z, z2) USING (x_1);
(1 row) (1 row)
-- Implicit coercions in a JOIN USING create issues similar to FULL JOIN -- Implicit coercions in a JOIN USING create issues similar to FULL JOIN
...@@ -1252,23 +1252,23 @@ select * from (values(now(),2,3,now(),5)) v(a,b,c,d,e) ...@@ -1252,23 +1252,23 @@ select * from (values(now(),2,3,now(),5)) v(a,b,c,d,e)
union all union all
select * from tt7a left join tt8a using (x), tt8a tt8ax; select * from tt7a left join tt8a using (x), tt8a tt8ax;
select pg_get_viewdef('vv2a', true); select pg_get_viewdef('vv2a', true);
pg_get_viewdef pg_get_viewdef
---------------------------------------------------------------- --------------------------------------------------------
SELECT v.a, + SELECT v.a, +
v.b, + v.b, +
v.c, + v.c, +
v.d, + v.d, +
v.e + v.e +
FROM ( VALUES (now(),2,3,now(),5)) v(a, b, c, d, e)+ FROM ( VALUES (now(),2,3,now(),5)) v(a, b, c, d, e)+
UNION ALL + UNION ALL +
SELECT x AS a, + SELECT x AS a, +
tt7a.y AS b, + tt7a.y AS b, +
tt8a.z AS c, + tt8a.z AS c, +
tt8ax.x_1 AS d, + tt8ax.x_1 AS d, +
tt8ax.z AS e + tt8ax.z AS e +
FROM tt7a + FROM tt7a +
LEFT JOIN tt8a USING (x), + LEFT JOIN tt8a USING (x), +
tt8a tt8ax(x_1, z); tt8a tt8ax(x_1, z);
(1 row) (1 row)
-- --
......
...@@ -346,13 +346,13 @@ CREATE VIEW v_test2 AS SELECT moo, 2*moo FROM v_test1 UNION ALL SELECT moo, 3*mo ...@@ -346,13 +346,13 @@ CREATE VIEW v_test2 AS SELECT moo, 2*moo FROM v_test1 UNION ALL SELECT moo, 3*mo
moo | integer | | plain | moo | integer | | plain |
?column? | integer | | plain | ?column? | integer | | plain |
View definition: View definition:
SELECT v_test1.moo, SELECT v_test1.moo,
2 * v_test1.moo 2 * v_test1.moo
FROM v_test1 FROM v_test1
UNION ALL UNION ALL
SELECT v_test1.moo, SELECT v_test1.moo,
3 * v_test1.moo 3 * v_test1.moo
FROM v_test1; FROM v_test1;
CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM v_test2 UNION ALL SELECT moo, 3*moo FROM v_test2; CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM v_test2 UNION ALL SELECT moo, 3*moo FROM v_test2;
\d+ mv_test2 \d+ mv_test2
...@@ -362,13 +362,13 @@ CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM v_test2 UNION ALL SE ...@@ -362,13 +362,13 @@ CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM v_test2 UNION ALL SE
moo | integer | | plain | | moo | integer | | plain | |
?column? | integer | | plain | | ?column? | integer | | plain | |
View definition: View definition:
SELECT v_test2.moo, SELECT v_test2.moo,
2 * v_test2.moo 2 * v_test2.moo
FROM v_test2 FROM v_test2
UNION ALL UNION ALL
SELECT v_test2.moo, SELECT v_test2.moo,
3 * v_test2.moo 3 * v_test2.moo
FROM v_test2; FROM v_test2;
CREATE MATERIALIZED VIEW mv_test3 AS SELECT * FROM mv_test2 WHERE moo = 12345; CREATE MATERIALIZED VIEW mv_test3 AS SELECT * FROM mv_test2 WHERE moo = 12345;
SELECT relispopulated FROM pg_class WHERE oid = 'mv_test3'::regclass; SELECT relispopulated FROM pg_class WHERE oid = 'mv_test3'::regclass;
......
...@@ -1401,111 +1401,111 @@ pg_rules| SELECT n.nspname AS schemaname, ...@@ -1401,111 +1401,111 @@ pg_rules| SELECT n.nspname AS schemaname,
JOIN pg_class c ON ((c.oid = r.ev_class))) JOIN pg_class c ON ((c.oid = r.ev_class)))
LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
WHERE (r.rulename <> '_RETURN'::name); WHERE (r.rulename <> '_RETURN'::name);
pg_seclabels| ( ( ( ( ( ( ( ( ( SELECT l.objoid, pg_seclabels| SELECT l.objoid,
l.classoid, l.classoid,
l.objsubid, l.objsubid,
CASE
WHEN (rel.relkind = 'r'::"char") THEN 'table'::text
WHEN (rel.relkind = 'v'::"char") THEN 'view'::text
WHEN (rel.relkind = 'm'::"char") THEN 'materialized view'::text
WHEN (rel.relkind = 'S'::"char") THEN 'sequence'::text
WHEN (rel.relkind = 'f'::"char") THEN 'foreign table'::text
ELSE NULL::text
END AS objtype,
rel.relnamespace AS objnamespace,
CASE
WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text)
ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text))
END AS objname,
l.provider,
l.label
FROM ((pg_seclabel l
JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid))))
JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid)))
WHERE (l.objsubid = 0)
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
'column'::text AS objtype,
rel.relnamespace AS objnamespace,
((
CASE
WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text)
ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text))
END || '.'::text) || (att.attname)::text) AS objname,
l.provider,
l.label
FROM (((pg_seclabel l
JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid))))
JOIN pg_attribute att ON (((rel.oid = att.attrelid) AND (l.objsubid = att.attnum))))
JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid)))
WHERE (l.objsubid <> 0))
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
CASE
WHEN (pro.proisagg = true) THEN 'aggregate'::text
WHEN (pro.proisagg = false) THEN 'function'::text
ELSE NULL::text
END AS objtype,
pro.pronamespace AS objnamespace,
(((
CASE
WHEN pg_function_is_visible(pro.oid) THEN quote_ident((pro.proname)::text)
ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((pro.proname)::text))
END || '('::text) || pg_get_function_arguments(pro.oid)) || ')'::text) AS objname,
l.provider,
l.label
FROM ((pg_seclabel l
JOIN pg_proc pro ON (((l.classoid = pro.tableoid) AND (l.objoid = pro.oid))))
JOIN pg_namespace nsp ON ((pro.pronamespace = nsp.oid)))
WHERE (l.objsubid = 0))
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
CASE CASE
WHEN (typ.typtype = 'd'::"char") THEN 'domain'::text WHEN (rel.relkind = 'r'::"char") THEN 'table'::text
ELSE 'type'::text WHEN (rel.relkind = 'v'::"char") THEN 'view'::text
WHEN (rel.relkind = 'm'::"char") THEN 'materialized view'::text
WHEN (rel.relkind = 'S'::"char") THEN 'sequence'::text
WHEN (rel.relkind = 'f'::"char") THEN 'foreign table'::text
ELSE NULL::text
END AS objtype, END AS objtype,
typ.typnamespace AS objnamespace, rel.relnamespace AS objnamespace,
CASE CASE
WHEN pg_type_is_visible(typ.oid) THEN quote_ident((typ.typname)::text) WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text)
ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((typ.typname)::text)) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text))
END AS objname, END AS objname,
l.provider, l.provider,
l.label l.label
FROM ((pg_seclabel l FROM ((pg_seclabel l
JOIN pg_type typ ON (((l.classoid = typ.tableoid) AND (l.objoid = typ.oid)))) JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid))))
JOIN pg_namespace nsp ON ((typ.typnamespace = nsp.oid))) JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid)))
WHERE (l.objsubid = 0)) WHERE (l.objsubid = 0)
UNION ALL UNION ALL
SELECT l.objoid, SELECT l.objoid,
l.classoid, l.classoid,
l.objsubid, l.objsubid,
'large object'::text AS objtype, 'column'::text AS objtype,
NULL::oid AS objnamespace, rel.relnamespace AS objnamespace,
(l.objoid)::text AS objname, ((
l.provider, CASE
l.label WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text)
FROM (pg_seclabel l ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text))
JOIN pg_largeobject_metadata lom ON ((l.objoid = lom.oid))) END || '.'::text) || (att.attname)::text) AS objname,
WHERE ((l.classoid = ('pg_largeobject'::regclass)::oid) AND (l.objsubid = 0))) l.provider,
l.label
FROM (((pg_seclabel l
JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid))))
JOIN pg_attribute att ON (((rel.oid = att.attrelid) AND (l.objsubid = att.attnum))))
JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid)))
WHERE (l.objsubid <> 0)
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
CASE
WHEN (pro.proisagg = true) THEN 'aggregate'::text
WHEN (pro.proisagg = false) THEN 'function'::text
ELSE NULL::text
END AS objtype,
pro.pronamespace AS objnamespace,
(((
CASE
WHEN pg_function_is_visible(pro.oid) THEN quote_ident((pro.proname)::text)
ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((pro.proname)::text))
END || '('::text) || pg_get_function_arguments(pro.oid)) || ')'::text) AS objname,
l.provider,
l.label
FROM ((pg_seclabel l
JOIN pg_proc pro ON (((l.classoid = pro.tableoid) AND (l.objoid = pro.oid))))
JOIN pg_namespace nsp ON ((pro.pronamespace = nsp.oid)))
WHERE (l.objsubid = 0)
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
CASE
WHEN (typ.typtype = 'd'::"char") THEN 'domain'::text
ELSE 'type'::text
END AS objtype,
typ.typnamespace AS objnamespace,
CASE
WHEN pg_type_is_visible(typ.oid) THEN quote_ident((typ.typname)::text)
ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((typ.typname)::text))
END AS objname,
l.provider,
l.label
FROM ((pg_seclabel l
JOIN pg_type typ ON (((l.classoid = typ.tableoid) AND (l.objoid = typ.oid))))
JOIN pg_namespace nsp ON ((typ.typnamespace = nsp.oid)))
WHERE (l.objsubid = 0)
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
'large object'::text AS objtype,
NULL::oid AS objnamespace,
(l.objoid)::text AS objname,
l.provider,
l.label
FROM (pg_seclabel l
JOIN pg_largeobject_metadata lom ON ((l.objoid = lom.oid)))
WHERE ((l.classoid = ('pg_largeobject'::regclass)::oid) AND (l.objsubid = 0))
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
'language'::text AS objtype,
NULL::oid AS objnamespace,
quote_ident((lan.lanname)::text) AS objname,
l.provider,
l.label
FROM (pg_seclabel l
JOIN pg_language lan ON (((l.classoid = lan.tableoid) AND (l.objoid = lan.oid))))
WHERE (l.objsubid = 0)
UNION ALL UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
'language'::text AS objtype,
NULL::oid AS objnamespace,
quote_ident((lan.lanname)::text) AS objname,
l.provider,
l.label
FROM (pg_seclabel l
JOIN pg_language lan ON (((l.classoid = lan.tableoid) AND (l.objoid = lan.oid))))
WHERE (l.objsubid = 0))
UNION ALL
SELECT l.objoid, SELECT l.objoid,
l.classoid, l.classoid,
l.objsubid, l.objsubid,
...@@ -1516,52 +1516,52 @@ UNION ALL ...@@ -1516,52 +1516,52 @@ UNION ALL
l.label l.label
FROM (pg_seclabel l FROM (pg_seclabel l
JOIN pg_namespace nsp ON (((l.classoid = nsp.tableoid) AND (l.objoid = nsp.oid)))) JOIN pg_namespace nsp ON (((l.classoid = nsp.tableoid) AND (l.objoid = nsp.oid))))
WHERE (l.objsubid = 0)) WHERE (l.objsubid = 0)
UNION ALL UNION ALL
SELECT l.objoid, SELECT l.objoid,
l.classoid, l.classoid,
l.objsubid, l.objsubid,
'event trigger'::text AS objtype, 'event trigger'::text AS objtype,
NULL::oid AS objnamespace, NULL::oid AS objnamespace,
quote_ident((evt.evtname)::text) AS objname, quote_ident((evt.evtname)::text) AS objname,
l.provider, l.provider,
l.label l.label
FROM (pg_seclabel l FROM (pg_seclabel l
JOIN pg_event_trigger evt ON (((l.classoid = evt.tableoid) AND (l.objoid = evt.oid)))) JOIN pg_event_trigger evt ON (((l.classoid = evt.tableoid) AND (l.objoid = evt.oid))))
WHERE (l.objsubid = 0)) WHERE (l.objsubid = 0)
UNION ALL UNION ALL
SELECT l.objoid, SELECT l.objoid,
l.classoid, l.classoid,
0 AS objsubid, 0 AS objsubid,
'database'::text AS objtype, 'database'::text AS objtype,
NULL::oid AS objnamespace, NULL::oid AS objnamespace,
quote_ident((dat.datname)::text) AS objname, quote_ident((dat.datname)::text) AS objname,
l.provider, l.provider,
l.label l.label
FROM (pg_shseclabel l FROM (pg_shseclabel l
JOIN pg_database dat ON (((l.classoid = dat.tableoid) AND (l.objoid = dat.oid))))) JOIN pg_database dat ON (((l.classoid = dat.tableoid) AND (l.objoid = dat.oid))))
UNION ALL UNION ALL
SELECT l.objoid, SELECT l.objoid,
l.classoid, l.classoid,
0 AS objsubid, 0 AS objsubid,
'tablespace'::text AS objtype, 'tablespace'::text AS objtype,
NULL::oid AS objnamespace, NULL::oid AS objnamespace,
quote_ident((spc.spcname)::text) AS objname, quote_ident((spc.spcname)::text) AS objname,
l.provider, l.provider,
l.label l.label
FROM (pg_shseclabel l FROM (pg_shseclabel l
JOIN pg_tablespace spc ON (((l.classoid = spc.tableoid) AND (l.objoid = spc.oid))))) JOIN pg_tablespace spc ON (((l.classoid = spc.tableoid) AND (l.objoid = spc.oid))))
UNION ALL UNION ALL
SELECT l.objoid, SELECT l.objoid,
l.classoid, l.classoid,
0 AS objsubid, 0 AS objsubid,
'role'::text AS objtype, 'role'::text AS objtype,
NULL::oid AS objnamespace, NULL::oid AS objnamespace,
quote_ident((rol.rolname)::text) AS objname, quote_ident((rol.rolname)::text) AS objname,
l.provider, l.provider,
l.label l.label
FROM (pg_shseclabel l FROM (pg_shseclabel l
JOIN pg_authid rol ON (((l.classoid = rol.tableoid) AND (l.objoid = rol.oid)))); JOIN pg_authid rol ON (((l.classoid = rol.tableoid) AND (l.objoid = rol.oid))));
pg_settings| SELECT a.name, pg_settings| SELECT a.name,
a.setting, a.setting,
a.unit, a.unit,
......
...@@ -300,48 +300,48 @@ SELECT * FROM vsubdepartment ORDER BY name; ...@@ -300,48 +300,48 @@ SELECT * FROM vsubdepartment ORDER BY name;
-- Check reverse listing -- Check reverse listing
SELECT pg_get_viewdef('vsubdepartment'::regclass); SELECT pg_get_viewdef('vsubdepartment'::regclass);
pg_get_viewdef pg_get_viewdef
------------------------------------------------------- -----------------------------------------------
WITH RECURSIVE subdepartment AS ( + WITH RECURSIVE subdepartment AS ( +
SELECT department.id, + SELECT department.id, +
department.parent_department, + department.parent_department, +
department.name + department.name +
FROM department + FROM department +
WHERE (department.name = 'A'::text)+ WHERE (department.name = 'A'::text)+
UNION ALL + UNION ALL +
SELECT d.id, + SELECT d.id, +
d.parent_department, + d.parent_department, +
d.name + d.name +
FROM department d, + FROM department d, +
subdepartment sd + subdepartment sd +
WHERE (d.parent_department = sd.id)+ WHERE (d.parent_department = sd.id)+
) + ) +
SELECT subdepartment.id, + SELECT subdepartment.id, +
subdepartment.parent_department, + subdepartment.parent_department, +
subdepartment.name + subdepartment.name +
FROM subdepartment; FROM subdepartment;
(1 row) (1 row)
SELECT pg_get_viewdef('vsubdepartment'::regclass, true); SELECT pg_get_viewdef('vsubdepartment'::regclass, true);
pg_get_viewdef pg_get_viewdef
----------------------------------------------------- ---------------------------------------------
WITH RECURSIVE subdepartment AS ( + WITH RECURSIVE subdepartment AS ( +
SELECT department.id, + SELECT department.id, +
department.parent_department, + department.parent_department, +
department.name + department.name +
FROM department + FROM department +
WHERE department.name = 'A'::text+ WHERE department.name = 'A'::text+
UNION ALL + UNION ALL +
SELECT d.id, + SELECT d.id, +
d.parent_department, + d.parent_department, +
d.name + d.name +
FROM department d, + FROM department d, +
subdepartment sd + subdepartment sd +
WHERE d.parent_department = sd.id+ WHERE d.parent_department = sd.id+
) + ) +
SELECT subdepartment.id, + SELECT subdepartment.id, +
subdepartment.parent_department, + subdepartment.parent_department, +
subdepartment.name + subdepartment.name +
FROM subdepartment; FROM subdepartment;
(1 row) (1 row)
...@@ -360,11 +360,11 @@ SELECT sum(n) FROM t; ...@@ -360,11 +360,11 @@ SELECT sum(n) FROM t;
sum | bigint | | plain | sum | bigint | | plain |
View definition: View definition:
WITH RECURSIVE t(n) AS ( WITH RECURSIVE t(n) AS (
VALUES (1) VALUES (1)
UNION ALL UNION ALL
SELECT t_1.n + 1 SELECT t_1.n + 1
FROM t t_1 FROM t t_1
WHERE t_1.n < 100 WHERE t_1.n < 100
) )
SELECT sum(t.n) AS sum SELECT sum(t.n) AS sum
FROM t; FROM t;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment