Re: Patch to change psql default banner v6

Guillaume Lelarge <[email protected]>
Newsgroups gmane.comp.db.postgresql.devel.patches
Message-ID <[email protected]>
Bryce Nesbitt a écrit :
> Guillaume Lelarge wrote:
>> Here is a patch that tries to implement this. Meta-commands should 
>> work from 7.4 to 8.4-devel releases. It was not hard to do, and I 
>> don't think it really is a burden to maintain.
>>
>> One part left to fix is \du and \dg commands. I would be glad to 
>> continue to work on this but I would prefer to have comments before.
> Good work!  I submitted a similar patch also.

Yes, I've seen that.

> For your patch I have one critique: the version sensitive code is 
> scattered all through describe.c.  Are there opportunities to apply some 
> tests at a higher level (reducing the number of tests), or gather the 
> tests into an easily maintainable chunk?
> 

I can't find an easy way to do this. And question is: is it really 
interesting to do this? I'm not sure it's worth it. If you want to work 
on this and patch my patch, you're welcome :)

> The cleaner it is, the more likely future patchers will continue to 
> maintain compatibility.
> 

+1

Attached is a new version of the patch. It fixes a few issues when one 
adds a pattern to metacommands.

Regards.


-- 
Guillaume.
  http://www.postgresqlfr.org
  http://dalibo.com


-- 
Sent via pgsql-patches mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches
psql_v2.patch (text/x-patch, 24 KB)
Index: src/bin/psql/describe.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/src/bin/psql/describe.c,v
retrieving revision 1.173
diff -c -c -r1.173 describe.c
*** src/bin/psql/describe.c	13 May 2008 00:23:17 -0000	1.173
--- src/bin/psql/describe.c	20 May 2008 19:33:27 -0000
***************
*** 59,68 ****
  	 * There are two kinds of aggregates: ones that work on particular types
  	 * and ones that work on all (denoted by input type = "any")
  	 */
  	printfPQExpBuffer(&buf,
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  p.proname AS \"%s\",\n"
! 				  "  pg_catalog.format_type(p.prorettype, NULL) AS \"%s\",\n"
  					  "  CASE WHEN p.pronargs = 0\n"
  					  "    THEN CAST('*' AS pg_catalog.text)\n"
  					  "    ELSE\n"
--- 59,75 ----
  	 * There are two kinds of aggregates: ones that work on particular types
  	 * and ones that work on all (denoted by input type = "any")
  	 */
+     
  	printfPQExpBuffer(&buf,
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  p.proname AS \"%s\",\n"
! 					  "  pg_catalog.format_type(p.prorettype, NULL) AS \"%s\"",
! 					  gettext_noop("Schema"),
! 					  gettext_noop("Name"),
! 					  gettext_noop("Result data type"));
! 	
! 	if (pset.sversion >= 80100)				  
! 	    appendPQExpBuffer(&buf, ",\n"
  					  "  CASE WHEN p.pronargs = 0\n"
  					  "    THEN CAST('*' AS pg_catalog.text)\n"
  					  "    ELSE\n"
***************
*** 72,86 ****
  					  "      FROM\n"
  					  "        pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
  					  "    ), ', ')\n"
! 					  "  END AS \"%s\",\n"
! 				 "  pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
  					  "FROM pg_catalog.pg_proc p\n"
  	   "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
  					  "WHERE p.proisagg\n",
- 					  gettext_noop("Schema"),
- 					  gettext_noop("Name"),
- 					  gettext_noop("Result data type"),
- 					  gettext_noop("Argument data types"),
  					  gettext_noop("Description"));
  
  	processSQLNamePattern(pset.db, &buf, pattern, true, false,
--- 79,91 ----
  					  "      FROM\n"
  					  "        pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
  					  "    ), ', ')\n"
! 					  "  END AS \"%s\"",
! 					  gettext_noop("Argument data types"));
! 					  
! 	appendPQExpBuffer(&buf, ",\n  pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
  					  "FROM pg_catalog.pg_proc p\n"
  	   "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
  					  "WHERE p.proisagg\n",
  					  gettext_noop("Description"));
  
  	processSQLNamePattern(pset.db, &buf, pattern, true, false,
***************
*** 132,142 ****
  					  gettext_noop("Location"));
  
  	if (verbose)
  		appendPQExpBuffer(&buf,
! 						  ",\n  spcacl AS \"%s\""
! 		 ",\n  pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
! 						  gettext_noop("Access privileges"),
  						  gettext_noop("Description"));
  
  	appendPQExpBuffer(&buf,
  					  "\nFROM pg_catalog.pg_tablespace\n");
--- 137,151 ----
  					  gettext_noop("Location"));
  
  	if (verbose)
