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

Reply via email to