Commit 0601cb54 authored by Tom Lane's avatar Tom Lane

Limit overall indentation in rule/view dumps.

Continuing to indent no matter how deeply nested we get doesn't really
do anything for readability; what's worse, it results in O(N^2) total
whitespace, which can become a performance and memory-consumption issue.

To address this, once we get past 40 characters of indentation, reduce
the indentation step distance 4x, and also limit the maximum indentation
by reducing it modulo 40.  This latter choice is a bit weird at first
glance, but it seems to preserve readability better than a simple cap
would do.

Back-patch to 9.3, because since commit 62e66640 the performance issue
is a hazard for pg_dump.

Greg Stark and Tom Lane
parent d166eed3
...@@ -71,6 +71,8 @@ ...@@ -71,6 +71,8 @@
#define PRETTYINDENT_JOIN 4 #define PRETTYINDENT_JOIN 4
#define PRETTYINDENT_VAR 4 #define PRETTYINDENT_VAR 4
#define PRETTYINDENT_LIMIT 40 /* wrap limit */
/* Pretty flags */ /* Pretty flags */
#define PRETTYFLAG_PAREN 1 #define PRETTYFLAG_PAREN 1
#define PRETTYFLAG_INDENT 2 #define PRETTYFLAG_INDENT 2
...@@ -6391,14 +6393,36 @@ appendContextKeyword(deparse_context *context, const char *str, ...@@ -6391,14 +6393,36 @@ appendContextKeyword(deparse_context *context, const char *str,
if (PRETTY_INDENT(context)) if (PRETTY_INDENT(context))
{ {
int indentAmount;
context->indentLevel += indentBefore; context->indentLevel += indentBefore;
/* remove any trailing spaces currently in the buffer ... */ /* remove any trailing spaces currently in the buffer ... */
removeStringInfoSpaces(buf); removeStringInfoSpaces(buf);
/* ... then add a newline and some spaces */ /* ... then add a newline and some spaces */
appendStringInfoChar(buf, '\n'); appendStringInfoChar(buf, '\n');
appendStringInfoSpaces(buf,
Max(context->indentLevel, 0) + indentPlus); if (context->indentLevel < PRETTYINDENT_LIMIT)
indentAmount = Max(context->indentLevel, 0) + indentPlus;
else
{
/*
* If we're indented more than PRETTYINDENT_LIMIT characters, try
* to conserve horizontal space by reducing the per-level
* indentation. For best results the scale factor here should
* divide all the indent amounts that get added to indentLevel
* (PRETTYINDENT_STD, etc). It's important that the indentation
* not grow unboundedly, else deeply-nested trees use O(N^2)
* whitespace; so we also wrap modulo PRETTYINDENT_LIMIT.
*/
indentAmount = PRETTYINDENT_LIMIT +
(context->indentLevel - PRETTYINDENT_LIMIT) /
(PRETTYINDENT_STD / 2);
indentAmount %= PRETTYINDENT_LIMIT;
/* scale/wrap logic affects indentLevel, but not indentPlus */
indentAmount += indentPlus;
}
appendStringInfoSpaces(buf, indentAmount);
appendStringInfoString(buf, str); appendStringInfoString(buf, str);
......
...@@ -1402,121 +1402,121 @@ pg_rules| SELECT n.nspname AS schemaname, ...@@ -1402,121 +1402,121 @@ pg_rules| SELECT n.nspname AS schemaname,
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 CASE
WHEN (rel.relkind = 'r'::"char") THEN 'table'::text WHEN (rel.relkind = 'r'::"char") THEN 'table'::text
WHEN (rel.relkind = 'v'::"char") THEN 'view'::text WHEN (rel.relkind = 'v'::"char") THEN 'view'::text
WHEN (rel.relkind = 'm'::"char") THEN 'materialized view'::text WHEN (rel.relkind = 'm'::"char") THEN 'materialized view'::text
WHEN (rel.relkind = 'S'::"char") THEN 'sequence'::text WHEN (rel.relkind = 'S'::"char") THEN 'sequence'::text
WHEN (rel.relkind = 'f'::"char") THEN 'foreign table'::text WHEN (rel.relkind = 'f'::"char") THEN 'foreign table'::text
ELSE NULL::text ELSE NULL::text
END AS objtype, END AS objtype,
rel.relnamespace AS objnamespace, rel.relnamespace AS objnamespace,
CASE CASE
WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text) 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)) 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_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid)))) JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid))))
JOIN pg_namespace nsp ON ((rel.relnamespace = 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,
'column'::text AS objtype, 'column'::text AS objtype,
rel.relnamespace AS objnamespace, rel.relnamespace AS objnamespace,
(( ((
CASE CASE
WHEN pg_table_is_visible(rel.oid) THEN quote_ident((rel.relname)::text) 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)) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((rel.relname)::text))
END || '.'::text) || (att.attname)::text) AS objname, END || '.'::text) || (att.attname)::text) AS objname,
l.provider, l.provider,
l.label l.label
FROM (((pg_seclabel l FROM (((pg_seclabel l
JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid)))) 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_attribute att ON (((rel.oid = att.attrelid) AND (l.objsubid = att.attnum))))
JOIN pg_namespace nsp ON ((rel.relnamespace = 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,
CASE CASE
WHEN (pro.proisagg = true) THEN 'aggregate'::text WHEN (pro.proisagg = true) THEN 'aggregate'::text
WHEN (pro.proisagg = false) THEN 'function'::text WHEN (pro.proisagg = false) THEN 'function'::text
ELSE NULL::text ELSE NULL::text
END AS objtype, END AS objtype,
pro.pronamespace AS objnamespace, pro.pronamespace AS objnamespace,
((( (((
CASE CASE
WHEN pg_function_is_visible(pro.oid) THEN quote_ident((pro.proname)::text) 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)) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((pro.proname)::text))
END || '('::text) || pg_get_function_arguments(pro.oid)) || ')'::text) AS objname, END || '('::text) || pg_get_function_arguments(pro.oid)) || ')'::text) AS objname,
l.provider, l.provider,
l.label l.label
FROM ((pg_seclabel l FROM ((pg_seclabel l
JOIN pg_proc pro ON (((l.classoid = pro.tableoid) AND (l.objoid = pro.oid)))) JOIN pg_proc pro ON (((l.classoid = pro.tableoid) AND (l.objoid = pro.oid))))
JOIN pg_namespace nsp ON ((pro.pronamespace = nsp.oid))) JOIN pg_namespace nsp ON ((pro.pronamespace = 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,
CASE CASE
WHEN (typ.typtype = 'd'::"char") THEN 'domain'::text WHEN (typ.typtype = 'd'::"char") THEN 'domain'::text
ELSE 'type'::text ELSE 'type'::text
END AS objtype, END AS objtype,
typ.typnamespace AS objnamespace, typ.typnamespace AS objnamespace,
CASE CASE
WHEN pg_type_is_visible(typ.oid) THEN quote_ident((typ.typname)::text) 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)) ELSE ((quote_ident((nsp.nspname)::text) || '.'::text) || quote_ident((typ.typname)::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_type typ ON (((l.classoid = typ.tableoid) AND (l.objoid = typ.oid))))
JOIN pg_namespace nsp ON ((typ.typnamespace = nsp.oid))) JOIN pg_namespace nsp ON ((typ.typnamespace = 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, 'large object'::text AS objtype,
NULL::oid AS objnamespace, NULL::oid AS objnamespace,
(l.objoid)::text AS objname, (l.objoid)::text AS objname,
l.provider, l.provider,
l.label l.label
FROM (pg_seclabel l FROM (pg_seclabel l
JOIN pg_largeobject_metadata lom ON ((l.objoid = lom.oid))) JOIN pg_largeobject_metadata lom ON ((l.objoid = lom.oid)))
WHERE ((l.classoid = ('pg_largeobject'::regclass)::oid) AND (l.objsubid = 0))) WHERE ((l.classoid = ('pg_largeobject'::regclass)::oid) AND (l.objsubid = 0)))
UNION ALL UNION ALL
SELECT l.objoid, SELECT l.objoid,
l.classoid, l.classoid,
l.objsubid, l.objsubid,
'language'::text AS objtype, 'language'::text AS objtype,
NULL::oid AS objnamespace, NULL::oid AS objnamespace,
quote_ident((lan.lanname)::text) AS objname, quote_ident((lan.lanname)::text) AS objname,
l.provider, l.provider,
l.label l.label
FROM (pg_seclabel l FROM (pg_seclabel l
JOIN pg_language lan ON (((l.classoid = lan.tableoid) AND (l.objoid = lan.oid)))) JOIN pg_language lan ON (((l.classoid = lan.tableoid) AND (l.objoid = lan.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,
'schema'::text AS objtype, 'schema'::text AS objtype,
nsp.oid AS objnamespace, nsp.oid AS objnamespace,
quote_ident((nsp.nspname)::text) AS objname, quote_ident((nsp.nspname)::text) AS objname,
l.provider, l.provider,
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,
......
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