+ 	{
  		appendPQExpBuffer(&buf,
! 						  ",\n  spcacl AS \"%s\"",
! 						  gettext_noop("Access privileges"));
!         if (pset.sversion >= 80200)
! 		    appendPQExpBuffer(&buf,
!                           ",\n  pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
  						  gettext_noop("Description"));
+     }
  
  	appendPQExpBuffer(&buf,
  					  "\nFROM pg_catalog.pg_tablespace\n");
***************
*** 179,186 ****
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  p.proname as \"%s\",\n"
  					  "  CASE WHEN p.proretset THEN 'setof ' ELSE '' END ||\n"
! 				  "  pg_catalog.format_type(p.prorettype, NULL) as \"%s\",\n"
! 					  "  CASE WHEN proallargtypes IS NOT NULL THEN\n"
  					  "    pg_catalog.array_to_string(ARRAY(\n"
  					  "      SELECT\n"
  					  "        CASE\n"
--- 188,201 ----
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  p.proname as \"%s\",\n"
  					  "  CASE WHEN p.proretset THEN 'setof ' ELSE '' END ||\n"
! 				  "  pg_catalog.format_type(p.prorettype, NULL) as \"%s\"",
! 					  gettext_noop("Schema"),
! 					  gettext_noop("Name"),
! 					  gettext_noop("Result data type"));
!     
!     if (pset.sversion >= 80100)
! 		appendPQExpBuffer(&buf,
! 					  ",\n  CASE WHEN proallargtypes IS NOT NULL THEN\n"
  					  "    pg_catalog.array_to_string(ARRAY(\n"
  					  "      SELECT\n"
  					  "        CASE\n"
***************
*** 208,216 ****
  					  "        pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
  					  "    ), ', ')\n"
  					  "  END AS \"%s\"",
- 					  gettext_noop("Schema"),
- 					  gettext_noop("Name"),
- 					  gettext_noop("Result data type"),
  					  gettext_noop("Argument data types"));
  
  	if (verbose)
--- 223,228 ----
***************
*** 220,226 ****
  						  "  WHEN p.provolatile = 's' THEN 'stable'\n"
  						  "  WHEN p.provolatile = 'v' THEN 'volatile'\n"
  						  "END as \"%s\""
! 						  ",\n  r.rolname as \"%s\",\n"
  						  "  l.lanname as \"%s\",\n"
  						  "  p.prosrc as \"%s\",\n"
  				  "  pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
--- 232,238 ----
  						  "  WHEN p.provolatile = 's' THEN 'stable'\n"
  						  "  WHEN p.provolatile = 'v' THEN 'volatile'\n"
  						  "END as \"%s\""
! 						  ",\n  pg_catalog.pg_get_userbyid(proowner) as \"%s\",\n"
  						  "  l.lanname as \"%s\",\n"
  						  "  p.prosrc as \"%s\",\n"
  				  "  pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
