diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 6df6bf2..dec6a96 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -412,6 +412,11 @@ CREATE RULE pg_settings_n AS GRANT SELECT, UPDATE ON pg_settings TO PUBLIC; +CREATE VIEW pg_file_settings AS + SELECT * FROM pg_show_all_file_settings() AS A; + +GRANT SELECT ON pg_file_settings TO PUBLIC; + CREATE VIEW pg_timezone_abbrevs AS SELECT * FROM pg_timezone_abbrevs(); diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index b2f04e5..a751fb0 100644 --- a/src/backend/utils/misc/guc-file.l +++ b/src/backend/utils/misc/guc-file.l @@ -122,6 +122,7 @@ ProcessConfigFile(GucContext context) ConfigVariable *item, *head, *tail; + ConfigFileVariable *guc; int i; /* @@ -258,6 +259,7 @@ ProcessConfigFile(GucContext context) error = true; ConfFileWithError = item->filename; } + num_guc_file_variables++; } /* @@ -344,6 +346,20 @@ ProcessConfigFile(GucContext context) PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT); } + guc_file_variables = (ConfigFileVariable *) + guc_malloc(FATAL, num_guc_file_variables * sizeof(struct ConfigFileVariable)); + + /* + * Apply guc config parameters to guc_file_variable + */ + guc = guc_file_variables; + for (item = head; item; item = item->next, guc++) + { + guc->name = guc_strdup(FATAL, item->name); + guc->value = guc_strdup(FATAL, item->value); + guc->filename = guc_strdup(FATAL, item->filename); + } + /* * Now apply the values from the config file. */ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 931993c..15cdc64 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -3561,9 +3561,17 @@ static const char *const map_old_guc_names[] = { */ static struct config_generic **guc_variables; +/* + * lookup of variables for pg_file_settings view. + */ +static struct ConfigFileVariable *guc_file_variables; + /* Current number of variables contained in the vector */ static int num_guc_variables; +/* Number of file variables */ +static int num_guc_file_variables; + /* Vector capacity */ static int size_guc_variables; @@ -7919,6 +7927,15 @@ GetNumConfigOptions(void) } /* + * Return the total number of GUC File variables + */ +int +GetNumConfigFileOptions(void) +{ + return num_guc_file_variables; +} + +/* * show_config_by_name - equiv to SHOW X command but implemented as * a function. */ @@ -8062,6 +8079,85 @@ show_all_settings(PG_FUNCTION_ARGS) } } +/* + * show_all_file_settings + */ + +#define NUM_PG_FILE_SETTINGS_ATTS 3 + +Datum +show_all_file_settings(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + TupleDesc tupdesc; + int call_cntr; + int max_calls; + AttInMetadata *attinmeta; + MemoryContext oldcontext; + + if (SRF_IS_FIRSTCALL()) + { + funcctx = SRF_FIRSTCALL_INIT(); + + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + /* + * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns + * of the appropriate types + */ + + tupdesc = CreateTemplateTupleDesc(NUM_PG_FILE_SETTINGS_ATTS, false); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "sourcefile", + TEXTOID, -1, 0); + + + attinmeta = TupleDescGetAttInMetadata(tupdesc); + funcctx->attinmeta = attinmeta; + funcctx->max_calls = GetNumConfigFileOptions(); + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + + call_cntr = funcctx->call_cntr; + max_calls = funcctx->max_calls; + attinmeta = funcctx->attinmeta; + + if (call_cntr < max_calls) + { + char *values[NUM_PG_FILE_SETTINGS_ATTS]; + HeapTuple tuple; + Datum result; + ConfigFileVariable conf; + + conf = guc_file_variables[call_cntr]; + + values[0] = conf.name; + values[1] = conf.value; + values[2] = conf.filename; + + if (call_cntr >= max_calls) + SRF_RETURN_DONE(funcctx); + + /* build a tuple */ + tuple = BuildTupleFromCStrings(attinmeta, values); + + /* make the tuple into a datum */ + result = HeapTupleGetDatum(tuple); + + SRF_RETURN_NEXT(funcctx, result); + } + else + { + SRF_RETURN_DONE(funcctx); + } + +} + static char * _ShowOption(struct config_generic * record, bool use_units) { diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 9edfdb8..0b3f582 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3017,6 +3017,10 @@ DATA(insert OID = 2078 ( set_config PGNSP PGUID 12 1 0 0 0 f f f f f f v 3 0 2 DESCR("SET X as a function"); DATA(insert OID = 2084 ( pg_show_all_settings PGNSP PGUID 12 1 1000 0 0 f f f f t t s 0 0 2249 "" "{25,25,25,25,25,25,25,25,25,25,25,1009,25,25,25,23}" "{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{name,setting,unit,category,short_desc,extra_desc,context,vartype,source,min_val,max_val,enumvals,boot_val,reset_val,sourcefile,sourceline}" _null_ show_all_settings _null_ _null_ _null_ )); DESCR("SHOW ALL as a function"); + +DATA(insert OID = 2095 ( pg_show_all_file_settings PGNSP PGUID 12 1 1000 0 0 f f f f t t s 0 0 2249 "" "{25,25,25}" "{o,o,o}" "{name,setting,sourcefile}" _null_ show_all_file_settings _null_ _null_ _null_ )); +DESCR("show config file settings"); + DATA(insert OID = 1371 ( pg_lock_status PGNSP PGUID 12 1 1000 0 0 f f f f t t v 0 0 2249 "" "{25,26,26,23,21,25,28,26,26,21,25,23,25,16,16}" "{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{locktype,database,relation,page,tuple,virtualxid,transactionid,classid,objid,objsubid,virtualtransaction,pid,mode,granted,fastpath}" _null_ pg_lock_status _null_ _null_ _null_ )); DESCR("view system lock information"); DATA(insert OID = 1065 ( pg_prepared_xact PGNSP PGUID 12 1 1000 0 0 f f f f t t v 0 0 2249 "" "{28,25,1184,26,26}" "{o,o,o,o,o}" "{transaction,gid,prepared,ownerid,dbid}" _null_ pg_prepared_xact _null_ _null_ _null_ )); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index bc4517d..91c823f 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -1090,6 +1090,7 @@ extern Datum quote_nullable(PG_FUNCTION_ARGS); extern Datum show_config_by_name(PG_FUNCTION_ARGS); extern Datum set_config_by_name(PG_FUNCTION_ARGS); extern Datum show_all_settings(PG_FUNCTION_ARGS); +extern Datum show_all_file_settings(PG_FUNCTION_ARGS); /* lockfuncs.c */ extern Datum pg_lock_status(PG_FUNCTION_ARGS); diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 717f46b..77f73e7 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -133,6 +133,13 @@ typedef struct ConfigVariable struct ConfigVariable *next; } ConfigVariable; +typedef struct ConfigFileVariable +{ + char *name; + char *value; + char *filename; +} ConfigFileVariable; + extern bool ParseConfigFile(const char *config_file, const char *calling_file, bool strict, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p); @@ -352,6 +359,7 @@ extern void AlterSystemSetConfigFile(AlterSystemStmt *setstmt); extern char *GetConfigOptionByName(const char *name, const char **varname); extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow); extern int GetNumConfigOptions(void); +extern int GetNumConfigFileOptions(void); extern void SetPGVariable(const char *name, List *args, bool is_local); extern void GetPGVariable(const char *name, DestReceiver *dest);