On 12/22/2011 06:11 PM, Andrew Dunstan wrote:
On 12/22/2011 02:17 PM, Andrew Dunstan wrote:
On 12/22/2011 01:05 PM, Tom Lane wrote:
Maybe, though I fear it might complicate the ruleutils code a bit.
You'd probably have to build the output for a column first and then
see how long it is before deciding whether to insert a newline.
In short, I don't mind trying to make this work better, but I think it
will take more work than a two-line patch.
OK. Let me whip something up. I had already come to the conclusion
you did about how best to do this.
Here's a WIP patch. At least it's fairly localized, but as expected
it's rather more than 2 lines :-). Sample output:
regression=# \pset format unaligned
Output format is unaligned.
regression=# select pg_get_viewdef('shoelace',true);
pg_get_viewdef
SELECT s.sl_name, s.sl_avail, s.sl_color, s.sl_len, s.sl_unit,
s.sl_len * u.un_fact AS sl_len_cm
FROM shoelace_data s, unit u
WHERE s.sl_unit = u.un_name;
(1 row)
regression=#
I just had an idea. We could invent a flavor of pg_get_viewdef() that
took an int as the second param, that would be the wrap width. For the
boolean case as above, 80 would be implied. 0 would mean always wrap.
psql could be made to default to the window width, or maybe window
width - 1, but we could provide a psql setting that would override it.
This time with patch.
cheers
andrew
*** a/src/backend/utils/adt/ruleutils.c
--- b/src/backend/utils/adt/ruleutils.c
***************
*** 3013,3018 **** get_target_list(List *targetList, deparse_context *context,
--- 3013,3019 ----
char *sep;
int colno;
ListCell *l;
+ bool last_was_multiline = false;
sep = " ";
colno = 0;
***************
*** 3021,3028 **** get_target_list(List *targetList, deparse_context *context,
TargetEntry *tle = (TargetEntry *) lfirst(l);
char *colname;
char *attname;
! if (tle->resjunk)
continue; /* ignore junk entries */
appendStringInfoString(buf, sep);
--- 3022,3033 ----
TargetEntry *tle = (TargetEntry *) lfirst(l);
char *colname;
char *attname;
+ StringInfoData targetbuf;
+ int leading_nl_pos = -1;
+ char *trailing_nl;
+ int i;
! if (tle->resjunk)
continue; /* ignore junk entries */
appendStringInfoString(buf, sep);
***************
*** 3030,3035 **** get_target_list(List *targetList, deparse_context *context,
--- 3035,3049 ----
colno++;
/*
+ * Put the new field spec into targetbuf so we can
+ * decide after we've got it whether or not it needs
+ * to go on a new line.
+ */
+
+ initStringInfo(&targetbuf);
+ context->buf = &targetbuf;
+
+ /*
* We special-case Var nodes rather than using get_rule_expr. This is
* needed because get_rule_expr will display a whole-row Var as
* "foo.*", which is the preferred notation in most contexts, but at
***************
*** 3063,3070 **** get_target_list(List *targetList, deparse_context *context,
if (colname) /* resname could be NULL */
{
if (attname == NULL || strcmp(attname, colname) != 0)
! appendStringInfo(buf, " AS %s", quote_identifier(colname));
}
}
}
--- 3077,3139 ----
if (colname) /* resname could be NULL */
{
if (attname == NULL || strcmp(attname, colname) != 0)
! appendStringInfo(&targetbuf, " AS %s", quote_identifier(colname));
! }
!
! /* Does the new field start with whitespace plus a new line? */
!
! for (i=0; i < targetbuf.len; i++)
! {
! if (targetbuf.data[i] == '\n')
! {
! leading_nl_pos = i;
! break;
! }
! if (targetbuf.data[i] > ' ')
! break;
! }
!
! context->buf = buf;
!
! /* Locate the start of the current line in the buffer */
!
! trailing_nl = (strrchr(buf->data,'\n'));
! if (trailing_nl == NULL)
! trailing_nl = buf->data;
! else
! trailing_nl++;
!
! /*
! * If the field we're adding already has a newline
! * don't add one. Otherwise, add one, plus some
! * indentation. if either the new field would
! * cause an 80 column overflow or the last field
! * had a multiline spec.
! */
!
! if (leading_nl_pos == -1 &&
! ((strlen(trailing_nl) + strlen(targetbuf.data) > 79) ||
! last_was_multiline))
! {
! appendContextKeyword(context, "", -PRETTYINDENT_STD,
! PRETTYINDENT_STD, PRETTYINDENT_VAR);
}
+
+ /* Add the new field */
+
+ appendStringInfoString(buf, targetbuf.data);
+
+
+ /* Keep track of this fieLd's status for next interation */
+
+ if (strchr(targetbuf.data + leading_nl_pos + 1,'\n') != NULL)
+ last_was_multiline = true;
+ else
+ last_was_multiline = false;
+
+ /* cleanup */
+
+ pfree (targetbuf.data);
}
}
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers