From d637125493c1134c78eef5114c3c8e1a36b3b3df Mon Sep 17 00:00:00 2001 From: "okbob@github.com" Date: Fri, 19 Jan 2024 20:01:56 +0100 Subject: [PATCH 12/15] function pg_session_variables for cleaning tests This is a function designed for testing and debugging. It returns the content of sessionvars as-is, and can therefore display entries about session variables that were dropped but for which this backend didn't process the shared invalidations yet. --- src/backend/commands/session_variable.c | 100 ++++++++++++++++++++++++ src/include/catalog/pg_proc.dat | 8 ++ 2 files changed, 108 insertions(+) diff --git a/src/backend/commands/session_variable.c b/src/backend/commands/session_variable.c index 768163e2009..9a9281acd83 100644 --- a/src/backend/commands/session_variable.c +++ b/src/backend/commands/session_variable.c @@ -22,6 +22,7 @@ #include "executor/execdesc.h" #include "executor/executor.h" #include "executor/svariableReceiver.h" +#include "funcapi.h" #include "miscadmin.h" #include "nodes/plannodes.h" #include "parser/parse_type.h" @@ -600,3 +601,102 @@ ExecuteLetStmt(ParseState *pstate, PopActiveSnapshot(); } + +/* + * pg_session_variables - designed for testing + * + * This is a function designed for testing and debugging. It returns the + * content of session variables as-is, and can therefore display data about + * session variables that were dropped, but for which this backend didn't + * process the shared invalidations yet. + */ +Datum +pg_session_variables(PG_FUNCTION_ARGS) +{ +#define NUM_PG_SESSION_VARIABLES_ATTS 8 + + /* + * Make sure syscache entries are flushed for recent catalog changes. For + * stable behavior we need to reliably detect which variables were + * dropped. + */ + AcceptInvalidationMessages(); + + InitMaterializedSRF(fcinfo, 0); + + if (sessionvars) + { + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + HASH_SEQ_STATUS status; + SVariable svar; + + hash_seq_init(&status, sessionvars); + + while ((svar = (SVariable) hash_seq_search(&status)) != NULL) + { + Datum values[NUM_PG_SESSION_VARIABLES_ATTS]; + bool nulls[NUM_PG_SESSION_VARIABLES_ATTS]; + HeapTuple tp; + bool var_is_valid = false; + + memset(values, 0, sizeof(values)); + memset(nulls, 0, sizeof(nulls)); + + values[0] = ObjectIdGetDatum(svar->varid); + values[3] = ObjectIdGetDatum(svar->typid); + + /* + * It is possible that the variable has been dropped from the + * catalog, but not yet purged from the hash table. + */ + tp = SearchSysCache1(VARIABLEOID, ObjectIdGetDatum(svar->varid)); + + if (HeapTupleIsValid(tp)) + { + Form_pg_variable varform = (Form_pg_variable) GETSTRUCT(tp); + + /* + * It is also possible that a variable has been dropped and + * someone created a new variable with the same object ID. + * Use the catalog information only if that is not the case. + */ + if (svar->create_lsn == varform->varcreate_lsn) + { + values[1] = CStringGetTextDatum( + get_namespace_name(varform->varnamespace)); + + values[2] = CStringGetTextDatum(NameStr(varform->varname)); + values[4] = CStringGetTextDatum(format_type_be(svar->typid)); + values[5] = BoolGetDatum(false); + + values[6] = BoolGetDatum( + object_aclcheck(VariableRelationId, svar->varid, + GetUserId(), ACL_SELECT) == ACLCHECK_OK); + + values[7] = BoolGetDatum( + object_aclcheck(VariableRelationId, svar->varid, + GetUserId(), ACL_UPDATE) == ACLCHECK_OK); + + var_is_valid = true; + } + + ReleaseSysCache(tp); + } + + /* if there is no matching catalog entry, return null values */ + if (!var_is_valid) + { + nulls[1] = true; + nulls[2] = true; + nulls[4] = true; + values[5] = BoolGetDatum(true); + nulls[6] = true; + nulls[7] = true; + } + + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); + } + } + + return (Datum) 0; +} diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index a71b9059822..d0399ec13fa 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12599,4 +12599,12 @@ proargnames => '{pid,io_id,io_generation,state,operation,off,length,target,handle_data_len,raw_result,result,target_desc,f_sync,f_localmem,f_buffered}', prosrc => 'pg_get_aios' }, +# Session variables support +{ oid => '8488', descr => 'list of used session variables', + proname => 'pg_session_variables', prorows => '1000', proretset => 't', + provolatile => 's', proparallel => 'r', prorettype => 'record', + proargtypes => '', proallargtypes => '{oid,text,text,oid,text,bool,bool,bool}', + proargmodes => '{o,o,o,o,o,o,o,o}', + proargnames => '{varid,schema,name,typid,typname,removed,can_select,can_update}', + prosrc => 'pg_session_variables' }, ] -- 2.50.1