Skip to content

Commit 2f582f7

Browse files
committed
Improve pretty printing of viewdefs.
Some line feeds are added to target lists and from lists to make them more readable. By default they wrap at 80 columns if possible, but the wrap column is also selectable - if 0 it wraps after every item. Andrew Dunstan, reviewed by Hitoshi Harada.
1 parent 84ff5b5 commit 2f582f7

File tree

9 files changed

+204
-18
lines changed

9 files changed

+204
-18
lines changed

doc/src/sgml/func.sgml

+10-2
Original file line numberDiff line numberDiff line change
@@ -13828,7 +13828,8 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
1382813828
<row>
1382913829
<entry><literal><function>pg_get_viewdef(<parameter>view_name</parameter>, <parameter>pretty_bool</>)</function></literal></entry>
1383013830
<entry><type>text</type></entry>
13831-
<entry>get underlying <command>SELECT</command> command for view (<emphasis>deprecated</emphasis>)</entry>
13831+
<entry>get underlying <command>SELECT</command> command for view,
13832+
lines with fields are wrapped to 80 columns if pretty_bool is true (<emphasis>deprecated</emphasis>)</entry>
1383213833
</row>
1383313834
<row>
1383413835
<entry><literal><function>pg_get_viewdef(<parameter>view_oid</parameter>)</function></literal></entry>
@@ -13838,7 +13839,14 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
1383813839
<row>
1383913840
<entry><literal><function>pg_get_viewdef(<parameter>view_oid</parameter>, <parameter>pretty_bool</>)</function></literal></entry>
1384013841
<entry><type>text</type></entry>
13841-
<entry>get underlying <command>SELECT</command> command for view</entry>
13842+
<entry>get underlying <command>SELECT</command> command for view,
13843+
lines with fields are wrapped to 80 columns if pretty_bool is true</entry>
13844+
</row>
13845+
<row>
13846+
<entry><literal><function>pg_get_viewdef(<parameter>view_oid</parameter>, <parameter>wrap_int</>)</function></literal></entry>
13847+
<entry><type>text</type></entry>
13848+
<entry>get underlying <command>SELECT</command> command for view,
13849+
wrapping lines with fields as specified, pretty printing is implied</entry>
1384213850
</row>
1384313851
<row>
1384413852
<entry><literal><function>pg_options_to_table(<parameter>reloptions</parameter>)</function></literal></entry>

src/backend/utils/adt/ruleutils.c

+135-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
#define PRETTYFLAG_PAREN 1
7474
#define PRETTYFLAG_INDENT 2
7575

76+
#define PRETTY_WRAP_DEFAULT 79
77+
7678
/* macro to test if pretty action needed */
7779
#define PRETTY_PAREN(context) ((context)->prettyFlags & PRETTYFLAG_PAREN)
7880
#define PRETTY_INDENT(context) ((context)->prettyFlags & PRETTYFLAG_INDENT)
@@ -136,6 +138,7 @@ static SPIPlanPtr plan_getrulebyoid = NULL;
136138
static const char *query_getrulebyoid = "SELECT * FROM pg_catalog.pg_rewrite WHERE oid = $1";
137139
static SPIPlanPtr plan_getviewrule = NULL;
138140
static const char *query_getviewrule = "SELECT * FROM pg_catalog.pg_rewrite WHERE ev_class = $1 AND rulename = $2";
141+
static int pretty_wrap = PRETTY_WRAP_DEFAULT;
139142

140143
/* GUC parameters */
141144
bool quote_all_identifiers = false;
@@ -380,6 +383,23 @@ pg_get_viewdef_ext(PG_FUNCTION_ARGS)
380383
PG_RETURN_TEXT_P(string_to_text(pg_get_viewdef_worker(viewoid, prettyFlags)));
381384
}
382385

