diff options
author | Tom Lane | 2025-03-26 14:59:42 +0000 |
---|---|---|
committer | Tom Lane | 2025-03-26 15:06:12 +0000 |
commit | 9324c8c580655800331b0582b770e88c01b7a5c4 (patch) | |
tree | 7abf1f4eebd29cb26fa05fc984db644fb174328d /src/backend/commands | |
parent | e92c0632c1473fe57383c58f0dfdde3bae7044f4 (diff) |
Introduce PG_MODULE_MAGIC_EXT macro.
This macro allows dynamically loaded shared libraries (modules) to
provide a wired-in module name and version, and possibly other
compile-time-constant fields in future. This information can be
retrieved with the new pg_get_loaded_modules() function.
This feature is expected to be particularly useful for modules
that do not have any exposed SQL functionality and thus are
not associated with a SQL-level extension object. But even for
modules that do belong to extensions, being able to verify the
actual code version can be useful.
Author: Andrei Lepikhov <[email protected]>
Reviewed-by: Yurii Rashkovskii <[email protected]>
Reviewed-by: Tom Lane <[email protected]>
Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/extension.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index dc38c325770..180f4af9be3 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2812,6 +2812,59 @@ pg_extension_config_dump(PG_FUNCTION_ARGS) } /* + * pg_get_loaded_modules + * + * SQL-callable function to get per-loaded-module information. Modules + * (shared libraries) aren't necessarily one-to-one with extensions, but + * they're sufficiently closely related to make this file a good home. + */ +Datum +pg_get_loaded_modules(PG_FUNCTION_ARGS) +{ + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + DynamicFileList *file_scanner; + + /* Build tuplestore to hold the result rows */ + InitMaterializedSRF(fcinfo, 0); + + for (file_scanner = get_first_loaded_module(); file_scanner != NULL; + file_scanner = get_next_loaded_module(file_scanner)) + { + const char *library_path, + *module_name, + *module_version; + const char *sep; + Datum values[3] = {0}; + bool nulls[3] = {0}; + + get_loaded_module_details(file_scanner, + &library_path, + &module_name, + &module_version); + + if (module_name == NULL) + nulls[0] = true; + else + values[0] = CStringGetTextDatum(module_name); + if (module_version == NULL) + nulls[1] = true; + else + values[1] = CStringGetTextDatum(module_version); + + /* For security reasons, we don't show the directory path */ + sep = last_dir_separator(library_path); + if (sep) + library_path = sep + 1; + values[2] = CStringGetTextDatum(library_path); + + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, + values, nulls); + } + + return (Datum) 0; +} + +/* * extension_config_remove * * Remove the specified table OID from extension's extconfig, if present. |