documentation fix for SET ROLE

Started by Bossart, Nathanalmost 5 years ago24 messages
#1Bossart, Nathan
bossartn@amazon.com

Hi hackers,

I noticed some interesting role behavior that seems to be either a bug
or a miss in the documentation. The documentation for SET ROLE claims
that RESET ROLE resets "the current user identifier to be the current
session user identifier" [0]https://www.postgresql.org/docs/devel/sql-set-role.html, but this doesn't seem to hold true when
"role" has been set via pg_db_role_setting. Here is an example:

setup:
postgres=# CREATE ROLE test2;
CREATE ROLE
postgres=# CREATE ROLE test1 LOGIN CREATEROLE IN ROLE test2;
CREATE ROLE
postgres=# ALTER ROLE test1 SET ROLE test2;
ALTER ROLE

after logging in as test1:
postgres=> SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+--------------
test1 | test2
(1 row)

postgres=> RESET ROLE;
RESET
postgres=> SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+--------------
test1 | test2
(1 row)

I believe this behavior is caused by the "role" getting set at
PGC_S_GLOBAL, which sets the default used by RESET [1]https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/utils/guc.h;h=5004ee41;hb=HEAD#l79. IMO this just
requires a small documentation fix. Here is my first attempt:

diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..a69bfeae24 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -54,7 +54,12 @@ RESET ROLE
   <para>
    The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
+   user identifier to the default value.  The default value is whatever value it
+   would be if no <command>SET</command> had been executed in the current
+   session.  This can be the command-line option value, the per-database default
+   setting, or the per-user default setting for the role, if any such settings
+   exist.  Otherwise, the default value will be the current session user
+   identifier.
    These forms can be executed by any user.
   </para>
  </refsect1>

Nathan