386+
Datum
387+
pg_get_viewdef_wrap(PG_FUNCTION_ARGS)
388+
{
389+
/* By OID */
390+
Oid viewoid = PG_GETARG_OID(0);
391+
int wrap = PG_GETARG_INT32(1);
392+
int prettyFlags;
393+
char *result;
394+
395+
/* calling this implies we want pretty printing */
396+
prettyFlags = PRETTYFLAG_PAREN | PRETTYFLAG_INDENT;
397+
pretty_wrap = wrap;
398+
result = pg_get_viewdef_worker(viewoid, prettyFlags);
399+
pretty_wrap = PRETTY_WRAP_DEFAULT;
400+
PG_RETURN_TEXT_P(string_to_text(result));
401+
}
402+
383403
Datum
384404
pg_get_viewdef_name(PG_FUNCTION_ARGS)
385405
{
@@ -3013,6 +3033,7 @@ get_target_list(List *targetList, deparse_context *context,
30133033
char *sep;
30143034
int colno;
30153035
ListCell *l;
3036+
bool last_was_multiline = false;
30163037

30173038
sep = " ";
30183039
colno = 0;
@@ -3021,6 +3042,10 @@ get_target_list(List *targetList, deparse_context *context,
30213042
TargetEntry *tle = (TargetEntry *) lfirst(l);
30223043
char *colname;
30233044
char *attname;
3045+
StringInfoData targetbuf;
3046+
int leading_nl_pos = -1;
3047+
char *trailing_nl;
3048+
int pos;
30243049

30253050
if (tle->resjunk)
30263051
continue; /* ignore junk entries */
@@ -3029,6 +3054,15 @@ get_target_list(List *targetList, deparse_context *context,
30293054
sep = ", ";
30303055
colno++;
30313056

3057+
/*
3058+
* Put the new field spec into targetbuf so we can
3059+
* decide after we've got it whether or not it needs
3060+
* to go on a new line.
3061+
*/
3062+
3063+
initStringInfo(&targetbuf);
3064+
context->buf = &targetbuf;
3065+
30323066
/*
30333067
* We special-case Var nodes rather than using get_rule_expr. This is
30343068
* needed because get_rule_expr will display a whole-row Var as
@@ -3063,8 +3097,66 @@ get_target_list(List *targetList, deparse_context *context,
30633097
if (colname) /* resname could be NULL */
30643098
{
30653099
if (attname == NULL || strcmp(attname, colname) != 0)
3066-
appendStringInfo(buf, " AS %s", quote_identifier(colname));
3100+
appendStringInfo(&targetbuf, " AS %s", quote_identifier(colname));
3101+
}
3102+
3103+
/* Restore context buffer */
3104+
3105+
context->buf = buf;
3106+
3107+
/* Does the new field start with whitespace plus a new line? */
3108+
3109+
for (pos=0; pos < targetbuf.len; pos++)
3110+
{
3111+
if (targetbuf.data[pos] == '\n')
3112+
{
3113+
leading_nl_pos = pos;
3114+
break;
3115+
}
3116+
if (targetbuf.data[pos] > ' ')
3117+
break;
3118+
}
3119+
3120+
/* Locate the start of the current line in the buffer */
3121+
3122+
trailing_nl = (strrchr(buf->data,'\n'));
3123+
if (trailing_nl == NULL)
3124+
trailing_nl = buf->data;
3125+
else
3126+
trailing_nl++;
3127+
3128+
/*
3129+
* If the field we're adding is the first in the list, or it already
3130+
* has a leading newline, or wrap mode is disabled (pretty_wrap < 0),
3131+
* don't add anything.
3132+
* Otherwise, add a newline, plus some indentation, if either the
3133+
* new field would cause an overflow or the last field used more than
3134+
* one line.
3135+
*/
3136+
3137+
if (colno > 1 &&
3138+
leading_nl_pos == -1 &&
3139+
pretty_wrap >= 0 &&
3140+
((strlen(trailing_nl) + strlen(targetbuf.data) > pretty_wrap) ||
3141+
last_was_multiline))
3142+
{
3143+
appendContextKeyword(context, "", -PRETTYINDENT_STD,
3144+
PRETTYINDENT_STD, PRETTYINDENT_VAR);
30673145
}
3146+
3147+
/* Add the new field */
3148+
3149+
appendStringInfoString(buf, targetbuf.data);
3150+
3151+
3152+
/* Keep track of this field's status for next iteration */
3153+
3154+
last_was_multiline =
3155+
(strchr(targetbuf.data + leading_nl_pos + 1,'\n') != NULL);
3156+
3157+
/* cleanup */
3158+
3159+
pfree (targetbuf.data);
30683160
}
30693161
}
30703162

@@ -6445,11 +6537,52 @@ get_from_clause(Query *query, const char *prefix, deparse_context *context)
64456537
appendContextKeyword(context, prefix,
64466538
-PRETTYINDENT_STD, PRETTYINDENT_STD, 2);
64476539
first = false;
6540+
6541+
get_from_clause_item(jtnode, query, context);
64486542
}
64496543
else
6544+
{
6545+
StringInfoData targetbuf;
6546+
char *trailing_nl;
6547+
64506548
appendStringInfoString(buf, ", ");
6549+
6550+
initStringInfo(&targetbuf);
6551+
context->buf = &targetbuf;
6552+
6553+
get_from_clause_item(jtnode, query, context);
6554+
6555+
context->buf = buf;
6556+
6557+
/* Locate the start of the current line in the buffer */
6558+
6559+
trailing_nl = (strrchr(buf->data,'\n'));
6560+
if (trailing_nl == NULL)
6561+
trailing_nl = buf->data;
6562+
else
6563+
trailing_nl++;
6564+
6565+
/*
6566+
* Add a newline, plus some indentation, if pretty_wrap is on and the
6567+
* new from-clause item would cause an overflow.
6568+
*/
6569+
6570+
if (pretty_wrap >= 0 &&
6571+
(strlen(trailing_nl) + strlen(targetbuf.data) > pretty_wrap))
6572+
{
6573+
appendContextKeyword(context, "", -PRETTYINDENT_STD,
6574+
PRETTYINDENT_STD, PRETTYINDENT_VAR);
6575+
}
6576+
6577+
/* Add the new item */
6578+
6579+
appendStringInfoString(buf, targetbuf.data);
6580+
6581+
/* cleanup */
6582+
6583+
pfree (targetbuf.data);
6584+
}
64516585

6452-
get_from_clause_item(jtnode, query, context);
64536586
}
64546587
}
64556588

