Hi,

I've more than once wanted to know what allocated shared memory in
postgres installation is used for. Especially with more an more
extensions around that's quite useful.

Thus I've written a patch to add a new SRF/VIEW
pg_get_shmem_allocations/pg_shmem_allocations that shows the contents of
the shared memory index:

postgres=# SELECT * FROM pg_shmem_allocations ORDER BY size DESC;
                 key                 |     off     |    size     | allocated
-------------------------------------+-------------+-------------+-----------
 Buffer Blocks                       |   286242528 | 17179869184 | t
 Buffer Descriptors                  |   152024800 |   134217728 | t
 Checkpointer Data                   | 17584720352 |    41943080 | t
 XLOG Ctl                            |   134234112 |    16804496 | t
 CLOG Ctl                            |   151038624 |      525312 | t
                                     | 17627719648 |      366624 | f
 Backend Activity Buffer             | 17584379168 |      272000 | t
 SUBTRANS Ctl                        |   151563936 |      263168 | t
 OldSerXid SLRU Ctl                  | 17584225696 |      131648 | t
 MultiXactMember Ctl                 |   151892960 |      131648 | t
 Shared Buffer Lookup Table          | 17466111712 |      131184 | t
 shmInvalBuffer                      | 17584653184 |       66104 | t
 Async Ctl                           | 17626666048 |       65856 | t
 MultiXactOffset Ctl                 |   151827104 |       65856 | t
 Fast Path Strong Relation Lock Data | 17583882752 |        4100 | t
 Backend Status Array                | 17584373304 |        3672 | t
 PROCLOCK hash                       | 17583785856 |        2160 | t
 PREDICATELOCKTARGET hash            | 17583886856 |        2160 | t
 PREDICATELOCK hash                  | 17583957632 |        2160 | t
 pg_stat_statements hash             | 17626731952 |        2160 | t
 SERIALIZABLEXID hash                | 17584175184 |        2160 | t
 LOCK hash                           | 17583684096 |        2160 | t
 Background Worker Data              | 17584651184 |        1992 | t
 Wal Receiver Ctl                    | 17626663712 |        1192 | t
 Backend Client Host Name Buffer     | 17584378064 |        1088 | t
 Backend Application Name Buffer     | 17584376976 |        1088 | t
 ProcSignalSlots                     | 17584719472 |         864 | t
 Sync Scan Locations List            | 17626665120 |         656 | t
 Async Queue Control                 | 17626665776 |         244 | t
 Control File                        |   134233856 |         240 | t
 AutoVacuum Data                     | 17626663432 |         224 | t
 BTree Vacuum State                  | 17626664904 |         216 | t
 PMSignalState                       | 17584719288 |         180 | t
 Shared MultiXact State              |   152024608 |         176 | t
 Proc Array                          | 17584373192 |         108 | t
 PredXactList                        | 17584149248 |          88 | t
 Proc Header                         | 17584357360 |          88 | t
 Wal Sender Ctl                      | 17626663656 |          56 | t
 pg_stat_statements                  | 17626731904 |          48 | t
 Buffer Strategy Status              | 17583684064 |          32 | t
 RWConflictPool                      | 17584184832 |          24 | t
 Prepared Transaction Table          | 17584651168 |          16 | t
 FinishedSerializableTransactions    | 17584225664 |          16 | t
 OldSerXidControlData                | 17584357344 |          16 | t
(44 rows)

I think this is quite worthwile information. It'd possibly be better of
in an extension, but the relevant dastructures aren't public.

The attached patch doesn't contain documentation because I wasn't sure
that others would be interested in the feature.

Greetings,

Andres Freund

PS: Yes, the checkpointer's allocation is crazy. The fsync queue is
sized by NBuffers which is absurd.

-- 
 Andres Freund                     http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
>From 6513633b94173fc1d9e2b213c43f9422ddbf5faa Mon Sep 17 00:00:00 2001
From: Greg Stark <st...@mit.edu>
Date: Mon, 28 Apr 2014 18:41:36 +0100
Subject: [PATCH] Add support for wrapping to psql's "extended" mode. This
 makes it very feasible to display tables that have both many columns and some
 large data in some columns (such as pg_stats).

Emre Hasegeli with review and rewriting from Sergey Muraviov and
reviewed by Greg Stark
---
 src/bin/psql/print.c               | 181 ++++++-
 src/test/regress/expected/psql.out | 944 +++++++++++++++++++++++++++++++++++++
 src/test/regress/sql/psql.sql      | 120 +++++
 3 files changed, 1222 insertions(+), 23 deletions(-)

diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 79fc43e..0ebffff 100644
--- a/src/bin/psql/print.c
+++ b/src/bin/psql/print.c
@@ -1161,6 +1161,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
 	struct lineptr *hlineptr,
 			   *dlineptr;
 	bool		is_pager = false;