[0]: https://www.postgresql.org/docs/devel/sql-set-role.html
[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/utils/guc.h;h=5004ee41;hb=HEAD#l79

#2David G. Johnston
david.g.johnston@gmail.com
In reply to: Bossart, Nathan (#1)
Re: documentation fix for SET ROLE

On Wednesday, February 17, 2021, Bossart, Nathan <bossartn@amazon.com>
wrote:

postgres=# ALTER ROLE test1 SET ROLE test2;
ALTER ROLE

I would not have expected this to work - “role” isn’t a
configuration_parameter. Its actually cool that it does, but this doc fix
should address this oversight as well.

David J.

#3Joe Conway
mail@joeconway.com
In reply to: David G. Johnston (#2)
Re: documentation fix for SET ROLE

On 2/17/21 2:12 PM, David G. Johnston wrote:

On Wednesday, February 17, 2021, Bossart, Nathan <bossartn@amazon.com
<mailto:bossartn@amazon.com>> wrote:

    postgres=# ALTER ROLE test1 SET ROLE test2;
    ALTER ROLE

I would not have expected this to work - “role” isn’t a
configuration_parameter.  Its actually cool that it does, but this doc fix
should address this oversight as well.

I was surprised this worked too.

But the behavior is consistent with other GUCs. In other words, when you "ALTER
ROLE ... SET ..." you change the default value for the session, and therefore a
RESET just changes to that value.

-- login as postgres
nmx=# show work_mem;
work_mem
----------
200MB
(1 row)

nmx=# set work_mem = '42MB';
SET
nmx=# show work_mem;
work_mem
----------
42MB
(1 row)

nmx=# reset work_mem;
RESET
nmx=# show work_mem;
work_mem
----------
200MB
(1 row)

ALTER ROLE test1 SET work_mem = '42MB';

-- login as test1
nmx=> show work_mem;
work_mem
----------
42MB
(1 row)

nmx=> reset work_mem;
RESET
nmx=> show work_mem;
work_mem
----------
42MB
(1 row)

Joe

--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#4Bossart, Nathan
bossartn@amazon.com
In reply to: Joe Conway (#3)
Re: documentation fix for SET ROLE

On 2/17/21, 12:15 PM, "Joe Conway" <mail@joeconway.com> wrote:

On 2/17/21 2:12 PM, David G. Johnston wrote:

On Wednesday, February 17, 2021, Bossart, Nathan <bossartn@amazon.com
<mailto:bossartn@amazon.com>> wrote:

postgres=# ALTER ROLE test1 SET ROLE test2;
ALTER ROLE

I would not have expected this to work - “role” isn’t a
configuration_parameter. Its actually cool that it does, but this doc fix
should address this oversight as well.

I was surprised this worked too.

But the behavior is consistent with other GUCs. In other words, when you "ALTER
ROLE ... SET ..." you change the default value for the session, and therefore a
RESET just changes to that value.

Looking further, I noticed that session_authorization does not work
the same way. AFAICT this is because it's set via SetConfigOption()
in InitializeSessionUserId(). If you initialize role here, it acts
the same as session_authorization.

diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 0f67b99cc5..a201bb3766 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -761,6 +761,7 @@ InitializeSessionUserId(const char *rolename, Oid roleid)
     }

/* Record username and superuser status as GUC settings too */
+ SetConfigOption("role", rname, PGC_BACKEND, PGC_S_OVERRIDE);
SetConfigOption("session_authorization", rname,
PGC_BACKEND, PGC_S_OVERRIDE);
SetConfigOption("is_superuser",

Nathan

#5Bossart, Nathan
bossartn@amazon.com
In reply to: Joe Conway (#3)
1 attachment(s)
Re: documentation fix for SET ROLE

On 2/17/21 2:12 PM, David G. Johnston wrote:

On Wednesday, February 17, 2021, Bossart, Nathan <bossartn@amazon.com
<mailto:bossartn@amazon.com>> wrote:

postgres=# ALTER ROLE test1 SET ROLE test2;
ALTER ROLE

I would not have expected this to work - “role” isn’t a
configuration_parameter. Its actually cool that it does, but this doc fix
should address this oversight as well.

Here's a patch that adds "role" and "session authorization" as
configuration parameters, too.

Nathan

Attachments:

v2-0001-Small-documentation-fix-for-SET-ROLE.patchapplication/octet-stream; name=v2-0001-Small-documentation-fix-for-SET-ROLE.patchDownload
From dec7711a92d51b65bf95588c7d077e7c08d3f6a9 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Fri, 19 Feb 2021 01:08:45 +0000
Subject: [PATCH v2] Small documentation fix for SET ROLE.

This change clarifies the behavior of RESET ROLE when "role" is set
per-user, per-database, or via command-line options.  Also, it adds
configuration parameter entries for "role" and
"session_authorization".
---
 doc/src/sgml/config.sgml       | 43 ++++++++++++++++++++++++++++++++++++++++++
 doc/src/sgml/ref/set_role.sgml |  7 ++++++-
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index e81141e45c..3150cda8aa 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -9220,6 +9220,49 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-role" xreflabel="role">
+      <term><varname>role</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>role</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Sets the current user identifier.  See
+        <link linkend="sql-set-role"><command>SET ROLE</command></link> for more
+        information.
+       </para>
+       <para>
+        This parameter can only be changed at connection start via
+        <link linkend="libpq-connect-options">command-line options</link> or at
+        run time via <link linkend="sql-set"><command>SET</command></link>,
+        <link linkend="sql-set-role"><command>SET ROLE</command></link>,
+        <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
+        <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-session-authorization" xreflabel="session_authorization">
+      <term><varname>session_authorization</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>session_authorization</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Sets the session user identifier and the current user identifier.  See
+        <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>
+        for more information.
+       </para>
+       <para>
+        This parameter can only be changed at run time via
+        <link linkend="sql-set"><command>SET</command></link> or
+        <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      </variablelist>
     </sect2>
    </sect1>
diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..a69bfeae24 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -54,7 +54,12 @@ RESET ROLE
 
   <para>
    The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
+   user identifier to the default value.  The default value is whatever value it
+   would be if no <command>SET</command> had been executed in the current
+   session.  This can be the command-line option value, the per-database default
+   setting, or the per-user default setting for the role, if any such settings
+   exist.  Otherwise, the default value will be the current session user
+   identifier.
    These forms can be executed by any user.
   </para>
  </refsect1>
-- 
2.16.6

#6David G. Johnston
david.g.johnston@gmail.com
In reply to: Bossart, Nathan (#5)
Re: documentation fix for SET ROLE

On Thu, Feb 18, 2021 at 6:18 PM Bossart, Nathan <bossartn@amazon.com> wrote:

On 2/17/21 2:12 PM, David G. Johnston wrote:

On Wednesday, February 17, 2021, Bossart, Nathan <bossartn@amazon.com
<mailto:bossartn@amazon.com>> wrote:

postgres=# ALTER ROLE test1 SET ROLE test2;
ALTER ROLE

I would not have expected this to work - “role” isn’t a
configuration_parameter. Its actually cool that it does, but this doc

fix

should address this oversight as well.

Here's a patch that adds "role" and "session authorization" as
configuration parameters, too.

You will want to add this to the commitfest if you haven't already.

I would suggest adding a section titled "Identification" and placing these
under that.

Reading it over it looks good. One point though: SET and SET ROLE are
indeed "at run-time" (not 'run time'). ALTER ROLE and ALTER DATABASE
should be considered "at connection-time" just like the command-line
options.

David J.

#7David G. Johnston
david.g.johnston@gmail.com
In reply to: David G. Johnston (#6)
Re: documentation fix for SET ROLE

On Mon, Mar 8, 2021 at 4:41 PM David G. Johnston <david.g.johnston@gmail.com>
wrote:

On Thu, Feb 18, 2021 at 6:18 PM Bossart, Nathan <bossartn@amazon.com>
wrote:

On 2/17/21 2:12 PM, David G. Johnston wrote:

On Wednesday, February 17, 2021, Bossart, Nathan <bossartn@amazon.com
<mailto:bossartn@amazon.com>> wrote:

postgres=# ALTER ROLE test1 SET ROLE test2;
ALTER ROLE

I would not have expected this to work - “role” isn’t a
configuration_parameter. Its actually cool that it does, but this doc

fix

should address this oversight as well.

Here's a patch that adds "role" and "session authorization" as
configuration parameters, too.

You will want to add this to the commitfest if you haven't already.

I would suggest adding a section titled "Identification" and placing these
under that.

Reading it over it looks good. One point though: SET and SET ROLE are
indeed "at run-time" (not 'run time'). ALTER ROLE and ALTER DATABASE
should be considered "at connection-time" just like the command-line
options.

Also, as a nearby email just reminded me, the determination of which role
name is used to figure out default settings is the presented user name, not
the one that would result from a connection-time role change as described
here - though this should be tested, and then documented.

David J.

#8Bossart, Nathan
bossartn@amazon.com
In reply to: David G. Johnston (#7)
1 attachment(s)
Re: documentation fix for SET ROLE

Thanks for reviewing.

On 3/8/21 3:49 PM, David G. Johnston wrote:

On Mon, Mar 8, 2021 at 4:41 PM David G. Johnston <david.g.johnston@gmail.com> wrote:

You will want to add this to the commitfest if you haven't already.

Here is the commitfest entry: https://commitfest.postgresql.org/32/2993/

I would suggest adding a section titled "Identification" and placing these under that.

Good idea.

Reading it over it looks good. One point though: SET and SET ROLE are indeed "at run-time" (not 'run time'). ALTER ROLE and ALTER DATABASE should be considered "at connection-time" just like the command-line options.

Makes sense. I've applied these changes.

Also, as a nearby email just reminded me, the determination of which role name is used to figure out default settings is the presented user name, not the one that would result from a connection-time role change as described here - though this should be tested, and then documented.

Yes, this seems to be correct. I've added a note about this behavior
in the patch.

-- setup
CREATE ROLE test1;
CREATE ROLE test2 WITH LOGIN IN ROLE test1;
ALTER ROLE test1 SET client_min_messages = 'error';
ALTER ROLE test2 SET client_min_messages = 'warning';
ALTER ROLE test2 SET ROLE = 'test1';

-- as test2
postgres=> SELECT CURRENT_USER, setting FROM pg_settings WHERE name = 'client_min_messages';
current_user | setting
--------------+---------
test1 | warning
(1 row)

Nathan

Attachments:

v3-0001-Small-documentation-fix-for-SET-ROLE.patchapplication/octet-stream; name=v3-0001-Small-documentation-fix-for-SET-ROLE.patchDownload
From f364779a4804754aff29112fb6d65762144f849b Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Wed, 10 Mar 2021 01:18:25 +0000
Subject: [PATCH v3 1/1] Small documentation fix for SET ROLE.

This change clarifies the behavior of RESET ROLE when "role" is set
per-user, per-database, or via command-line options.  Also, it adds
configuration parameter entries for "role" and
"session_authorization".
---
 doc/src/sgml/config.sgml       | 68 ++++++++++++++++++++++++++++++++++++++++++
 doc/src/sgml/ref/set_role.sgml | 10 +++++--
 2 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 529876895b..ffedd6cc14 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -9179,6 +9179,74 @@ SET XML OPTION { DOCUMENT | CONTENT };
     </variablelist>
    </sect2>
 
+   <sect2 id="runtime-config-identification">
+    <title>Identification</title>
+    <variablelist>
+
+     <varlistentry id="guc-role" xreflabel="role">
+      <term><varname>role</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>role</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Sets the current user identifier.  See
+        <link linkend="sql-set-role"><command>SET ROLE</command></link> for more
+        information.
+       </para>
+       <para>
+        This parameter can be changed at connection-time via
+        <link linkend="libpq-connect-options">command-line options</link>,
+        <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, and
+        <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>
+        and at run-time via <link linkend="sql-set"><command>SET</command></link>
+        and <link linkend="sql-set-role"><command>SET ROLE</command></link>.
+       </para>
+       <note>
+        <para>
+         While connection-time settings for <varname>role</varname> modify a
+         session's default setting for <varname>role</varname>, such settings do
+         not affect other default settings for the session.  The originally
+         authenticated session user is used to determine other session defaults.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-session-authorization" xreflabel="session_authorization">
+      <term><varname>session_authorization</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>session_authorization</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Sets the session user identifier and the current user identifier.  See
+        <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>
+        for more information.
+       </para>
+       <para>
+        This parameter can only be changed at run-time via
+        <link linkend="sql-set"><command>SET</command></link> and
+        <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>.
+       </para>
+       <note>
+        <para>
+         While it is possible to provide a connection-time setting for this
+         parameter via
+         <link linkend="libpq-connect-options">command-line options</link>,
+         <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, and
+         <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+         such settings are silently ignored.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
+    </variablelist>
+   </sect2>
+
      <sect2 id="runtime-config-client-other">
      <title>Other Defaults</title>
 
diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..4eaec8d669 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,13 @@ RESET ROLE
   </para>
 
   <para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   The <literal>NONE</literal> form resets the current user identifier to the
+   current session user identifier.  The <literal>RESET</literal> form resets
+   the current user identifier to the default value.  The default value can be
+   the command-line option value, the per-database default setting, or the
+   per-user default setting for the originally authenticated session user, if
+   any such settings exist.  Otherwise, the default value will be the current
+   session user identifier.  These forms can be executed by any user.
   </para>
  </refsect1>
 
-- 
2.16.6

#9Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Bossart, Nathan (#8)
Re: documentation fix for SET ROLE

I have had a look at the patch, and while I agree that this should
be documented, I am not happy with the patch as it is.

I think we should *not* document that under "server configuration".
This is confusing and will lead people to think that a role is
a configuration parameter. But you cannot add

role = myrole

to "postgresql.conf". A role is not a GUC.

I think that the place to document this is
doc/src/sgml/ref/alter_role.sgml.

The second hunk of the patch is in the right place:

--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,13 @@ RESET ROLE
   </para>
   <para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   The <literal>NONE</literal> form resets the current user identifier to the
+   current session user identifier.  The <literal>RESET</literal> form resets
+   the current user identifier to the default value.  The default value can be
+   the command-line option value, the per-database default setting, or the
+   per-user default setting for the originally authenticated session user, if
+   any such settings exist.  Otherwise, the default value will be the current
+   session user identifier.  These forms can be executed by any user.
   </para>
  </refsect1>

Perhaps this could be reworded in a simpler fashion, like:

<literal>SET ROLE NONE</literal> sets the user identifier to the current
session identifier, as returned by the <function>session_user</function>
function. <literal>RESET ROLE</literal> sets the user identifier to the
value it had after you connected to the database. This can be different
from the session identifier if <literal>ALTER DATABASE</literal> or
<literal>ALTER ROLE</literal> were used to assign a different default role.

(I hope what I wrote is correct.)

Yours,
Laurenz Albe

#10David G. Johnston
david.g.johnston@gmail.com
In reply to: Laurenz Albe (#9)
Re: documentation fix for SET ROLE

On Thu, Mar 11, 2021 at 7:58 AM Laurenz Albe <laurenz.albe@cybertec.at>
wrote:

I think we should *not* document that under "server configuration".
This is confusing and will lead people to think that a role is
a configuration parameter. But you cannot add

role = myrole

to "postgresql.conf". A role is not a GUC.

I think that the place to document this is
doc/src/sgml/ref/alter_role.sgml.

Good point. I agree that another syntax specification should be added to
ALTER ROLE/DATABASE cover this instead of shoe-horning it into the "SET
configuration_parameter" syntax specification even though the syntax is
nearly identical. It is indeed a different mechanic that just happens to
share a similar syntax. (On that note, does "FROM CURRENT" work with
"ROLE"?)

I'm a bit indifferent on the wording for RESET ROLE, though it should
probably mirror whatever wording we use for GUCs since this behaves like
one even if it isn't one technically.

David J.

#11Bossart, Nathan
bossartn@amazon.com
In reply to: David G. Johnston (#10)
1 attachment(s)
Re: documentation fix for SET ROLE

Thanks for reviewing.

On 3/11/21, 6:59 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

I have had a look at the patch, and while I agree that this should
be documented, I am not happy with the patch as it is.

I think we should *not* document that under "server configuration".
This is confusing and will lead people to think that a role is
a configuration parameter. But you cannot add

role = myrole

to "postgresql.conf". A role is not a GUC.

I think that the place to document this is
doc/src/sgml/ref/alter_role.sgml.

I don't think I totally agree that "role" and "session_authorization"
aren't GUCs. They are defined in guc.c, and "role" is referred to as
a GUC in both miscinit.c and variable.c. Plus, they are usable as
configuration parameters in many of the same ways that ordinary GUCs
are (e.g., SET, ALTER ROLE, ALTER DATABASE). It is true that "role"
and "session_authorization" cannot be set in postgresql.conf and ALTER
SYSTEM SET, and I think we should add a note to this effect in the
documentation. However, I don't see the value in duplicating a
paragraph about "role" and "session_authorization" in a number of
statements that already accept a configuration_parameter and point to
the chapter on Server Configuration.

I do agree that that adding these parameters to the Server
Configuration section is a bit confusing. At the very least, the
proposed patch would add them to the Client Connection Defaults
section, but it's still not ideal. This is probably why they've been
left out so far.

The second hunk of the patch is in the right place:

--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,13 @@ RESET ROLE
</para>
<para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   The <literal>NONE</literal> form resets the current user identifier to the
+   current session user identifier.  The <literal>RESET</literal> form resets
+   the current user identifier to the default value.  The default value can be
+   the command-line option value, the per-database default setting, or the
+   per-user default setting for the originally authenticated session user, if
+   any such settings exist.  Otherwise, the default value will be the current
+   session user identifier.  These forms can be executed by any user.
</para>
</refsect1>

Perhaps this could be reworded in a simpler fashion, like:

<literal>SET ROLE NONE</literal> sets the user identifier to the current
session identifier, as returned by the <function>session_user</function>
function. <literal>RESET ROLE</literal> sets the user identifier to the
value it had after you connected to the database. This can be different
from the session identifier if <literal>ALTER DATABASE</literal> or
<literal>ALTER ROLE</literal> were used to assign a different default role.

(I hope what I wrote is correct.)

I like the simpler text, but I think it is missing a couple of things.
If no session default was set, RESET ROLE will set the role to the
current session user identifier, which can either be what it was when
you first connected or what you SET SESSION AUTHORIZATION to. The
other thing missing is that "role" can be set via the command-line
options, too. Here's an attempt at including those things:

<literal>SET ROLE NONE</literal> sets the current user identifier to the
current session user identifier, as returned by
<function>session_user</function>. <literal>RESET ROLE</literal> sets the
current user identifier to the connection-time setting specified by the
<link linkend="libpq-connect-options">command-line options</link>,
<link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
<link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
if any such settings exist. Otherwise, <literal>RESET ROLE</literal> sets
the current user identifier to the current session user identifier. These
forms can be executed by any user.

I attached a new version of my proposed patch, but I acknowledge that
much of it is still under discussion.

Nathan

Attachments:

v4-0001-Small-documentation-fix-for-SET-ROLE.patchapplication/octet-stream; name=v4-0001-Small-documentation-fix-for-SET-ROLE.patchDownload
From 266d4d252af0da109d5ce69bf67b2170f449756c Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Thu, 11 Mar 2021 19:13:40 +0000
Subject: [PATCH v4 1/1] Small documentation fix for SET ROLE.

This change clarifies the behavior of RESET ROLE when "role" is set
per-user, per-database, or via command-line options.  Also, it adds
configuration parameter entries for "role" and
"session_authorization".
---
 doc/src/sgml/config.sgml       | 74 ++++++++++++++++++++++++++++++++++++++++++
 doc/src/sgml/ref/set_role.sgml | 13 ++++++--
 2 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index a218d78bef..4b47268715 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -9139,6 +9139,80 @@ SET XML OPTION { DOCUMENT | CONTENT };
     </variablelist>
    </sect2>
 
+   <sect2 id="runtime-config-identification">
+    <title>Identification</title>
+    <variablelist>
+
+     <varlistentry id="guc-role" xreflabel="role">
+      <term><varname>role</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>role</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Sets the current user identifier.  See
+        <link linkend="sql-set-role"><command>SET ROLE</command></link> for more
+        information.
+       </para>
+       <para>
+        This parameter can be changed at connection-time via
+        <link linkend="libpq-connect-options">command-line options</link>,
+        <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, and
+        <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>
+        and at run-time via <link linkend="sql-set"><command>SET</command></link>
+        and <link linkend="sql-set-role"><command>SET ROLE</command></link>.  It
+        cannot be set via the server configuration files, the server command
+        line, or
+        <link linkend="sql-altersystem"><command>ALTER SYSTEM</command></link>.
+       </para>
+       <note>
+        <para>
+         While connection-time settings for <varname>role</varname> modify a
+         session's default setting for <varname>role</varname>, such settings do
+         not affect other default settings for the session.  The originally
+         authenticated session user is used to determine other session defaults.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-session-authorization" xreflabel="session_authorization">
+      <term><varname>session_authorization</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>session_authorization</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Sets the session user identifier and the current user identifier.  See
+        <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>
+        for more information.
+       </para>
+       <para>
+        This parameter can only be changed at run-time via
+        <link linkend="sql-set"><command>SET</command></link> and
+        <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>.
+        It cannot be set via the server configuration files, the server command
+        line, or
+        <link linkend="sql-altersystem"><command>ALTER SYSTEM</command></link>.
+       </para>
+       <note>
+        <para>
+         While it is possible to provide a connection-time setting for this
+         parameter via
+         <link linkend="libpq-connect-options">command-line options</link>,
+         <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, and
+         <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+         such settings are silently ignored.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
+    </variablelist>
+   </sect2>
+
      <sect2 id="runtime-config-client-other">
      <title>Other Defaults</title>
 
diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..f02babf3af 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,16 @@ RESET ROLE
   </para>
 
   <para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   <literal>SET ROLE NONE</literal> sets the current user identifier to the
+   current session user identifier, as returned by
+   <function>session_user</function>.  <literal>RESET ROLE</literal> sets the
+   current user identifier to the connection-time setting specified by the
+   <link linkend="libpq-connect-options">command-line options</link>,
+   <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
+   <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+   if any such settings exist.  Otherwise, <literal>RESET ROLE</literal> sets
+   the current user identifier to the current session user identifier.  These
+   forms can be executed by any user.
   </para>
  </refsect1>
 
-- 
2.16.6

#12David G. Johnston
david.g.johnston@gmail.com
In reply to: Bossart, Nathan (#11)
Re: documentation fix for SET ROLE

On Thursday, March 11, 2021, Bossart, Nathan <bossartn@amazon.com> wrote:

Thanks for reviewing.

On 3/11/21, 6:59 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

I have had a look at the patch, and while I agree that this should
be documented, I am not happy with the patch as it is.

I think we should *not* document that under "server configuration".
This is confusing and will lead people to think that a role is
a configuration parameter. But you cannot add

role = myrole

to "postgresql.conf". A role is not a GUC.

I think that the place to document this is
doc/src/sgml/ref/alter_role.sgml.

I don't think I totally agree that "role" and "session_authorization"
aren't GUCs. They are defined in guc.c, and "role" is referred to as
a GUC in both miscinit.c and variable.c.

Implementation details are not that convincing to me. As a user I wouldn’t
think of these as being “server configuration” or even “client defaults”;
typically they are just representations of me as session state.

The minor bit of documentation pseudo-redundancy doesn’t bother me if I
accept they are there own separate thing. The fact that set role and set
session authorization are entirely distinct top-level commands in our
documentation, as opposed to bundled in with plain set, is a much more
convincing example for treating them uniquely and not just additional GUCs.

David J.

#13Bossart, Nathan
bossartn@amazon.com
In reply to: David G. Johnston (#12)
1 attachment(s)
Re: documentation fix for SET ROLE

On 3/11/21, 12:11 PM, "David G. Johnston" <david.g.johnston@gmail.com> wrote:

On Thursday, March 11, 2021, Bossart, Nathan <bossartn@amazon.com> wrote:

Thanks for reviewing.

On 3/11/21, 6:59 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

I have had a look at the patch, and while I agree that this should
be documented, I am not happy with the patch as it is.

I think we should *not* document that under "server configuration".
This is confusing and will lead people to think that a role is
a configuration parameter. But you cannot add

role = myrole

to "postgresql.conf". A role is not a GUC.

I think that the place to document this is
doc/src/sgml/ref/alter_role.sgml.

I don't think I totally agree that "role" and "session_authorization"
aren't GUCs. They are defined in guc.c, and "role" is referred to as
a GUC in both miscinit.c and variable.c.

Implementation details are not that convincing to me. As a user I wouldn’t think of these as being “server configuration” or even “client defaults”; typically they are just representations of me as session state.

The minor bit of documentation pseudo-redundancy doesn’t bother me if I accept they are there own separate thing. The fact that set role and set session authorization are entirely distinct top-level commands in our documentation, as opposed to bundled in with plain set, is a much more convincing example for treating them uniquely and not just additional GUCs.

I see your point. What do you think about something like the attached
patch?

Nathan

Attachments:

v5-0001-Small-documentation-fix-for-SET-ROLE.patchapplication/octet-stream; name=v5-0001-Small-documentation-fix-for-SET-ROLE.patchDownload
From c26916e523dd7fd8381de0a16445c02bf27e2972 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Thu, 11 Mar 2021 22:18:30 +0000
Subject: [PATCH v5 1/1] Small documentation fix for SET ROLE.

This change clarifies the behavior of RESET ROLE when "role" is set
per-user, per-database, or via command-line options.  Also, it adds
additional information about setting "role" in these ways.
---
 doc/src/sgml/libpq.sgml              | 12 ++++++++++++
 doc/src/sgml/ref/alter_database.sgml | 10 ++++++++++
 doc/src/sgml/ref/alter_role.sgml     | 10 ++++++++++
 doc/src/sgml/ref/set.sgml            | 22 ++++++++++++++++++++++
 doc/src/sgml/ref/set_role.sgml       | 13 ++++++++++---
 5 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 910e9a81ea..6d0539a18c 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1288,6 +1288,18 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
         backslash.  For a detailed discussion of the available
         options, consult <xref linkend="runtime-config"/>.
        </para>
+       <note>
+        <para>
+         In addition to the options listed in <xref linkend="runtime-config"/>,
+         <varname>role</varname> may be used as a command-line option.  While
+         setting <varname>role</varname> via command-line options modifies its
+         default setting for the session, such settings will not affect other
+         default settings for the session.  The originally authenticated session
+         user is used to determine other session defaults.  See 
+         <link linkend="sql-set-role"><command>SET ROLE</command></link> for
+         more information.
+        </para>
+       </note>
       </listitem>
      </varlistentry>
 
diff --git a/doc/src/sgml/ref/alter_database.sgml b/doc/src/sgml/ref/alter_database.sgml
index 81e37536a3..67e5a4b5f0 100644
--- a/doc/src/sgml/ref/alter_database.sgml
+++ b/doc/src/sgml/ref/alter_database.sgml
@@ -187,6 +187,16 @@ ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET ALL
         the parameter as the database-specific value.
        </para>
 
+       <para>
+        <varname>role</varname> may be used as a configuration parameter in this
+        command.  While database-specific settings for <varname>role</varname>
+        modify its default setting for new sessions, such settings do not affect
+        other default settings for the session.  The originally authenticated
+        session user is used to determine other session defaults.  See
+        <link linkend="sql-set-role"><command>SET ROLE</command></link> for more
+        information.
+       </para>
+
        <para>
         See <xref linkend="sql-set"/> and <xref linkend="runtime-config"/>
         for more information about allowed parameter names
diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml
index 5aa5648ae7..5c4651e190 100644
--- a/doc/src/sgml/ref/alter_role.sgml
+++ b/doc/src/sgml/ref/alter_role.sgml
@@ -220,6 +220,16 @@ ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | A
         parameter is set or removed for the given role and database only.
        </para>
 
+       <para>
+        <varname>role</varname> may be used as a configuration parameter in this
+        command.  While role-specific settings for <varname>role</varname>
+        modify its default setting for new sessions, such settings do not affect
+        other default settings for the session.  The originally authenticated
+        session user is used to determine other session defaults.  See
+        <link linkend="sql-set-role"><command>SET ROLE</command></link> for more
+        information.
+       </para>
+
        <para>
         Role-specific variable settings take effect only at login;
         <link linkend="sql-set-role"><command>SET ROLE</command></link> and
diff --git a/doc/src/sgml/ref/set.sgml b/doc/src/sgml/ref/set.sgml
index 339ee9eec9..631522e22c 100644
--- a/doc/src/sgml/ref/set.sgml
+++ b/doc/src/sgml/ref/set.sgml
@@ -258,6 +258,28 @@ SELECT setseed(<replaceable>value</replaceable>);
       </para>
      </listitem>
     </varlistentry>
+
+    <varlistentry>
+     <term><literal>role</literal></term>
+     <listitem>
+      <para>
+       <literal>SET role TO <replaceable>value</replaceable></literal> is an
+       alias for
+       <link linkend="sql-set-role"><command>SET ROLE</command></link>.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term><literal>session_authorization</literal></term>
+     <listitem>
+      <para>
+       <literal>SET session_authorization TO <replaceable>value</replaceable></literal>
+       is an alias for
+       <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>.
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </para>
  </refsect1>
diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..f02babf3af 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,16 @@ RESET ROLE
   </para>
 
   <para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   <literal>SET ROLE NONE</literal> sets the current user identifier to the
+   current session user identifier, as returned by
+   <function>session_user</function>.  <literal>RESET ROLE</literal> sets the
+   current user identifier to the connection-time setting specified by the
+   <link linkend="libpq-connect-options">command-line options</link>,
+   <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
+   <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+   if any such settings exist.  Otherwise, <literal>RESET ROLE</literal> sets
+   the current user identifier to the current session user identifier.  These
+   forms can be executed by any user.
   </para>
  </refsect1>
 
-- 
2.16.6

#14Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Bossart, Nathan (#13)
Re: documentation fix for SET ROLE

On Thu, 2021-03-11 at 22:30 +0000, Bossart, Nathan wrote:

On 3/11/21, 12:11 PM, "David G. Johnston" <david.g.johnston@gmail.com> wrote:

The minor bit of documentation pseudo-redundancy doesn’t bother me if I accept
they are there own separate thing. The fact that set role and set session
authorization are entirely distinct top-level commands in our documentation,
as opposed to bundled in with plain set, is a much more convincing example
for treating them uniquely and not just additional GUCs.

I see your point. What do you think about something like the attached
patch?

After sleeping on it, I have come to think that it is excessive to write
so much documentation for a feature that is that unimportant.

It takes some effort to come up with a good use case for it.

I think we can add a few lines to ALTER ROLE, perhaps ALTER DATABASE
(although I don't see what sense it could make to set that on the database level),
and briefly explain the difference between RESET ROLE and SET ROLE NONE.

I think adding too much detail will harm - anyone who needs to know the
exact truth can resort to the implementation.

I'll try to come up with a proposal later.

Yours,
Laurenz Albe

#15Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Laurenz Albe (#14)
1 attachment(s)
Re: documentation fix for SET ROLE

On Fri, 2021-03-12 at 10:16 +0100, I wrote:

After sleeping on it, I have come to think that it is excessive to write
so much documentation for a feature that is that unimportant.

It takes some effort to come up with a good use case for it.

I think we can add a few lines to ALTER ROLE, perhaps ALTER DATABASE
(although I don't see what sense it could make to set that on the database level),
and briefly explain the difference between RESET ROLE and SET ROLE NONE.

I think adding too much detail will harm - anyone who needs to know the
exact truth can resort to the implementation.

I'll try to come up with a proposal later.

Attached is my idea of the documentation change.

I think that ALTER DATABASE ... SET ROLE can remain undocumented, because
I cannot imagine that it could be useful.

I am unsure if specifying "role" in a libpq connect string might be
worth documenting. Can you think of a use case?

Yours,
Laurenz Albe

Attachments:

0001-Document-ALTER-ROLE-.-SET-ROLE.patchtext/x-patch; charset=UTF-8; name=0001-Document-ALTER-ROLE-.-SET-ROLE.patchDownload
From 5daa6c2a874898506fda316fe651f107dbed34d5 Mon Sep 17 00:00:00 2001
From: Laurenz Albe <laurenz.albe@cybertec.at>
Date: Fri, 12 Mar 2021 15:32:01 +0100
Subject: [PATCH] Document ALTER ROLE ... SET ROLE

This was previously undocumented, like ALTER DATABASE ... SET ROLE or
specifying "role=some_role" in a libpq connect string, but it might
have some practical use cases.
---
 doc/src/sgml/ref/alter_role.sgml | 15 +++++++++++++--
 doc/src/sgml/ref/set_role.sgml   |  8 ++++++--
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml
index 5aa5648ae7..a377fc303b 100644
--- a/doc/src/sgml/ref/alter_role.sgml
+++ b/doc/src/sgml/ref/alter_role.sgml
@@ -40,6 +40,7 @@ ALTER ROLE <replaceable class="parameter">name</replaceable> RENAME TO <replacea
 
 ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
 ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
+ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET ROLE <replaceable class="parameter">other_role</replaceable>
 ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
 ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET ALL
 
@@ -91,7 +92,7 @@ ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | A
 
   <para>
    The remaining variants change a role's session default for a configuration
-   variable, either for all databases or, when the <literal>IN
+   variable or the role assumed, either for all databases or, when the <literal>IN
    DATABASE</literal> clause is specified, only for sessions in the named
    database.  If <literal>ALL</literal> is specified instead of a role name,
    this changes the setting for all roles.  Using <literal>ALL</literal>
@@ -104,7 +105,7 @@ ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | A
    starts a new session, the specified value becomes the session
    default, overriding whatever setting is present in
    <filename>postgresql.conf</filename> or has been received from the <command>postgres</command>
-   command line. This only happens at login time; executing
+   command line.  This only happens at login time; executing
    <link linkend="sql-set-role"><command>SET ROLE</command></link> or
    <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link> does not cause new
    configuration values to be set.
@@ -234,6 +235,16 @@ ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | A
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+       <term><replaceable>other_role</replaceable></term>
+       <listitem>
+         <para>
+           The name of a role that contains the modified role as a member.
+           This identity is automatically assumed when the connection is established.
+         </para>
+       </listitem>
+     </varlistentry>
     </variablelist>
  </refsect1>
 
diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..4ce4873fe8 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,8 +53,12 @@ RESET ROLE
   </para>
 
   <para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
+   <literal>SET ROLE NONE</literal> sets the current user identifier to the
+   session user identifier, as returned by <function>session_user</function>.
+   <literal>RESET ROLE</literal> sets the current user identifier to the
+   connection-time setting, which may be different from the session user
+   identifier if a different role has been set with
+   <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>.
    These forms can be executed by any user.
   </para>
  </refsect1>
-- 
2.26.2

#16David G. Johnston
david.g.johnston@gmail.com
In reply to: Laurenz Albe (#15)
Re: documentation fix for SET ROLE

On Fri, Mar 12, 2021 at 7:35 AM Laurenz Albe <laurenz.albe@cybertec.at>
wrote:

On Fri, 2021-03-12 at 10:16 +0100, I wrote:

After sleeping on it, I have come to think that it is excessive to write
so much documentation for a feature that is that unimportant.

It takes some effort to come up with a good use case for it.

I think we can add a few lines to ALTER ROLE, perhaps ALTER DATABASE
(although I don't see what sense it could make to set that on the

database level),

and briefly explain the difference between RESET ROLE and SET ROLE NONE.

I think adding too much detail will harm - anyone who needs to know the
exact truth can resort to the implementation.

I'll try to come up with a proposal later.

Attached is my idea of the documentation change.

I think that ALTER DATABASE ... SET ROLE can remain undocumented, because
I cannot imagine that it could be useful.

I am unsure if specifying "role" in a libpq connect string might be
worth documenting. Can you think of a use case?

Does our imagination really matter here? It works and is just as "useful"
as "ALTER ROLE" and so should be documented if we document ALTER ROLE.

I agree that ALTER DATABASE seems entirely useless and even
counter-productive...but I would still document if only because we document
ALTER ROLE and they should be kept similar.

Haven't formed an opinion on the merits of the two patches.

David J.

#17Bossart, Nathan
bossartn@amazon.com
In reply to: David G. Johnston (#16)
Re: documentation fix for SET ROLE

On 3/12/21, 6:35 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

On Fri, 2021-03-12 at 10:16 +0100, I wrote:

After sleeping on it, I have come to think that it is excessive to write
so much documentation for a feature that is that unimportant.

It takes some effort to come up with a good use case for it.

I think we can add a few lines to ALTER ROLE, perhaps ALTER DATABASE
(although I don't see what sense it could make to set that on the database level),
and briefly explain the difference between RESET ROLE and SET ROLE NONE.

I think adding too much detail will harm - anyone who needs to know the
exact truth can resort to the implementation.

I'll try to come up with a proposal later.

Attached is my idea of the documentation change.

I think that ALTER DATABASE ... SET ROLE can remain undocumented, because
I cannot imagine that it could be useful.

I am unsure if specifying "role" in a libpq connect string might be
worth documenting. Can you think of a use case?

My main goal of this thread is to get the RESET ROLE documentation
fixed. I don't have a terribly strong opinion on documenting these
special uses of "role". I lean in favor of adding it, but I wouldn't
be strongly opposed to simply leaving it out for now. But if we're
going to add it, I think we might as well add it everywhere.

Nathan

#18Joe Conway
mail@joeconway.com
In reply to: Bossart, Nathan (#17)
Re: documentation fix for SET ROLE

On 3/12/21 1:16 PM, Bossart, Nathan wrote:

On 3/12/21, 6:35 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

On Fri, 2021-03-12 at 10:16 +0100, I wrote:

After sleeping on it, I have come to think that it is excessive to write
so much documentation for a feature that is that unimportant.

It takes some effort to come up with a good use case for it.

I think we can add a few lines to ALTER ROLE, perhaps ALTER DATABASE
(although I don't see what sense it could make to set that on the database level),
and briefly explain the difference between RESET ROLE and SET ROLE NONE.

I think adding too much detail will harm - anyone who needs to know the
exact truth can resort to the implementation.

I'll try to come up with a proposal later.

Attached is my idea of the documentation change.

I think that ALTER DATABASE ... SET ROLE can remain undocumented, because
I cannot imagine that it could be useful.

I am unsure if specifying "role" in a libpq connect string might be
worth documenting. Can you think of a use case?

My main goal of this thread is to get the RESET ROLE documentation
fixed. I don't have a terribly strong opinion on documenting these
special uses of "role". I lean in favor of adding it, but I wouldn't
be strongly opposed to simply leaving it out for now. But if we're
going to add it, I think we might as well add it everywhere.

Looking back at the commit history it seems to me that this only works
accidentally. Perhaps it would be best to fix RESET ROLE and be done with it.

Joe

--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#19Bossart, Nathan
bossartn@amazon.com
In reply to: Joe Conway (#18)
Re: documentation fix for SET ROLE

On 3/12/21, 11:14 AM, "Joe Conway" <mail@joeconway.com> wrote:

On 3/12/21 1:16 PM, Bossart, Nathan wrote:

My main goal of this thread is to get the RESET ROLE documentation
fixed. I don't have a terribly strong opinion on documenting these
special uses of "role". I lean in favor of adding it, but I wouldn't
be strongly opposed to simply leaving it out for now. But if we're
going to add it, I think we might as well add it everywhere.

Looking back at the commit history it seems to me that this only works
accidentally. Perhaps it would be best to fix RESET ROLE and be done with it.

That seems reasonable to me.

Nathan

#20Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Bossart, Nathan (#19)
Re: documentation fix for SET ROLE

On Fri, 2021-03-12 at 21:41 +0000, Bossart, Nathan wrote:

On 3/12/21, 11:14 AM, "Joe Conway" <mail@joeconway.com> wrote:

Looking back at the commit history it seems to me that this only works
accidentally. Perhaps it would be best to fix RESET ROLE and be done with it.

That seems reasonable to me.

+1 from me too.

Yours,
Laurenz Albe

#21Bossart, Nathan
bossartn@amazon.com
In reply to: Laurenz Albe (#20)
Re: documentation fix for SET ROLE

On 3/15/21, 7:06 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

On Fri, 2021-03-12 at 21:41 +0000, Bossart, Nathan wrote:

On 3/12/21, 11:14 AM, "Joe Conway" <mail@joeconway.com> wrote:

Looking back at the commit history it seems to me that this only works
accidentally. Perhaps it would be best to fix RESET ROLE and be done with it.

That seems reasonable to me.

+1 from me too.

Here's my latest attempt. I think it's important to state that it
sets the role to the current session user identifier unless there is a
connection-time setting. If there is no connection-time setting, it
will reset the role to the current session user, which might be
different if you've run SET SESSION AUTHORIZATION.

diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..f02babf3af 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,16 @@ RESET ROLE
   </para>
   <para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   <literal>SET ROLE NONE</literal> sets the current user identifier to the
+   current session user identifier, as returned by
+   <function>session_user</function>.  <literal>RESET ROLE</literal> sets the
+   current user identifier to the connection-time setting specified by the
+   <link linkend="libpq-connect-options">command-line options</link>,
+   <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
+   <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+   if any such settings exist.  Otherwise, <literal>RESET ROLE</literal> sets
+   the current user identifier to the current session user identifier.  These
+   forms can be executed by any user.
   </para>
  </refsect1>

Nathan

#22Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Bossart, Nathan (#21)
Re: documentation fix for SET ROLE

On Mon, 2021-03-15 at 17:09 +0000, Bossart, Nathan wrote:

On 3/15/21, 7:06 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

On Fri, 2021-03-12 at 21:41 +0000, Bossart, Nathan wrote:

On 3/12/21, 11:14 AM, "Joe Conway" <mail@joeconway.com> wrote:

Looking back at the commit history it seems to me that this only works
accidentally. Perhaps it would be best to fix RESET ROLE and be done with it.

That seems reasonable to me.

+1 from me too.

Here's my latest attempt. I think it's important to state that it
sets the role to the current session user identifier unless there is a
connection-time setting. If there is no connection-time setting, it
will reset the role to the current session user, which might be
different if you've run SET SESSION AUTHORIZATION.

diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..f02babf3af 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,16 @@ RESET ROLE
</para>
<para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   <literal>SET ROLE NONE</literal> sets the current user identifier to the
+   current session user identifier, as returned by
+   <function>session_user</function>.  <literal>RESET ROLE</literal> sets the
+   current user identifier to the connection-time setting specified by the
+   <link linkend="libpq-connect-options">command-line options</link>,
+   <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
+   <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+   if any such settings exist.  Otherwise, <literal>RESET ROLE</literal> sets
+   the current user identifier to the current session user identifier.  These
+   forms can be executed by any user.
</para>
</refsect1>

Actually, SET ROLE NONE is defined by the SQL standard:

18.3 <set role statement>

[...]

If NONE is specified, then
Case:
i) If there is no current user identifier, then an exception condition is raised:
invalid role specification.
ii) Otherwise, the current role name is removed.

This is reflected in a comment in src/backend/commands/variable.c:

/*
* SET ROLE
*
* The SQL spec requires "SET ROLE NONE" to unset the role, so we hardwire
* a translation of "none" to InvalidOid. Otherwise this is much like
* SET SESSION AUTHORIZATION.
*/

On the other hand, RESET (according to src/backend/utils/misc/README)
does something different:

Prior values of configuration variables must be remembered in order to deal
with several special cases: RESET (a/k/a SET TO DEFAULT)

So I think it is intentional that RESET ROLE does something else than
SET ROLE NONE, and we should not change that.

So I think that documenting this is the way to go. I'll mark it as
"ready for committer".

Yours,
Laurenz Albe

#23Joe Conway
mail@joeconway.com
In reply to: Laurenz Albe (#22)
Re: documentation fix for SET ROLE

On 4/2/21 10:21 AM, Laurenz Albe wrote:

On Mon, 2021-03-15 at 17:09 +0000, Bossart, Nathan wrote:

On 3/15/21, 7:06 AM, "Laurenz Albe" <laurenz.albe@cybertec.at> wrote:

On Fri, 2021-03-12 at 21:41 +0000, Bossart, Nathan wrote:

On 3/12/21, 11:14 AM, "Joe Conway" <mail@joeconway.com> wrote:

Looking back at the commit history it seems to me that this only works
accidentally. Perhaps it would be best to fix RESET ROLE and be done with it.

That seems reasonable to me.

+1 from me too.

Here's my latest attempt. I think it's important to state that it
sets the role to the current session user identifier unless there is a
connection-time setting. If there is no connection-time setting, it
will reset the role to the current session user, which might be
different if you've run SET SESSION AUTHORIZATION.

diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
index 739f2c5cdf..f02babf3af 100644
--- a/doc/src/sgml/ref/set_role.sgml
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -53,9 +53,16 @@ RESET ROLE
</para>
<para>
-   The <literal>NONE</literal> and <literal>RESET</literal> forms reset the current
-   user identifier to be the current session user identifier.
-   These forms can be executed by any user.
+   <literal>SET ROLE NONE</literal> sets the current user identifier to the
+   current session user identifier, as returned by
+   <function>session_user</function>.  <literal>RESET ROLE</literal> sets the
+   current user identifier to the connection-time setting specified by the
+   <link linkend="libpq-connect-options">command-line options</link>,
+   <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
+   <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+   if any such settings exist.  Otherwise, <literal>RESET ROLE</literal> sets
+   the current user identifier to the current session user identifier.  These
+   forms can be executed by any user.
</para>
</refsect1>

Actually, SET ROLE NONE is defined by the SQL standard:

18.3 <set role statement>

[...]

If NONE is specified, then
Case:
i) If there is no current user identifier, then an exception condition is raised:
invalid role specification.
ii) Otherwise, the current role name is removed.

This is reflected in a comment in src/backend/commands/variable.c:

/*
* SET ROLE
*
* The SQL spec requires "SET ROLE NONE" to unset the role, so we hardwire
* a translation of "none" to InvalidOid. Otherwise this is much like
* SET SESSION AUTHORIZATION.
*/

On the other hand, RESET (according to src/backend/utils/misc/README)
does something different:

Prior values of configuration variables must be remembered in order to deal
with several special cases: RESET (a/k/a SET TO DEFAULT)

So I think it is intentional that RESET ROLE does something else than
SET ROLE NONE, and we should not change that.

So I think that documenting this is the way to go. I'll mark it as
"ready for committer".

pushed

Joe
--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#24Bossart, Nathan
bossartn@amazon.com
In reply to: Joe Conway (#23)
Re: documentation fix for SET ROLE

On 4/2/21, 10:54 AM, "Joe Conway" <mail@joeconway.com> wrote:

On 4/2/21 10:21 AM, Laurenz Albe wrote:

So I think that documenting this is the way to go. I'll mark it as
"ready for committer".

pushed

Thanks!

Nathan