***************
*** 238,245 ****
  		appendPQExpBuffer(&buf,
  						  "\nFROM pg_catalog.pg_proc p"
  		"\n     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace"
! 			 "\n     LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang"
! 				"\n     JOIN pg_catalog.pg_roles r ON r.oid = p.proowner\n");
  
  	/*
  	 * we skip in/out funcs by excluding functions that take or return cstring
--- 250,256 ----
  		appendPQExpBuffer(&buf,
  						  "\nFROM pg_catalog.pg_proc p"
  		"\n     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace"
! 			 "\n     LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
  
  	/*
  	 * we skip in/out funcs by excluding functions that take or return cstring
***************
*** 254,260 ****
  						  "n.nspname", "p.proname", NULL,
  						  "pg_catalog.pg_function_is_visible(p.oid)");
  
! 	appendPQExpBuffer(&buf, "ORDER BY 1, 2, 3, 4;");
  
  	res = PSQLexec(buf.data, false);
  	termPQExpBuffer(&buf);
--- 265,273 ----
  						  "n.nspname", "p.proname", NULL,
  						  "pg_catalog.pg_function_is_visible(p.oid)");
  
! 	appendPQExpBuffer(&buf, "ORDER BY 1, 2, 3");
! 	if (pset.sversion >= 80100)
!         appendPQExpBuffer(&buf, ", 4;");
  
  	res = PSQLexec(buf.data, false);
  	termPQExpBuffer(&buf);
***************
*** 292,298 ****
  					  gettext_noop("Schema"),
  					  gettext_noop("Name"));
  	if (verbose)
! 		appendPQExpBuffer(&buf,
  						  "  t.typname AS \"%s\",\n"
  						  "  CASE WHEN t.typrelid != 0\n"
  						  "      THEN CAST('tuple' AS pg_catalog.text)\n"
--- 305,327 ----
  					  gettext_noop("Schema"),
  					  gettext_noop("Name"));
  	if (verbose)
! 	{
!     	if (pset.sversion < 80300)
! 	    {
! 		    appendPQExpBuffer(&buf,
! 						  "  t.typname AS \"%s\",\n"
! 						  "  CASE WHEN t.typrelid != 0\n"
! 						  "      THEN CAST('tuple' AS pg_catalog.text)\n"
! 						  "    WHEN t.typlen < 0\n"
! 						  "      THEN CAST('var' AS pg_catalog.text)\n"
! 						  "    ELSE CAST(t.typlen AS pg_catalog.text)\n"
! 						  "  END AS \"%s\",\n",
! 						  gettext_noop("Internal name"),
! 						  gettext_noop("Size"));
!         }
!         else
!         {
! 		    appendPQExpBuffer(&buf,
  						  "  t.typname AS \"%s\",\n"
  						  "  CASE WHEN t.typrelid != 0\n"
  						  "      THEN CAST('tuple' AS pg_catalog.text)\n"
***************
*** 312,317 ****
--- 341,348 ----
  						  gettext_noop("Internal name"),
  						  gettext_noop("Size"),
  						  gettext_noop("Elements"));
+         }
+     }
  						  
  	appendPQExpBuffer(&buf,
  					  "  pg_catalog.obj_description(t.oid, 'pg_type') as \"%s\"\n",
***************
*** 419,425 ****
  
  	printfPQExpBuffer(&buf,
  					  "SELECT d.datname as \"%s\",\n"
! 					  "       r.rolname as \"%s\",\n"
  					  "       pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n"
  					  "       d.datacl as \"%s\"",
  					  gettext_noop("Name"),
--- 450,456 ----
  
  	printfPQExpBuffer(&buf,
  					  "SELECT d.datname as \"%s\",\n"
! 					  "       pg_catalog.pg_get_userbyid(d.datdba) as \"%s\",\n"
  					  "       pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n"
  					  "       d.datacl as \"%s\"",
  					  gettext_noop("Name"),
***************
*** 428,450 ****
  					  gettext_noop("Access Privileges"));
  	if (verbose)
  	{
! 		appendPQExpBuffer(&buf,
  						  ",\n       CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
  						  "            THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
  						  "            ELSE 'No Access'\n"
  						  "       END as \"%s\"",
  						  gettext_noop("Size"));
! 		appendPQExpBuffer(&buf,
  						  ",\n       t.spcname as \"%s\"",
  						  gettext_noop("Tablespace"));
! 		appendPQExpBuffer(&buf,
  						  ",\n       pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
  						  gettext_noop("Description"));
  	}
  	appendPQExpBuffer(&buf,
! 					  "\nFROM pg_catalog.pg_database d"
! 					  "\n  JOIN pg_catalog.pg_roles r ON d.datdba = r.oid\n");
! 	if (verbose)
  		appendPQExpBuffer(&buf,
  		   "  JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
  	appendPQExpBuffer(&buf, "ORDER BY 1;");
--- 459,483 ----
  					  gettext_noop("Access Privileges"));
  	if (verbose)
  	{
! 	    if (pset.sversion >= 80200)
!     		appendPQExpBuffer(&buf,
  						  ",\n       CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
  						  "            THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
  						  "            ELSE 'No Access'\n"
  						  "       END as \"%s\"",
  						  gettext_noop("Size"));
!         if (pset.sversion >= 80100)
!     		appendPQExpBuffer(&buf,
  						  ",\n       t.spcname as \"%s\"",
  						  gettext_noop("Tablespace"));
!         if (pset.sversion >= 80200)
! 		    appendPQExpBuffer(&buf,
  						  ",\n       pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
  						  gettext_noop("Description"));
  	}
  	appendPQExpBuffer(&buf,
! 					  "\nFROM pg_catalog.pg_database d\n");
! 	if (verbose && pset.sversion >= 80100)
  		appendPQExpBuffer(&buf,
  		   "  JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
  	appendPQExpBuffer(&buf, "ORDER BY 1;");
***************
*** 484,499 ****
  	printfPQExpBuffer(&buf,
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  c.relname as \"%s\",\n"
! 					  "  CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'S' THEN '%s' END as \"%s\",\n"
! 					  "  pg_catalog.array_to_string(c.relacl, E'\\n') as \"%s\"\n"
! 					  "FROM pg_catalog.pg_class c\n"
! 	   "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
! 					  "WHERE c.relkind IN ('r', 'v', 'S')\n",
  					  gettext_noop("Schema"),
  					  gettext_noop("Name"),
  					  gettext_noop("table"), gettext_noop("view"), gettext_noop("sequence"),
! 					  gettext_noop("Type"),
  					  gettext_noop("Access privileges"));
  
  	/*
  	 * Unless a schema pattern is specified, we suppress system and temp
--- 517,538 ----
  	printfPQExpBuffer(&buf,
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  c.relname as \"%s\",\n"
! 					  "  CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'S' THEN '%s' END as \"%s\",\n",
  					  gettext_noop("Schema"),
  					  gettext_noop("Name"),
  					  gettext_noop("table"), gettext_noop("view"), gettext_noop("sequence"),
! 					  gettext_noop("Type"));
! 					  
!     if (pset.sversion >= 80100)
! 	    appendPQExpBuffer(&buf, "  pg_catalog.array_to_string(c.relacl, E'\\n') as \"%s\"\n",
! 					  gettext_noop("Access privileges"));
!     else
! 	    appendPQExpBuffer(&buf, "  pg_catalog.array_to_string(c.relacl, '\n') as \"%s\"\n",
  					  gettext_noop("Access privileges"));
+ 	    
+ 	appendPQExpBuffer(&buf, "FROM pg_catalog.pg_class c\n"
+ 	   "     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
+ 					  "WHERE c.relkind IN ('r', 'v', 'S')\n");
  
  	/*
  	 * Unless a schema pattern is specified, we suppress system and temp
***************
*** 984,990 ****
  		PGresult   *result;
  
  		printfPQExpBuffer(&buf,
! 						  "SELECT i.indisunique, i.indisprimary, i.indisclustered, i.indisvalid, a.amname, c2.relname,\n"
  					"  pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
  						  "FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
  		  "WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
--- 1023,1035 ----
  		PGresult   *result;
  
  		printfPQExpBuffer(&buf,
! 						  "SELECT i.indisunique, i.indisprimary, i.indisclustered, ");
!         if (pset.sversion < 80000)
!         	appendPQExpBuffer(&buf, "true as indisvalid, ");
!         else
!         	appendPQExpBuffer(&buf, "i.indisvalid, ");
! 
! 		appendPQExpBuffer(&buf, "a.amname, c2.relname,\n"
  					"  pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
  						  "FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
  		  "WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
***************
*** 1086,1093 ****
  		if (tableinfo.hasindex)
  		{
  			printfPQExpBuffer(&buf,
! 							  "SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, "
! 							  "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true), c2.reltablespace\n"
  							  "FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n"
  							  "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
  			  "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
--- 1131,1143 ----
  		if (tableinfo.hasindex)
  		{
  			printfPQExpBuffer(&buf,
! 							  "SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, ");
!             if (pset.sversion < 80000)
!             	appendPQExpBuffer(&buf, "true as indisvalid, ");
!             else
!         	    appendPQExpBuffer(&buf, "i.indisvalid, c2.reltablespace, ");
! 
! 		    appendPQExpBuffer(&buf, "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)\n"
  							  "FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n"
  							  "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
  			  "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
***************
*** 1134,1140 ****
  					printTableAddFooter(&cont, buf.data);
  
  					/* Print tablespace of the index on the same line */
