summaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorTom Lane2025-03-26 14:59:42 +0000
committerTom Lane2025-03-26 15:06:12 +0000
commit9324c8c580655800331b0582b770e88c01b7a5c4 (patch)
tree7abf1f4eebd29cb26fa05fc984db644fb174328d /src/backend/commands
parente92c0632c1473fe57383c58f0dfdde3bae7044f4 (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.c53
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.