src/include/catalog/catversion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201202141
56+
#define CATALOG_VERSION_NO 201202191
5757

5858
#endif

src/include/catalog/pg_proc.h

+2
Original file line numberDiff line numberDiff line change
@@ -3743,6 +3743,8 @@ DATA(insert OID = 2505 ( pg_get_viewdef PGNSP PGUID 12 1 0 0 0 f f f f t f s
37433743
DESCR("select statement of a view with pretty-print option");
37443744
DATA(insert OID = 2506 ( pg_get_viewdef PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "26 16" _null_ _null_ _null_ _null_ pg_get_viewdef_ext _null_ _null_ _null_ ));
37453745
DESCR("select statement of a view with pretty-print option");
3746+
DATA(insert OID = 3159 ( pg_get_viewdef PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "26 23" _null_ _null_ _null_ _null_ pg_get_viewdef_wrap _null_ _null_ _null_ ));
3747+
DESCR("select statement of a view with pretty-printing and specified line wrapping");
37463748
DATA(insert OID = 2507 ( pg_get_indexdef PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 25 "26 23 16" _null_ _null_ _null_ _null_ pg_get_indexdef_ext _null_ _null_ _null_ ));
37473749
DESCR("index description (full create statement or single expression) with pretty-print option");
37483750
DATA(insert OID = 2508 ( pg_get_constraintdef PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "26 16" _null_ _null_ _null_ _null_ pg_get_constraintdef_ext _null_ _null_ _null_ ));

src/include/utils/builtins.h

+1
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
624624
extern Datum pg_get_ruledef_ext(PG_FUNCTION_ARGS);
625625
extern Datum pg_get_viewdef(PG_FUNCTION_ARGS);
626626
extern Datum pg_get_viewdef_ext(PG_FUNCTION_ARGS);
627+
extern Datum pg_get_viewdef_wrap(PG_FUNCTION_ARGS);
627628
extern Datum pg_get_viewdef_name(PG_FUNCTION_ARGS);
628629
extern Datum pg_get_viewdef_name_ext(PG_FUNCTION_ARGS);
629630
extern Datum pg_get_indexdef(PG_FUNCTION_ARGS);

src/test/regress/expected/polymorphism.out

+3-1
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,9 @@ select * from dfview;
13811381
c3 | bigint | | plain |
13821382
c4 | bigint | | plain |
13831383
View definition:
1384-
SELECT int8_tbl.q1, int8_tbl.q2, dfunc(int8_tbl.q1, int8_tbl.q2, flag := int8_tbl.q1 > int8_tbl.q2) AS c3, dfunc(int8_tbl.q1, flag := int8_tbl.q1 < int8_tbl.q2, b := int8_tbl.q2) AS c4
1384+
SELECT int8_tbl.q1, int8_tbl.q2,
1385+
dfunc(int8_tbl.q1, int8_tbl.q2, flag := int8_tbl.q1 > int8_tbl.q2) AS c3,
1386+
dfunc(int8_tbl.q1, flag := int8_tbl.q1 < int8_tbl.q2, b := int8_tbl.q2) AS c4
13851387
FROM int8_tbl;
13861388

13871389
drop view dfview;

src/test/regress/expected/rules.out

+33
Original file line numberDiff line numberDiff line change
@@ -1568,3 +1568,36 @@ select * from only t1_2;
15681568
19
15691569
(10 rows)
15701570

1571+
-- test various flavors of pg_get_viewdef()
1572+
select pg_get_viewdef('shoe'::regclass) as unpretty;
1573+
unpretty
1574+
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1575+
SELECT sh.shoename, sh.sh_avail, sh.slcolor, sh.slminlen, (sh.slminlen * un.un_fact) AS slminlen_cm, sh.slmaxlen, (sh.slmaxlen * un.un_fact) AS slmaxlen_cm, sh.slunit FROM shoe_data sh, unit un WHERE (sh.slunit = un.un_name);
1576+
(1 row)
1577+
1578+
select pg_get_viewdef('shoe'::regclass,true) as pretty;
1579+
pretty
1580+
-------------------------------------------------------------
1581+
SELECT sh.shoename, sh.sh_avail, sh.slcolor, sh.slminlen, +
1582+
sh.slminlen * un.un_fact AS slminlen_cm, sh.slmaxlen, +
1583+
sh.slmaxlen * un.un_fact AS slmaxlen_cm, sh.slunit +
1584+
FROM shoe_data sh, unit un +
1585+
WHERE sh.slunit = un.un_name;
1586+
(1 row)
1587+
1588+
select pg_get_viewdef('shoe'::regclass,0) as prettier;
1589+
prettier
1590+
-----------------------------------------------
1591+
SELECT sh.shoename, +
1592+
sh.sh_avail, +
1593+
sh.slcolor, +
1594+
sh.slminlen, +
1595+
sh.slminlen * un.un_fact AS slminlen_cm, +
1596+
sh.slmaxlen, +
1597+
sh.slmaxlen * un.un_fact AS slmaxlen_cm, +
1598+
sh.slunit +
1599+
FROM shoe_data sh, +
1600+
unit un +
1601+
WHERE sh.slunit = un.un_name;
1602+
(1 row)
1603+

src/test/regress/expected/with.out

+13-12
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,19 @@ SELECT pg_get_viewdef('vsubdepartment'::regclass);
277277
(1 row)
278278

279279
SELECT pg_get_viewdef('vsubdepartment'::regclass, true);
280-
pg_get_viewdef
281-
--------------------------------------------------------------------------------------
282-
WITH RECURSIVE subdepartment AS ( +
283-
SELECT department.id, department.parent_department, department.name+
284-
FROM department +
285-
WHERE department.name = 'A'::text +
286-
UNION ALL +
287-
SELECT d.id, d.parent_department, d.name +
288-
FROM department d, subdepartment sd +
289-
WHERE d.parent_department = sd.id +
290-
) +
291-
SELECT subdepartment.id, subdepartment.parent_department, subdepartment.name +
280+
pg_get_viewdef
281+
-------------------------------------------------------------------------------
282+
WITH RECURSIVE subdepartment AS ( +
283+
SELECT department.id, department.parent_department, +
284+
department.name +
285+
FROM department +
286+
WHERE department.name = 'A'::text +
287+
UNION ALL +
288+
SELECT d.id, d.parent_department, d.name +
289+
FROM department d, subdepartment sd +
290+
WHERE d.parent_department = sd.id +
291+
) +
292+
SELECT subdepartment.id, subdepartment.parent_department, subdepartment.name+
292293
FROM subdepartment;
293294
(1 row)
294295

src/test/regress/sql/rules.sql

+6
Original file line numberDiff line numberDiff line change
@@ -927,3 +927,9 @@ update t1 set a = 4 where a = 5;
927927
select * from only t1;
928928
select * from only t1_1;
929929
select * from only t1_2;
930+
931+
-- test various flavors of pg_get_viewdef()
932+
933+
select pg_get_viewdef('shoe'::regclass) as unpretty;
934+
select pg_get_viewdef('shoe'::regclass,true) as pretty;
935+
select pg_get_viewdef('shoe'::regclass,0) as prettier;

0 commit comments

Comments
 (0)