+	int			output_columns = 0;		/* Width of interactive console */
 
 	if (cancel_pressed)
 		return;
@@ -1234,24 +1235,86 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
 			fprintf(fout, "%s\n", cont->title);
 	}
 
+	/*
+	 * Choose target output width: \pset columns, or $COLUMNS, or ioctl
+	 */
+	if (cont->opt->columns > 0)
+		output_columns = cont->opt->columns;
+	else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
+	{
+		if (cont->opt->env_columns > 0)
+			output_columns = cont->opt->env_columns;
+#ifdef TIOCGWINSZ
+		else
+		{
+			struct winsize screen_size;
+
+			if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
+				output_columns = screen_size.ws_col;
+		}
+#endif
+	}
+
+	if (cont->opt->format == PRINT_WRAPPED)
+	{
+		/* Calculate the available width to wrap the columns to after
+		 * subtracting the maximum header width and separators. At a minimum
+		 * enough to print "[ RECORD N ]" */
+		unsigned int width, swidth;
+
+		if (opt_border == 0)
+			swidth = 1; /* "header data" */
+		else if (opt_border == 1)
+			swidth = 3; /* "header | data" */
+		else if (opt_border > 1)
+			swidth = 7; /* "| header | data |" */
+
+		/* Wrap to maximum width */
+		width = dwidth + swidth + hwidth;
+		if ((output_columns > 0) && (width > output_columns))
+		{
+			dwidth = output_columns - hwidth - swidth;
+			width = output_columns;
+		}
+
+		/* Wrap to minimum width */
+		if (!opt_tuples_only)
+		{
+			int delta = 1 + log10(cont->nrows) - width;
+			if (opt_border == 0)
+				delta += 6; /* "* RECORD " */
+			else if (opt_border == 1)
+				delta += 10; /* "-[ RECORD  ]" */
+			else if (opt_border == 2)
+				delta += 15; /* "+-[ RECORD  ]-+" */
+
+			if (delta > 0)
+				dwidth += delta;
+		}
+		else if (dwidth < 3)
+			dwidth = 3;
+	}
+
 	/* print records */
 	for (i = 0, ptr = cont->cells; *ptr; i++, ptr++)
 	{
 		printTextRule pos;
-		int			line_count,
+		int			dline,
+					hline,
 					dcomplete,
-					hcomplete;
+					hcomplete,
+					offset,
+					chars_to_output;
 
 		if (cancel_pressed)
 			break;
 
 		if (i == 0)
 			pos = PRINT_RULE_TOP;
-		else if (!(*(ptr + 1)))
-			pos = PRINT_RULE_BOTTOM;
 		else
 			pos = PRINT_RULE_MIDDLE;
 
+		/* Print record header (e.g. "[ RECORD N ]") above each record */
 		if (i % cont->ncolumns == 0)
 		{
 			if (!opt_tuples_only)
@@ -1270,48 +1333,120 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
 		pg_wcsformat((const unsigned char *) *ptr, strlen(*ptr), encoding,
 					 dlineptr, dheight);
 
-		line_count = 0;
+		/* Loop through header and data in parallel dealing with newlines and
+		 * wrapped lines until they're both exhausted */
+		dline = hline = 0;
 		dcomplete = hcomplete = 0;
+		offset = 0;
+		chars_to_output = dlineptr[dline].width;
 		while (!dcomplete || !hcomplete)
 		{
+			/* Left border */
 			if (opt_border == 2)
-				fprintf(fout, "%s ", dformat->leftvrule);
+				fprintf(fout, "%s", dformat->leftvrule);
+
+			/* Header (never wrapped so just need to deal with newlines) */
 			if (!hcomplete)
 			{
-				fprintf(fout, "%-s%*s", hlineptr[line_count].ptr,
-						hwidth - hlineptr[line_count].width, "");
+				int swidth, twidth = hwidth + 1;
+				fputs(hline? format->header_nl_left: " ", fout);
+				strlen_max_width((char *) hlineptr[hline].ptr, &twidth,
+								 encoding);
+				fprintf(fout, "%-s", hlineptr[hline].ptr);
+
+				swidth = hwidth - twidth;
+				if (swidth > 0) /* spacer */
+					fprintf(fout, "%*s", swidth, " ");
 
-				if (!hlineptr[line_count + 1].ptr)
+				if (hlineptr[hline + 1].ptr)
+				{
+					/* More lines after this one due to a newline */
+					fputs(format->header_nl_right, fout);
+					hline++;
+				} 
+				else 
+				{
+					/* This was the last line of the header */
+					fputs(" ", fout);
 					hcomplete = 1;
+				}
 			}
 			else
-				fprintf(fout, "%*s", hwidth, "");
+			{
+				/* Header exhausted but more data for column */
+				fprintf(fout, "%*s", hwidth + 2, "");
+			}
 
+			/* Separator */
 			if (opt_border > 0)
-				fprintf(fout, " %s ", dformat->midvrule);
-			else
-				fputc(' ', fout);
+			{
+				if (offset)
+					fputs(format->midvrule_wrap, fout);
+				else if (!dline)
+					fputs(dformat->midvrule, fout);
+				else if (dline)
+					fputs(format->midvrule_nl, fout);
+				else
+					fputs(format->midvrule_blank, fout);
+			}
 
+			/* Data */
 			if (!dcomplete)
 			{
-				if (opt_border < 2)
-					fprintf(fout, "%s\n", dlineptr[line_count].ptr);
-				else
-					fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr,
-							dwidth - dlineptr[line_count].width, "",
-							dformat->rightvrule);
+				int target_width,
+					bytes_to_output,
+					swidth;
+
+				fputs(!dcomplete && !offset? " ": format->wrap_left, fout);
 
-				if (!dlineptr[line_count + 1].ptr)
+				target_width = dwidth;
+				bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset,
+												   &target_width, encoding);
+				fputnbytes(fout, (char *)(dlineptr[dline].ptr + offset),
+						   bytes_to_output);
+
+				chars_to_output -= target_width;
+				offset += bytes_to_output;
+
+				/* spacer */
+				swidth = dwidth - target_width;
+				if (swidth > 0)
+					fprintf(fout, "%*s", swidth, "");
+
+				if (chars_to_output)
+				{
+					/* continuing a wrapped column */
+					fputs(format->wrap_right, fout);
+				}
+				else if (dlineptr[dline + 1].ptr)
+				{
+					/* reached a newline in the column */
+					fputs(format->nl_right, fout);
+					dline++;
+					offset = 0;
+					chars_to_output = dlineptr[dline].width;
+				}
+				else
+				{
+					/* reached the end of the cell */
+					fputs(" ", fout);
 					dcomplete = 1;
+				}
+
+				if (opt_border == 2)
+					fputs(dformat->rightvrule, fout);
+
+				fputs("\n", fout);
 			}
 			else
 			{
+				/* data exhausted (this can occur if header is longer than the
+				 * data due to newlines in the header) */
 				if (opt_border < 2)
-					fputc('\n', fout);
+					fputs("\n", fout);
 				else
-					fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule);
+					fprintf(fout, "%*s  %s\n", dwidth, "", dformat->rightvrule);
 			}
