Hello,

While working through the documentation I found an empty cell in the table for the large objects privilege display with the psql command [1]. And indeed the \dl command does not show privileges. And there is no modifier + for it.

This patch adds a + modifier to the \dl command and also to the \lo_list command to display privilege information on large objects.

I decided to move the do_lo_list function to describe.c in order to use the printACLColumn helper function. And at the same time I renamed do_lo_list to listLargeObjects to unify with the names of other similar functions.

I don't like how I handled the + modifier in the \lo_list command. But I don't know how to do better now. This is the second time I've programmed in C. The first time was the 'Hello World' program. So maybe something is done wrong.

If it's interesting, I can add the patch to commitfest.

1. https://www.postgresql.org/docs/devel/ddl-priv.html#PRIVILEGES-SUMMARY-TABLE

--
Pavel Luzanov
Postgres Professional: https://postgrespro.com
The Russian Postgres Company

diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index e0ffb020bf..374515bcb2 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -2094,7 +2094,7 @@ REVOKE ALL ON accounts FROM PUBLIC;
       <entry><literal>LARGE OBJECT</literal></entry>
       <entry><literal>rw</literal></entry>
       <entry>none</entry>
-      <entry></entry>
+      <entry><literal>\dl+</literal></entry>
      </row>
      <row>
       <entry><literal>SCHEMA</literal></entry>
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index fcab5c0d51..de47ef528e 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1681,11 +1681,13 @@ testdb=&gt;
 
 
       <varlistentry>
-        <term><literal>\dl</literal></term>
+        <term><literal>\dl[+]</literal></term>
         <listitem>
         <para>
         This is an alias for <command>\lo_list</command>, which shows a
-        list of large objects.
+        list of large objects. If <literal>+</literal> is appended 
+        to the command name, each large object is listed with its 
+        associated permissions, if any.
         </para>
         </listitem>
       </varlistentry>
@@ -2588,12 +2590,15 @@ lo_import 152801
       </varlistentry>
 
       <varlistentry>
-        <term><literal>\lo_list</literal></term>
+        <term><literal>\lo_list[+]</literal></term>
         <listitem>
         <para>
         Shows a list of all <productname>PostgreSQL</productname>
         large objects currently stored in the database,
         along with any comments provided for them.
+        If <literal>+</literal> is appended to the command name, 
+        each large object is listed with its associated permissions,
+        if any. 
         </para>
         </listitem>
       </varlistentry>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 49d4c0e3ce..5251b0bab8 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -807,7 +807,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
 				success = describeRoles(pattern, show_verbose, show_system);
 				break;
 			case 'l':
-				success = do_lo_list();
+				success = listLargeObjects(show_verbose);
 				break;
 			case 'L':
 				success = listLanguages(pattern, show_verbose, show_system);
@@ -1936,7 +1936,10 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
 		}
 
 		else if (strcmp(cmd + 3, "list") == 0)
