Observed in testClassDBRolesMgmt.sql. This is because only superusers can view backend_start in pg_stat_activity for other users. This is an issue because DDL operations performed while SET SESSION AUTHORIZATION is active fail because the DDL activity trigger tries to insert a NULL SessionID into DDLActivity. Below is an example error message from trying to perform a DDL op. under SET SESSION AUTHORIZATION:
SET SESSION AUTHORIZATION sysadm;
classdb200=> CREATE TABLE ttable(a INT);
ERROR: null value in column "sessionid" violates not-null constraint
DETAIL: Failing row contains (sysadm, 2018-06-22 15:29:47.738855, CREATE TABLE, sysadm.ttable, null).
CONTEXT: SQL statement "INSERT INTO ClassDB.DDLActivity VALUES
(SESSION_USER, statement_timestamp() AT TIME ZONE 'utc', TG_TAG, objId,
ClassDB.getSessionID())"
PL/pgSQL function logddlactivity() line 34 at SQL statement
There are three solutions I see for this issue:
Change ClassDB.getSessionID() owner to superuser, and set it to SECURITY DEFINER. This will allow it to always return a session ID. However the SessionID will be "wrong" under testing conditions in the sense that the session ID stored will be that of the superuser running the test, but the username will be the user specified in SET SESSION AUTHORIZATION. This is probably OK since it will only show up in testing. In normal conditions, this will still return the correct session ID.
Check if the caller of ClassDB.SessionID() is superuser, and if not return the dummy value (0000000.0000000) we are using in ClassDB.ConnectionActivity. In normal usage, the caller of this function will always be a superuser, since the DDL trigger function is executed as a superuser.
Observed in
testClassDBRolesMgmt.sql
. This is because only superusers can viewbackend_start
inpg_stat_activity
for other users. This is an issue because DDL operations performed whileSET SESSION AUTHORIZATION
is active fail because the DDL activity trigger tries to insert aNULL SessionID
intoDDLActivity
. Below is an example error message from trying to perform a DDL op. underSET SESSION AUTHORIZATION
:There are three solutions I see for this issue:
Change
ClassDB.getSessionID()
owner to superuser, and set it toSECURITY DEFINER
. This will allow it to always return a session ID. However theSessionID
will be "wrong" under testing conditions in the sense that the session ID stored will be that of the superuser running the test, but the username will be the user specified inSET SESSION AUTHORIZATION
. This is probably OK since it will only show up in testing. In normal conditions, this will still return the correct session ID.Check if the caller of
ClassDB.SessionID()
is superuser, and if not return the dummy value (0000000.0000000
) we are using inClassDB.ConnectionActivity
. In normal usage, the caller of this function will always be a superuser, since the DDL trigger function is executed as a superuser.COALESCE
backend_start
with0000000
,