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 62e666400d the performance issue
is a hazard for pg_dump.

Greg Stark and Tom Lane
This commit is contained in:
Tom Lane 2014-04-30 12:48:12 -04:00
parent d166eed302
commit 0601cb54da
2 changed files with 140 additions and 116 deletions

View File

@ -71,6 +71,8 @@
#define PRETTYINDENT_JOIN 4
#define PRETTYINDENT_VAR 4
#define PRETTYINDENT_LIMIT 40 /* wrap limit */
/* Pretty flags */
#define PRETTYFLAG_PAREN 1
#define PRETTYFLAG_INDENT 2
@ -6391,14 +6393,36 @@ appendContextKeyword(deparse_context *context, const char *str,
if (PRETTY_INDENT(context))
{
int indentAmount;
context->indentLevel += indentBefore;
/* remove any trailing spaces currently in the buffer ... */
removeStringInfoSpaces(buf);
/* ... then add a newline and some spaces */
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);

View File

@ -1493,7 +1493,7 @@ pg_seclabels| ( ( ( ( ( ( (
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
UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,