út 4. 4. 2023 v 21:11 odesílatel Pavel Stehule <[email protected]>
napsal:
>
>
> út 4. 4. 2023 v 20:50 odesílatel Pavel Stehule <[email protected]>
> napsal:
>
>>
>>
>> út 4. 4. 2023 v 19:55 odesílatel Tom Lane <[email protected]> napsal:
>>
>>> Pavel Stehule <[email protected]> writes:
>>> > út 4. 4. 2023 v 18:42 odesílatel Tom Lane <[email protected]> napsal:
>>> >> 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
>>>
>>> Yeah, but how big is the use-case? The reason I'm skeptical is that
>>> half the time what you're going to get is "none":
>>>
>>> $ psql
>>> psql (16devel)
>>> Type "help" for help.
>>>
>>> regression=# show role;
>>> role
>>> ------
>>> none
>>> (1 row)
>>>
>>> That's required by SQL spec I believe, but that doesn't make it useful
>>> data to keep in one's prompt.
>>>
>>
>> Who needs it, and who uses different roles, then very quickly uses SET
>> ROLE TO command.
>>
>> But I fully agree so current behavior can be a little bit messy. I like
>> this feature, and I think it can have some benefits. Proposed
>> implementation is minimalistic.
>>
>> One hard problem is translation of the oid of current_user to name. It
>> requires an opened transaction, and then it cannot be postponed to the end
>> of the statement. On the other hand, when the change of role is done inside
>> a nested command, then it should not be visible from the client side.
>>
>> Can you accept the introduction of a new invisible GUC, that can be
>> modified only by SET ROLE TO command when it is executed as top command?
>>
>
> It was stupid idea.
>
> There can be implemented fallbacks. When the role is "none", then the
> :USER can be displayed instead.
>
> It can work, because the custom role "none" is not allowed
>
> (2023-04-04 21:10:25) postgres=# create role none;
> ERROR: role name "none" is reserved
> LINE 1: create role none;
>
> ?
>
>
attached updated patch
Regards
Pavel
>
>
>
>>
>> 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..98669fc18a 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4540,7 +4540,24 @@ testdb=> <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 set to the database session user name.
+ </para>
+
+ <para>
+ This substitution requires <productname>PostgreSQL</productname>
+ version 16 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..7399bacd5f 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,41 @@ 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 *rolename;
+
+ /*
+ * 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)
+ {
+ rolename = PQparameterStatus(pset.db, "role");
+
+ /* fallback when role is not set yet */
+ if (strcmp(rolename, "none") == 0)
+ rolename = session_username();
+ }
+
+ if (rolename)
+ strlcpy(buf, rolename, sizeof(buf));
+ else
+ buf[0] = '\0';
+ }
+ break;
/* backend pid */
case 'p':
if (pset.db)