-			line_count++;
 		}
 	}
 
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 2bbee7d..c7dbd54 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -68,3 +68,947 @@ Record separator (recordsep) is <newline>.
 Table attributes (tableattr) unset.
 Title (title) unset.
 Tuples only (tuples_only) is off.
+-- test multi-line headers, wrapping, and newline indicators
+prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "a
+
+b", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a
+b" from generate_series(1,10) as n(n) group by n>1 ;
+\pset linestyle ascii
+\pset expanded off
+\pset columns 40
+\pset border 0
+\pset format unaligned
+execute q;
+a
+
+b|a
+b
+xx|yyyyyyyyyyyyyyyyyy
+xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+(2 rows)
+\pset format aligned
+execute q;
+         a          +        a         +
+                    +        b          
+         b                              
+-------------------- ------------------
+xx                   yyyyyyyyyyyyyyyyyy
+xxxx                +yyyyyyyyyyyyyyyy  +
+xxxxxx              +yyyyyyyyyyyyyy    +
+xxxxxxxx            +yyyyyyyyyyyy      +
+xxxxxxxxxx          +yyyyyyyyyy        +
+xxxxxxxxxxxx        +yyyyyyyy          +
+xxxxxxxxxxxxxx      +yyyyyy            +
+xxxxxxxxxxxxxxxx    +yyyy              +
+xxxxxxxxxxxxxxxxxx  +yy                +
+xxxxxxxxxxxxxxxxxxxx 
+(2 rows)
+
+\pset format wrapped
+execute q;
+         a          +        a         +
+                    +        b          
+         b                              
+-------------------- ------------------
+xx                   yyyyyyyyyyyyyyyyyy
+xxxx                +yyyyyyyyyyyyyyyy  +
+xxxxxx              +yyyyyyyyyyyyyy    +
+xxxxxxxx            +yyyyyyyyyyyy      +
+xxxxxxxxxx          +yyyyyyyyyy        +
+xxxxxxxxxxxx        +yyyyyyyy          +
+xxxxxxxxxxxxxx      +yyyyyy            +
+xxxxxxxxxxxxxxxx    +yyyy              +
+xxxxxxxxxxxxxxxxxx  +yy                +
+xxxxxxxxxxxxxxxxxxxx 
+(2 rows)
+
+\pset border 1
+\pset format unaligned
+execute q;
+a
+
+b|a
+b
+xx|yyyyyyyyyyyyyyyyyy
+xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+(2 rows)
+\pset format aligned
+execute q;
+          a          +|         a         +
+                     +|         b          
+          b           |                    
+----------------------+--------------------
+ xx                   | yyyyyyyyyyyyyyyyyy
+ xxxx                +| yyyyyyyyyyyyyyyy  +
+ xxxxxx              +| yyyyyyyyyyyyyy    +
+ xxxxxxxx            +| yyyyyyyyyyyy      +
+ xxxxxxxxxx          +| yyyyyyyyyy        +
+ xxxxxxxxxxxx        +| yyyyyyyy          +
+ xxxxxxxxxxxxxx      +| yyyyyy            +
+ xxxxxxxxxxxxxxxx    +| yyyy              +
+ xxxxxxxxxxxxxxxxxx  +| yy                +
+ xxxxxxxxxxxxxxxxxxxx | 
+(2 rows)
+
+\pset format wrapped
+execute q;
+         a        +|         a         +
+                  +|         b          
+         b         |                    
+-------------------+--------------------
+ xx                | yyyyyyyyyyyyyyyyyy
+ xxxx             +| yyyyyyyyyyyyyyyy  +
+ xxxxxx           +| yyyyyyyyyyyyyy    +
+ xxxxxxxx         +| yyyyyyyyyyyy      +
+ xxxxxxxxxx       +| yyyyyyyyyy        +
+ xxxxxxxxxxxx     +| yyyyyyyy          +
+ xxxxxxxxxxxxxx   +| yyyyyy            +
+ xxxxxxxxxxxxxxxx +| yyyy              +
+ xxxxxxxxxxxxxxxxx.| yy                +
+.x                +| 
+ xxxxxxxxxxxxxxxxx.| 
+.xxx               | 
+(2 rows)
+
+\pset border 2
+\pset format unaligned
+execute q;
+a
+
+b|a
+b
+xx|yyyyyyyyyyyyyyyyyy
+xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+(2 rows)
+\pset format aligned
+execute q;
++----------------------+--------------------+
+|          a          +|         a         +|
+|                     +|         b          |
+|          b           |                    |
++----------------------+--------------------+
+| xx                   | yyyyyyyyyyyyyyyyyy |
+| xxxx                +| yyyyyyyyyyyyyyyy  +|
+| xxxxxx              +| yyyyyyyyyyyyyy    +|
+| xxxxxxxx            +| yyyyyyyyyyyy      +|
+| xxxxxxxxxx          +| yyyyyyyyyy        +|
+| xxxxxxxxxxxx        +| yyyyyyyy          +|
+| xxxxxxxxxxxxxx      +| yyyyyy            +|
+| xxxxxxxxxxxxxxxx    +| yyyy              +|
+| xxxxxxxxxxxxxxxxxx  +| yy                +|
+| xxxxxxxxxxxxxxxxxxxx |                    |
++----------------------+--------------------+
+(2 rows)
+
+\pset format wrapped
+execute q;
++-----------------+--------------------+
+|        a       +|         a         +|
+|                +|         b          |
+|        b        |                    |
++-----------------+--------------------+
+| xx              | yyyyyyyyyyyyyyyyyy |
+| xxxx           +| yyyyyyyyyyyyyyyy  +|
+| xxxxxx         +| yyyyyyyyyyyyyy    +|
+| xxxxxxxx       +| yyyyyyyyyyyy      +|
+| xxxxxxxxxx     +| yyyyyyyyyy        +|
+| xxxxxxxxxxxx   +| yyyyyyyy          +|
+| xxxxxxxxxxxxxx +| yyyyyy            +|
+| xxxxxxxxxxxxxxx.| yyyy              +|
+|.x              +| yy                +|
+| xxxxxxxxxxxxxxx.|                    |
+|.xxx            +|                    |
+| xxxxxxxxxxxxxxx.|                    |
+|.xxxxx           |                    |
++-----------------+--------------------+
+(2 rows)
+
+\pset expanded on
+\pset columns 20
+\pset border 0
+\pset format unaligned
+execute q;
+a
+
+b|xx
+a
+b|yyyyyyyyyyyyyyyyyy
+
+a
+
+b|xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx
+a
+b|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+\pset format aligned
+execute q;
+* Record 1           
+ a+ xx                   
+  +
+ b 
+ a+ yyyyyyyyyyyyyyyyyy   
+ b 
+* Record 2           
+ a+ xxxx                +
+  + xxxxxx              +
+ b  xxxxxxxx            +
+    xxxxxxxxxx          +
+    xxxxxxxxxxxx        +
+    xxxxxxxxxxxxxx      +
+    xxxxxxxxxxxxxxxx    +
+    xxxxxxxxxxxxxxxxxx  +
+    xxxxxxxxxxxxxxxxxxxx 
+ a+ yyyyyyyyyyyyyyyy    +
+ b  yyyyyyyyyyyyyy      +
+    yyyyyyyyyyyy        +
+    yyyyyyyyyy          +
+    yyyyyyyy            +
+    yyyyyy              +
+    yyyy                +
+    yy                  +
+                         
+
+\pset format wrapped
+execute q;
+* Record 1         
+ a+ xx                 
+  +
+ b 
+ a+ yyyyyyyyyyyyyyyyyy 
+ b 
+* Record 2         
+ a+ xxxx              +
+  + xxxxxx            +
+ b  xxxxxxxx          +
+    xxxxxxxxxx        +
+    xxxxxxxxxxxx      +
+    xxxxxxxxxxxxxx    +
+    xxxxxxxxxxxxxxxx  +
+    xxxxxxxxxxxxxxxxxx+
+    xxxxxxxxxxxxxxxxxx.
+   .xx                 
+ a+ yyyyyyyyyyyyyyyy  +
+ b  yyyyyyyyyyyyyy    +
+    yyyyyyyyyyyy      +
+    yyyyyyyyyy        +
+    yyyyyyyy          +
+    yyyyyy            +
+    yyyy              +
+    yy                +
+                       
+
+\pset border 1
+\pset format unaligned
+execute q;
+a
+
+b|xx
+a
+b|yyyyyyyyyyyyyyyyyy
+
+a
+
+b|xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx
+a
+b|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+\pset format aligned
+execute q;
+-[ RECORD 1 ]-----------
+ a+| xx                   
+  +|
+ b |
+ a+| yyyyyyyyyyyyyyyyyy   
+ b |
+-[ RECORD 2 ]-----------
+ a+| xxxx                +
+  +| xxxxxx              +
+ b | xxxxxxxx            +
+   | xxxxxxxxxx          +
+   | xxxxxxxxxxxx        +
+   | xxxxxxxxxxxxxx      +
+   | xxxxxxxxxxxxxxxx    +
+   | xxxxxxxxxxxxxxxxxx  +
+   | xxxxxxxxxxxxxxxxxxxx 
+ a+| yyyyyyyyyyyyyyyy    +
+ b | yyyyyyyyyyyyyy      +
+   | yyyyyyyyyyyy        +
+   | yyyyyyyyyy          +
+   | yyyyyyyy            +
+   | yyyyyy              +
+   | yyyy                +
+   | yy                  +
+   |                      
+
+\pset format wrapped
+execute q;
+-[ RECORD 1 ]-------
+ a+| xx               
+  +|
+ b |
+ a+| yyyyyyyyyyyyyyyy.
+ b |.yy               
+-[ RECORD 2 ]-------
+ a+| xxxx            +
+  +| xxxxxx          +
+ b | xxxxxxxx        +
+   | xxxxxxxxxx      +
+   | xxxxxxxxxxxx    +
+   | xxxxxxxxxxxxxx  +
+   | xxxxxxxxxxxxxxxx+
+   | xxxxxxxxxxxxxxxx.
+   |.xx              +
+   | xxxxxxxxxxxxxxxx.
+   |.xxxx             
+ a+| yyyyyyyyyyyyyyyy+
+ b | yyyyyyyyyyyyyy  +
+   | yyyyyyyyyyyy    +
+   | yyyyyyyyyy      +
+   | yyyyyyyy        +
+   | yyyyyy          +
+   | yyyy            +
+   | yy              +
+   |                  
+
+\pset border 2
+\pset format unaligned
+execute q;
+a
+
+b|xx
+a
+b|yyyyyyyyyyyyyyyyyy
+
+a
+
+b|xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx
+a
+b|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+\pset format aligned
+execute q;
++-[ RECORD 1 ]-------------+
+| a+| xx                   |
+|  +|                      |
+| b |                      |
+| a+| yyyyyyyyyyyyyyyyyy   |
+| b |                      |
++-[ RECORD 2 ]-------------+
+| a+| xxxx                +|
+|  +| xxxxxx              +|
+| b | xxxxxxxx            +|
+|   | xxxxxxxxxx          +|
+|   | xxxxxxxxxxxx        +|
+|   | xxxxxxxxxxxxxx      +|
+|   | xxxxxxxxxxxxxxxx    +|
+|   | xxxxxxxxxxxxxxxxxx  +|
+|   | xxxxxxxxxxxxxxxxxxxx |
+| a+| yyyyyyyyyyyyyyyy    +|
+| b | yyyyyyyyyyyyyy      +|
+|   | yyyyyyyyyyyy        +|
+|   | yyyyyyyyyy          +|
+|   | yyyyyyyy            +|
+|   | yyyyyy              +|
+|   | yyyy                +|
+|   | yy                  +|
+|   |                      |
++---+----------------------+
+
+\pset format wrapped
+execute q;
++-[ RECORD 1 ]-----+
+| a+| xx           |
+|  +|              |
+| b |              |
+| a+| yyyyyyyyyyyy.|
+| b |.yyyyyy       |
++-[ RECORD 2 ]-----+
+| a+| xxxx        +|
+|  +| xxxxxx      +|
+| b | xxxxxxxx    +|
+|   | xxxxxxxxxx  +|
+|   | xxxxxxxxxxxx+|
+|   | xxxxxxxxxxxx.|
+|   |.xx          +|
+|   | xxxxxxxxxxxx.|
+|   |.xxxx        +|
+|   | xxxxxxxxxxxx.|
+|   |.xxxxxx      +|
+|   | xxxxxxxxxxxx.|
+|   |.xxxxxxxx     |
+| a+| yyyyyyyyyyyy.|
+| b |.yyyy        +|
+|   | yyyyyyyyyyyy.|
+|   |.yy          +|
+|   | yyyyyyyyyyyy+|
+|   | yyyyyyyyyy  +|
+|   | yyyyyyyy    +|
+|   | yyyyyy      +|
+|   | yyyy        +|
+|   | yy          +|
+|   |              |
++---+--------------+
+
+\pset linestyle old-ascii
+\pset expanded off
+\pset columns 40
+\pset border 0
+\pset format unaligned
+execute q;
+a
+
+b|a
+b
+xx|yyyyyyyyyyyyyyyyyy
+xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+(2 rows)
+\pset format aligned
+execute q;
+         a                   a         
+                    +        b         
+         b          +                  
+-------------------- ------------------
+xx                   yyyyyyyyyyyyyyyyyy
+xxxx                 yyyyyyyyyyyyyyyy   
+xxxxxx               yyyyyyyyyyyyyy     
+xxxxxxxx             yyyyyyyyyyyy       
+xxxxxxxxxx           yyyyyyyyyy         
+xxxxxxxxxxxx         yyyyyyyy           
+xxxxxxxxxxxxxx       yyyyyy             
+xxxxxxxxxxxxxxxx     yyyy               
+xxxxxxxxxxxxxxxxxx   yy                 
+xxxxxxxxxxxxxxxxxxxx 
+(2 rows)
+
+\pset format wrapped
+execute q;
+         a                   a         
+                    +        b         
+         b          +                  
+-------------------- ------------------
+xx                   yyyyyyyyyyyyyyyyyy
+xxxx                 yyyyyyyyyyyyyyyy   
+xxxxxx               yyyyyyyyyyyyyy     
+xxxxxxxx             yyyyyyyyyyyy       
+xxxxxxxxxx           yyyyyyyyyy         
+xxxxxxxxxxxx         yyyyyyyy           
+xxxxxxxxxxxxxx       yyyyyy             
+xxxxxxxxxxxxxxxx     yyyy               
+xxxxxxxxxxxxxxxxxx   yy                 
+xxxxxxxxxxxxxxxxxxxx 
+(2 rows)
+
+\pset border 1
+\pset format unaligned
+execute q;
+a
+
+b|a
+b
+xx|yyyyyyyyyyyyyyyyyy
+xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+(2 rows)
+\pset format aligned
+execute q;
+          a           |         a          
++                     |+        b          
++         b           |+                   
+----------------------+--------------------
+ xx                   | yyyyyyyyyyyyyyyyyy
+ xxxx                 | yyyyyyyyyyyyyyyy   
+ xxxxxx               : yyyyyyyyyyyyyy     
+ xxxxxxxx             : yyyyyyyyyyyy       
+ xxxxxxxxxx           : yyyyyyyyyy         
+ xxxxxxxxxxxx         : yyyyyyyy           
+ xxxxxxxxxxxxxx       : yyyyyy             
+ xxxxxxxxxxxxxxxx     : yyyy               
+ xxxxxxxxxxxxxxxxxx   : yy                 
+ xxxxxxxxxxxxxxxxxxxx : 
+(2 rows)
+
+\pset format wrapped
+execute q;
+         a         |         a          
++                  |+        b          
++        b         |+                   
+-------------------+--------------------
+ xx                | yyyyyyyyyyyyyyyyyy
+ xxxx              | yyyyyyyyyyyyyyyy   
+ xxxxxx            : yyyyyyyyyyyyyy     
+ xxxxxxxx          : yyyyyyyyyyyy       
+ xxxxxxxxxx        : yyyyyyyyyy         
+ xxxxxxxxxxxx      : yyyyyyyy           
+ xxxxxxxxxxxxxx    : yyyyyy             
+ xxxxxxxxxxxxxxxx  : yyyy               
+ xxxxxxxxxxxxxxxxx : yy                 
+ x                 : 
+ xxxxxxxxxxxxxxxxx   
+ xxx                 
+(2 rows)
+
+\pset border 2
+\pset format unaligned
+execute q;
+a
+
+b|a
+b
+xx|yyyyyyyyyyyyyyyyyy
+xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+(2 rows)
+\pset format aligned
+execute q;
++----------------------+--------------------+
+|          a           |         a          |
+|+                     |+        b          |
+|+         b           |+                   |
++----------------------+--------------------+
+| xx                   | yyyyyyyyyyyyyyyyyy |
+| xxxx                 | yyyyyyyyyyyyyyyy   |
+| xxxxxx               : yyyyyyyyyyyyyy     |
+| xxxxxxxx             : yyyyyyyyyyyy       |
+| xxxxxxxxxx           : yyyyyyyyyy         |
+| xxxxxxxxxxxx         : yyyyyyyy           |
+| xxxxxxxxxxxxxx       : yyyyyy             |
+| xxxxxxxxxxxxxxxx     : yyyy               |
+| xxxxxxxxxxxxxxxxxx   : yy                 |
+| xxxxxxxxxxxxxxxxxxxx :                    |
++----------------------+--------------------+
+(2 rows)
+
+\pset format wrapped
+execute q;
++-----------------+--------------------+
+|        a        |         a          |
+|+                |+        b          |
+|+       b        |+                   |
++-----------------+--------------------+
+| xx              | yyyyyyyyyyyyyyyyyy |
+| xxxx            | yyyyyyyyyyyyyyyy   |
+| xxxxxx          : yyyyyyyyyyyyyy     |
+| xxxxxxxx        : yyyyyyyyyyyy       |
+| xxxxxxxxxx      : yyyyyyyyyy         |
+| xxxxxxxxxxxx    : yyyyyyyy           |
+| xxxxxxxxxxxxxx  : yyyyyy             |
+| xxxxxxxxxxxxxxx : yyyy               |
+| x               : yy                 |
+| xxxxxxxxxxxxxxx :                    |
+| xxx                                  |
+| xxxxxxxxxxxxxxx                      |
+| xxxxx                                |
++-----------------+--------------------+
+(2 rows)
+
+\pset expanded on
+\pset columns 20
+\pset border 0
+\pset format unaligned
+execute q;
+a
+
+b|xx
+a
+b|yyyyyyyyyyyyyyyyyy
+
+a
+
+b|xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx
+a
+b|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+\pset format aligned
+execute q;
+* Record 1           
+ a  xx                   
++  
++b 
+ a  yyyyyyyyyyyyyyyyyy   
++b 
+* Record 2           
+ a  xxxx                 
++   xxxxxx               
++b  xxxxxxxx             
+    xxxxxxxxxx           
+    xxxxxxxxxxxx         
+    xxxxxxxxxxxxxx       
+    xxxxxxxxxxxxxxxx     
+    xxxxxxxxxxxxxxxxxx   
+    xxxxxxxxxxxxxxxxxxxx 
+ a  yyyyyyyyyyyyyyyy     
++b  yyyyyyyyyyyyyy       
+    yyyyyyyyyyyy         
+    yyyyyyyyyy           
+    yyyyyyyy             
+    yyyyyy               
+    yyyy                 
+    yy                   
+                         
+
+\pset format wrapped
+execute q;
+* Record 1         
+ a  xx                 
++  
++b 
+ a  yyyyyyyyyyyyyyyyyy 
++b 
+* Record 2         
+ a  xxxx               
++   xxxxxx             
++b  xxxxxxxx           
+    xxxxxxxxxx         
+    xxxxxxxxxxxx       
+    xxxxxxxxxxxxxx     
+    xxxxxxxxxxxxxxxx   
+    xxxxxxxxxxxxxxxxxx 
+    xxxxxxxxxxxxxxxxxx 
+    xx                 
+ a  yyyyyyyyyyyyyyyy   
++b  yyyyyyyyyyyyyy     
+    yyyyyyyyyyyy       
+    yyyyyyyyyy         
+    yyyyyyyy           
+    yyyyyy             
+    yyyy               
+    yy                 
+                       
+
+\pset border 1
+\pset format unaligned
+execute q;
+a
+
+b|xx
+a
+b|yyyyyyyyyyyyyyyyyy
+
+a
+
+b|xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx
+a
+b|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+\pset format aligned
+execute q;
+-[ RECORD 1 ]-----------
+ a | xx                   
++  ;
++b ;
+ a | yyyyyyyyyyyyyyyyyy   
++b ;
+-[ RECORD 2 ]-----------
+ a | xxxx                 
++  : xxxxxx               
++b : xxxxxxxx             
+   : xxxxxxxxxx           
+   : xxxxxxxxxxxx         
+   : xxxxxxxxxxxxxx       
+   : xxxxxxxxxxxxxxxx     
+   : xxxxxxxxxxxxxxxxxx   
+   : xxxxxxxxxxxxxxxxxxxx 
+ a | yyyyyyyyyyyyyyyy     
++b : yyyyyyyyyyyyyy       
+   : yyyyyyyyyyyy         
+   : yyyyyyyyyy           
+   : yyyyyyyy             
+   : yyyyyy               
+   : yyyy                 
+   : yy                   
+   :                      
+
+\pset format wrapped
+execute q;
+-[ RECORD 1 ]-------
+ a | xx               
++  ;
++b ;
+ a | yyyyyyyyyyyyyyyy 
++b ; yy               
+-[ RECORD 2 ]-------
+ a | xxxx             
++  : xxxxxx           
++b : xxxxxxxx         
+   : xxxxxxxxxx       
+   : xxxxxxxxxxxx     
+   : xxxxxxxxxxxxxx   
+   : xxxxxxxxxxxxxxxx 
+   : xxxxxxxxxxxxxxxx 
+   ; xx               
+   : xxxxxxxxxxxxxxxx 
+   ; xxxx             
+ a | yyyyyyyyyyyyyyyy 
++b : yyyyyyyyyyyyyy   
+   : yyyyyyyyyyyy     
+   : yyyyyyyyyy       
+   : yyyyyyyy         
+   : yyyyyy           
+   : yyyy             
+   : yy               
+   :                  
+
+\pset border 2
+\pset format unaligned
+execute q;
+a
+
+b|xx
+a
+b|yyyyyyyyyyyyyyyyyy
+
+a
+
+b|xxxx
+xxxxxx
+xxxxxxxx
+xxxxxxxxxx
+xxxxxxxxxxxx
+xxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxx
+a
+b|yyyyyyyyyyyyyyyy
+yyyyyyyyyyyyyy
+yyyyyyyyyyyy
+yyyyyyyyyy
+yyyyyyyy
+yyyyyy
+yyyy
+yy
+
+\pset format aligned
+execute q;
++-[ RECORD 1 ]-------------+
+| a | xx                   |
+|+  ;                      |
+|+b ;                      |
+| a | yyyyyyyyyyyyyyyyyy   |
+|+b ;                      |
++-[ RECORD 2 ]-------------+
+| a | xxxx                 |
+|+  : xxxxxx               |
+|+b : xxxxxxxx             |
+|   : xxxxxxxxxx           |
+|   : xxxxxxxxxxxx         |
+|   : xxxxxxxxxxxxxx       |
+|   : xxxxxxxxxxxxxxxx     |
+|   : xxxxxxxxxxxxxxxxxx   |
+|   : xxxxxxxxxxxxxxxxxxxx |
+| a | yyyyyyyyyyyyyyyy     |
+|+b : yyyyyyyyyyyyyy       |
+|   : yyyyyyyyyyyy         |
+|   : yyyyyyyyyy           |
+|   : yyyyyyyy             |
+|   : yyyyyy               |
+|   : yyyy                 |
+|   : yy                   |
+|   :                      |
++---+----------------------+
+
+\pset format wrapped
+execute q;
++-[ RECORD 1 ]-----+
+| a | xx           |
+|+  ;              |
+|+b ;              |
+| a | yyyyyyyyyyyy |
+|+b ; yyyyyy       |
++-[ RECORD 2 ]-----+
+| a | xxxx         |
+|+  : xxxxxx       |
+|+b : xxxxxxxx     |
+|   : xxxxxxxxxx   |
+|   : xxxxxxxxxxxx |
+|   : xxxxxxxxxxxx |
+|   ; xx           |
+|   : xxxxxxxxxxxx |
+|   ; xxxx         |
+|   : xxxxxxxxxxxx |
+|   ; xxxxxx       |
+|   : xxxxxxxxxxxx |
+|   ; xxxxxxxx     |
+| a | yyyyyyyyyyyy |
+|+b ; yyyy         |
+|   : yyyyyyyyyyyy |
+|   ; yy           |
+|   : yyyyyyyyyyyy |
+|   : yyyyyyyyyy   |
+|   : yyyyyyyy     |
+|   : yyyyyy       |
+|   : yyyy         |
+|   : yy           |
+|   :              |
++---+--------------+
+
+deallocate q;
diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql
index 99ad5b4..a7d5eeb 100644
--- a/src/test/regress/sql/psql.sql
+++ b/src/test/regress/sql/psql.sql
@@ -40,3 +40,123 @@ select 10 as test01, 20 as test02 from generate_series(1,0) \gset
 
 -- show all pset options
 \pset
+
+-- test multi-line headers, wrapping, and newline indicators
+prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "a
+
+b", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a
+b" from generate_series(1,10) as n(n) group by n>1 ;
+
+\pset linestyle ascii
+
+\pset expanded off
+\pset columns 40
+
+\pset border 0
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 1
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 2
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset expanded on
+\pset columns 20
+
+\pset border 0
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 1
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 2
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset linestyle old-ascii
+
+\pset expanded off
+\pset columns 40
+
+\pset border 0
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 1
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 2
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset expanded on
+\pset columns 20
+
+\pset border 0
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 1
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+\pset border 2
+\pset format unaligned
+execute q;
+\pset format aligned
+execute q;
+\pset format wrapped
+execute q;
+
+deallocate q;
-- 
1.8.5.rc2.dirty

-- 
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