Ășt 4. 4. 2023 v 18:42 odesĂ­latel Tom Lane <t...@sss.pgh.pa.us> napsal:

> Kirk Wolak <wol...@gmail.com> writes:
> > Changed status to Ready for Committer. (100% Guessing here...)
>
> Basically, I want to reject this on the grounds that it's not
> useful enough to justify the overhead of marking the "role" GUC
> as GUC_REPORT.  The problems with it not going to work properly
> with old servers are an additional reason not to like it.
>

If I understand to next comment correctly, the overhead should not be too
big

/*
 * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables
 *
 * This is called just before we wait for a new client query.
 *
 * By handling things this way, we ensure that a ParameterStatus message
 * is sent at most once per variable per query, even if the variable
 * changed multiple times within the query.  That's quite possible when
 * using features such as function SET clauses.  Function SET clauses
 * also tend to cause values to change intraquery but eventually revert
 * to their prevailing values; ReportGUCOption is responsible for avoiding
 * redundant reports in such cases.
 */



>
> But, if I lose the argument and we do commit this, I think it
> should just print an empty string when dealing with an old server.
> "ERR02000" is an awful idea, not least because it could be a
> real role name.
>

ok


>
> BTW, we should probably get rid of the PQuser() fallback in
> %n (session_username()) as well.  It's unlikely that there are
> still servers in the wild that don't report "session_authorization",
> but if we did find one then the output is potentially misleading.
> I'd rather print nothing than something that might not be your
> actual session authorization setting.
>

It should be a separate patch?

Updated patch attached

Regards

Pavel



>
>                         regards, tom lane
>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 9f72dd29d8..966cce9559 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2482,6 +2482,7 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
        <varname>in_hot_standby</varname>,
        <varname>is_superuser</varname>,
        <varname>session_authorization</varname>,
+       <varname>role</varname>,
        <varname>DateStyle</varname>,
        <varname>IntervalStyle</varname>,
        <varname>TimeZone</varname>,
@@ -2496,7 +2497,8 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
        9.0;
        <varname>default_transaction_read_only</varname> and
        <varname>in_hot_standby</varname> were not reported by releases before
-       14.)
+       14;
+       <varname>role</varname> was not reported by releases before 16;)
        Note that
        <varname>server_version</varname>,
        <varname>server_encoding</varname> and
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 29bbec2188..330c085329 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4540,7 +4540,26 @@ testdb=&gt; <userinput>INSERT INTO my_table VALUES (:'content');</userinput>
         <listitem><para>The port number at which the database server is listening.</para></listitem>
       </varlistentry>
 
-      <varlistentry id="app-psql-prompting-n">
+      <varlistentry id="app-psql-prompting-n-uc">
+        <term><literal>%N</literal></term>
+        <listitem>
+         <para>
+          The database role name. This value is specified by command
+          <command>SET ROLE</command>. Until execution of this command
+          the value is <literal>none</literal>. The value is same like
+          the value of the parameter <varname>role</varname> (can be
+          displayed by <command>SHOW</command>.
+         </para>
+
+         <para>
+          This substitution requires <productname>PostgreSQL</productname>
+          version 15 and up. When you use older version, the empty string
+          is used instead.
+         </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry id="app-psql-prompting-n-lc">
         <term><literal>%n</literal></term>
         <listitem>
          <para>
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 8062589efd..3eec4768b3 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -4174,7 +4174,7 @@ struct config_string ConfigureNamesString[] =
 		{"role", PGC_USERSET, UNGROUPED,
 			gettext_noop("Sets the current role."),
 			NULL,
-			GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
+			GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
 		},
 		&role_string,
 		"none",
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..a304fe1868 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,35 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 					if (pset.db)
 						strlcpy(buf, session_username(), sizeof(buf));
 					break;
+					/* DB server user role */
+				case 'N':
+					if (pset.db)
+					{
+						int			minServerMajor;
+						int			serverMajor;
+						const char *val;
+
+						/*
+						 * This feature requires GUC "role" to be marked
+						 * as GUC_REPORT. Without it is hard to specify fallback
+						 * result. Returning empty value can be messy, returning
+						 * PQuser like session_username can be messy too.
+						 * Exec query is not too practical too, because it doesn't
+						 * work when session is not in transactional state, and
+						 * CURRENT_ROLE returns different result when role is not
+						 * explicitly specified by SET ROLE. 
+						 */
+						minServerMajor = 1600;
+						serverMajor = PQserverVersion(pset.db) / 100;
+						if (serverMajor >= minServerMajor)
+							val = PQparameterStatus(pset.db, "role");
+
+						if (val)
+							strlcpy(buf, val, sizeof(buf));
+						else
+							buf[0] = '\0';
+					}
+					break;
 					/* backend pid */
 				case 'p':
 					if (pset.db)

Reply via email to