! 					add_tablespace_footer(&cont, 'i',
  										  atooid(PQgetvalue(result, i, 6)),
  										  false);
  				}
--- 1184,1191 ----
  					printTableAddFooter(&cont, buf.data);
  
  					/* Print tablespace of the index on the same line */
! 					if (pset.sversion >= 80000)
! 					    add_tablespace_footer(&cont, 'i',
  										  atooid(PQgetvalue(result, i, 6)),
  										  false);
  				}
***************
*** 1572,1578 ****
  
  	initPQExpBuffer(&buf);
  
! 	appendPQExpBufferStr(&buf,
  					     "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
  						 "  r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
  						 "  r.rolconnlimit,\n"
--- 1623,1645 ----
  
  	initPQExpBuffer(&buf);
  
! 	if (pset.sversion < 80100)
! 	{
! 	    appendPQExpBufferStr(&buf,
! 					  "SELECT u.usename AS rolname,\n"
! 					  "  u.usesuper AS rolsuper,\n"
! 					  "  FALSE AS rolinherit, FALSE AS rolcreaterole,\n"
! 					  "  usecreatedb AS rolcreatedb, TRUE AS rolcanlogin,\n"
! 					  "  -1 AS rolconnlimit,\n"
! 					  "  ARRAY(SELECT g.groname FROM pg_catalog.pg_group g WHERE u.usesysid = ANY(g.grolist)) as memberof\n"
! 					  "FROM pg_catalog.pg_user u\n");
! 
!     	processSQLNamePattern(pset.db, &buf, pattern, false, false,
! 						  NULL, "u.usename", NULL, NULL);
!     }
!     else
!     {
!     	appendPQExpBufferStr(&buf,
  					     "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
  						 "  r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
  						 "  r.rolconnlimit,\n"
***************
*** 1581,1596 ****
  					     "        JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
  					     "        WHERE m.member = r.oid) as memberof");
  
! 	if (verbose)
! 	{
! 		appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
! 		ncols++;
! 	}
  
! 	appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_roles r\n");
  
! 	processSQLNamePattern(pset.db, &buf, pattern, false, false,
  						  NULL, "r.rolname", NULL, NULL);
  
  	appendPQExpBuffer(&buf, "ORDER BY 1;");
  
--- 1648,1664 ----
  					     "        JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
  					     "        WHERE m.member = r.oid) as memberof");
  
!     	if (pset.sversion >= 80200 && verbose)
! 	    {
! 		    appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
! 		    ncols++;
! 	    }
  
!     	appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_roles r\n");
  
!     	processSQLNamePattern(pset.db, &buf, pattern, false, false,
  						  NULL, "r.rolname", NULL, NULL);
+     }
  
  	appendPQExpBuffer(&buf, "ORDER BY 1;");
  
