From a88f0d2c0455b687dcc6aabad7cc8c7319f3776f Mon Sep 17 00:00:00 2001 From: "okbob@github.com" Date: Fri, 19 Jan 2024 20:01:56 +0100 Subject: [PATCH 06/18] 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 | 102 ++++++++++++++++++++++++ src/include/catalog/pg_proc.dat | 7 ++ 2 files changed, 109 insertions(+) diff --git a/src/backend/commands/session_variable.c b/src/backend/commands/session_variable.c index 3d3fe35046..28636daec3 100644 --- a/src/backend/commands/session_variable.c +++ b/src/backend/commands/session_variable.c @@ -600,3 +600,105 @@ ExecuteLetStmt(ParseState *pstate, PopActiveSnapshot(); } + +/* + * pg_session_variables - designed for testing + * + * 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. + */ +Datum +pg_session_variables(PG_FUNCTION_ARGS) +{ +#define NUM_PG_SESSION_VARIABLES_ATTS 8 + + elog(DEBUG1, "pg_session_variables start"); + + 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); + + /* check if session variable is visible in system catalog */ + tp = SearchSysCache1(VARIABLEOID, ObjectIdGetDatum(svar->varid)); + + /* + * Sessionvars can hold data of variables removed from catalog, + * (and not purged) and then namespacename and name cannot be read + * from catalog. + */ + if (HeapTupleIsValid(tp)) + { + Form_pg_variable varform = (Form_pg_variable) GETSTRUCT(tp); + + /* When we see data in catalog */ + if (svar->create_lsn == varform->varcreate_lsn) + { + /* and when when these data are not out of date */ + 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 (!var_is_valid) + { + /* + * When session variable was removed from catalog, but we + * haven't processed the invlidation yet. In this case, we can + * display only few oids. Other data are not available + * (without Form_pg_variable record), or can be lost (because + * there is not protection by dependency (more). + */ + nulls[1] = true; + nulls[2] = true; + nulls[4] = true; + nulls[6] = true; + nulls[7] = true; + + values[5] = BoolGetDatum(true); + } + + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); + } + } + + elog(DEBUG1, "pg_session_variables end"); + + return (Datum) 0; +} diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index c5c6c6d2cd..ff0b71f81d 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12169,4 +12169,11 @@ proargtypes => 'int2', prosrc => 'gist_stratnum_identity' }, +{ 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.43.0