-			success = do_lo_list();
+			success = listLargeObjects(false);
+
+		else if (strcmp(cmd + 3, "list+") == 0)
+			success = listLargeObjects(true);
 
 		else if (strcmp(cmd + 3, "unlink") == 0)
 		{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 90ff649be7..bb04e2d5f7 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -6828,3 +6828,65 @@ listOpFamilyFunctions(const char *access_method_pattern,
 	PQclear(res);
 	return true;
 }
+
+/*
+ * \dl or \lo_list
+ * Lists large objects in database
+ */
+bool
+listLargeObjects(bool verbose)
+{
+        PQExpBufferData buf;
+        PGresult   *res;
+        printQueryOpt myopt = pset.popt;
+
+        initPQExpBuffer(&buf);
+
+        if (pset.sversion >= 90000)
+        {
+                printfPQExpBuffer(&buf,
+                                 "SELECT oid as \"%s\",\n"
+                                 "  pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n  ",
+                                 gettext_noop("ID"),
+                                 gettext_noop("Owner"));
+
+                if (verbose)
+                {
+                        printACLColumn(&buf, "lomacl");
+                        appendPQExpBufferStr(&buf, ",\n  ");
+                }
+
+                appendPQExpBuffer(&buf,
+                                 "pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
+                                 "FROM pg_catalog.pg_largeobject_metadata\n"
+                                 "ORDER BY oid",
+                                 gettext_noop("Description"));
+
+        }
+        else
+        {
+                printfPQExpBuffer(&buf,
+                                 "SELECT loid as \"%s\",\n"
+                                 "  pg_catalog.obj_description(loid, 'pg_largeobject') as \"%s\"\n"
+                                 "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) x\n"
+                                 "ORDER BY 1",
+                                 gettext_noop("ID"),
+                                 gettext_noop("Description"));
+        }
+
+        res = PSQLexec(buf.data);
+        termPQExpBuffer(&buf);
+        if (!res)
+                return false;
+
+        myopt.topt.tuples_only = false;
+        myopt.nullPrint = NULL;
+        myopt.title = _("Large objects");
+        myopt.translate_header = true;
+
+        printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
+
+        PQclear(res);
+        return true;
+}
+
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 71b320f1fc..53738cc0cb 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -139,5 +139,8 @@ extern bool listOpFamilyOperators(const char *accessMethod_pattern,
 extern bool listOpFamilyFunctions(const char *access_method_pattern,
 								  const char *family_pattern, bool verbose);
 
+/* \dl or \lo_list */
+extern bool listLargeObjects(bool verbose);
+
 
 #endif							/* DESCRIBE_H */
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index d3fda67edd..7f1c9bc912 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -248,7 +248,7 @@ slashUsage(unsigned short int pager)
 	fprintf(output, _("  \\dFt[+] [PATTERN]      list text search templates\n"));
 	fprintf(output, _("  \\dg[S+] [PATTERN]      list roles\n"));
 	fprintf(output, _("  \\di[S+] [PATTERN]      list indexes\n"));
-	fprintf(output, _("  \\dl                    list large objects, same as \\lo_list\n"));
+	fprintf(output, _("  \\dl[+]                 list large objects, same as \\lo_list\n"));
 	fprintf(output, _("  \\dL[S+] [PATTERN]      list procedural languages\n"));
 	fprintf(output, _("  \\dm[S+] [PATTERN]      list materialized views\n"));
 	fprintf(output, _("  \\dn[S+] [PATTERN]      list schemas\n"));
@@ -324,7 +324,7 @@ slashUsage(unsigned short int pager)
 	fprintf(output, _("Large Objects\n"));
 	fprintf(output, _("  \\lo_export LOBOID FILE\n"
 					  "  \\lo_import FILE [COMMENT]\n"
-					  "  \\lo_list\n"
+					  "  \\lo_list[+]\n"
 					  "  \\lo_unlink LOBOID      large object operations\n"));
 
 	ClosePager(output);
diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c
index c15fcc0885..243875be83 100644
--- a/src/bin/psql/large_obj.c
+++ b/src/bin/psql/large_obj.c
@@ -262,55 +262,3 @@ do_lo_unlink(const char *loid_arg)
 
 	return true;
 }
-
-
-
-/*
- * do_lo_list()
- *
- * Show all large objects in database with comments
- */
-bool
-do_lo_list(void)
-{
-	PGresult   *res;
-	char		buf[1024];
-	printQueryOpt myopt = pset.popt;
-
-	if (pset.sversion >= 90000)
-	{
-		snprintf(buf, sizeof(buf),
-				 "SELECT oid as \"%s\",\n"
-				 "  pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n"
-				 "  pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
-				 "  FROM pg_catalog.pg_largeobject_metadata "
-				 "  ORDER BY oid",
-				 gettext_noop("ID"),
-				 gettext_noop("Owner"),
-				 gettext_noop("Description"));
-	}
-	else
-	{
-		snprintf(buf, sizeof(buf),
-				 "SELECT loid as \"%s\",\n"
-				 "  pg_catalog.obj_description(loid, 'pg_largeobject') as \"%s\"\n"
-				 "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) x\n"
-				 "ORDER BY 1",
-				 gettext_noop("ID"),
-				 gettext_noop("Description"));
-	}
-
-	res = PSQLexec(buf);
-	if (!res)
-		return false;
-
-	myopt.topt.tuples_only = false;
-	myopt.nullPrint = NULL;
-	myopt.title = _("Large objects");
-	myopt.translate_header = true;
-
-	printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
-
-	PQclear(res);
-	return true;
-}
diff --git a/src/bin/psql/large_obj.h b/src/bin/psql/large_obj.h
index 003acbf52c..3172a7704d 100644
--- a/src/bin/psql/large_obj.h
+++ b/src/bin/psql/large_obj.h
@@ -11,6 +11,5 @@
 bool		do_lo_export(const char *loid_arg, const char *filename_arg);
 bool		do_lo_import(const char *filename_arg, const char *comment_arg);
 bool		do_lo_unlink(const char *loid_arg);
-bool		do_lo_list(void);
 
 #endif							/* LARGE_OBJ_H */

Reply via email to