***************
*** 1607,1613 ****
  	printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
  	printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
  
! 	if (verbose)
  		printTableAddHeader(&cont, gettext_noop("Description"), true, align);
  
  	for (i = 0; i < nrows; i++)
--- 1675,1681 ----
  	printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
  	printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
  
! 	if (pset.sversion >= 80200 && verbose)
  		printTableAddHeader(&cont, gettext_noop("Description"), true, align);
  
  	for (i = 0; i < nrows; i++)
***************
*** 1650,1656 ****
  
  		printTableAddCell(&cont, PQgetvalue(res, i, 7), false);
  
! 		if (verbose)
  			printTableAddCell(&cont, PQgetvalue(res, i, 8), false);
  	}
  	termPQExpBuffer(&buf);
--- 1718,1724 ----
  
  		printTableAddCell(&cont, PQgetvalue(res, i, 7), false);
  
! 		if (pset.sversion >= 80200 && verbose)
  			printTableAddCell(&cont, PQgetvalue(res, i, 8), false);
  	}
  	termPQExpBuffer(&buf);
***************
*** 1716,1722 ****
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  c.relname as \"%s\",\n"
  					  "  CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'i' THEN '%s' WHEN 'S' THEN '%s' WHEN 's' THEN '%s' END as \"%s\",\n"
! 					  "  r.rolname as \"%s\"",
  					  gettext_noop("Schema"),
  					  gettext_noop("Name"),
  					  gettext_noop("table"), gettext_noop("view"), gettext_noop("index"), gettext_noop("sequence"), gettext_noop("special"),
--- 1784,1790 ----
  					  "SELECT n.nspname as \"%s\",\n"
  					  "  c.relname as \"%s\",\n"
  					  "  CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'i' THEN '%s' WHEN 'S' THEN '%s' WHEN 's' THEN '%s' END as \"%s\",\n"
! 					  "  pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
  					  gettext_noop("Schema"),
  					  gettext_noop("Name"),
  					  gettext_noop("table"), gettext_noop("view"), gettext_noop("index"), gettext_noop("sequence"), gettext_noop("special"),
***************
*** 1730,1738 ****
  
  	if (verbose)
  	{
! 		appendPQExpBuffer(&buf,
  						  ",\n  pg_catalog.pg_size_pretty(pg_catalog.pg_relation_size(c.oid)) as \"%s\"",
  					  	  gettext_noop("Size"));
  		appendPQExpBuffer(&buf,
  			  ",\n  pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
  						  gettext_noop("Description"));
--- 1798,1809 ----
  
  	if (verbose)
  	{
! 	    if (pset.sversion >= 80100)
! 	    {
!             appendPQExpBuffer(&buf,
  						  ",\n  pg_catalog.pg_size_pretty(pg_catalog.pg_relation_size(c.oid)) as \"%s\"",
  					  	  gettext_noop("Size"));
+         }
  		appendPQExpBuffer(&buf,
  			  ",\n  pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
  						  gettext_noop("Description"));
***************
*** 1740,1746 ****
  
  	appendPQExpBuffer(&buf,
  					  "\nFROM pg_catalog.pg_class c"
- 					"\n     JOIN pg_catalog.pg_roles r ON r.oid = c.relowner"
  	 "\n     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
  	if (showIndexes)
  		appendPQExpBuffer(&buf,
--- 1811,1816 ----
***************
*** 1985,1991 ****
  	initPQExpBuffer(&buf);
  	printfPQExpBuffer(&buf,
  					  "SELECT n.nspname AS \"%s\",\n"
! 					  "       r.rolname AS \"%s\"",
  					  gettext_noop("Name"),
  					  gettext_noop("Owner"));
  
--- 2055,2061 ----
  	initPQExpBuffer(&buf);
  	printfPQExpBuffer(&buf,
  					  "SELECT n.nspname AS \"%s\",\n"
! 					  "       pg_catalog.pg_get_userbyid(nspowner) AS \"%s\"",
  					  gettext_noop("Name"),
  					  gettext_noop("Owner"));
  
***************
*** 1997,2004 ****
  						  gettext_noop("Description"));
  
  	appendPQExpBuffer(&buf,
! 			  "\nFROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_roles r\n"
! 					  "       ON n.nspowner=r.oid\n"
  					  "WHERE	(n.nspname !~ '^pg_temp_' OR\n"
  		   "		 n.nspname = (pg_catalog.current_schemas(true))[1])\n");		/* temp schema is first */
  
--- 2067,2073 ----
  						  gettext_noop("Description"));
  
  	appendPQExpBuffer(&buf,
! 			  "\nFROM pg_catalog.pg_namespace n\n"
  					  "WHERE	(n.nspname !~ '^pg_temp_' OR\n"
  		   "		 n.nspname = (pg_catalog.current_schemas(true))[1])\n");		/* temp schema is first */
  
***************
*** 2035,2040 ****
--- 2104,2116 ----
  	PGresult   *res;
  	printQueryOpt myopt = pset.popt;
  
+ 	if (pset.sversion < 80300)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text parsers.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 
  	if (verbose)
  		return listTSParsersVerbose(pattern);
  
***************
*** 2083,2088 ****
--- 2159,2171 ----
  	PGresult   *res;
  	int			i;
  
+ 	if (pset.sversion < 80300)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text parser.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 
  	initPQExpBuffer(&buf);
  
  	printfPQExpBuffer(&buf,
***************
*** 2150,2155 ****
--- 2233,2245 ----
  	printQueryOpt myopt = pset.popt;
  	static const bool trans_columns[] = {true, false, false};
  
+ 	if (pset.sversion < 80000)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text parser.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 
  	initPQExpBuffer(&buf);
  
  	printfPQExpBuffer(&buf,
***************
*** 2261,2266 ****
--- 2351,2363 ----
  	PGresult   *res;
  	printQueryOpt myopt = pset.popt;
  
+ 	if (pset.sversion < 80300)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text dictionary.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 
  	initPQExpBuffer(&buf);
  
  	printfPQExpBuffer(&buf,
***************
*** 2322,2327 ****
--- 2419,2431 ----
  	PGresult   *res;
  	printQueryOpt myopt = pset.popt;
  
+ 	if (pset.sversion < 80300)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text template.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 
  	initPQExpBuffer(&buf);
  
  	if (verbose)
***************
*** 2383,2388 ****
--- 2487,2499 ----
  	PGresult   *res;
  	printQueryOpt myopt = pset.popt;
  
+ 	if (pset.sversion < 80300)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text config.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 	
  	if (verbose)
  		return listTSConfigsVerbose(pattern);
  
***************
*** 2428,2433 ****
--- 2539,2551 ----
  	PGresult   *res;
  	int			i;
  
+ 	if (pset.sversion < 80300)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text config.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 
  	initPQExpBuffer(&buf);
  
  	printfPQExpBuffer(&buf,
***************
*** 2504,2509 ****
--- 2622,2634 ----
  	PGresult   *res;
  	printQueryOpt myopt = pset.popt;
  
+ 	if (pset.sversion < 80300)
+ 	{
+ 		fprintf(stderr, _("The server version (%d) does not support full text config.\n"),
+ 				pset.sversion);
+ 		return true;
+ 	}
+ 
  	initPQExpBuffer(&buf);
  
  	printfPQExpBuffer(&buf,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.