Hi
st 8. 3. 2023 v 17:58 odesÃlatel Pavel Stehule <pavel.steh...@gmail.com> napsal: > Hi > > I try to write a safeguard check that ensures the expected extension > version for an extension library. > > Some like > > const char *expected_extversion = "2.5"; > > ... > > extoid = getExtensionOfObject(ProcedureRelationId, > fcinfo->flinfo->fn_oid)); > extversion = get_extension_version(extoid); > if (strcmp(expected_extversion, extversion) != 0) > elog(ERROR, "extension \"%s\" needs \"ALTER EXTENSION %s UPDATE\", > get_extension_name(extversion), > get_extension_name(extversion))) > > Currently the extension version is not simply readable - I need to read > directly from the table. > > Notes, comments? > attached patch Regards Pavel > > Regards > > Pavel > >
From b12a43d885af4311dbb61684d65b6f5fc41b60d2 Mon Sep 17 00:00:00 2001 From: "ok...@github.com" <pavel.steh...@gmail.com> Date: Sat, 11 Mar 2023 05:04:28 +0100 Subject: [PATCH] get_extension_version - given an extension OID, look up the version Returns a palloc'd string, or NULL if no such extension. --- src/backend/commands/extension.c | 50 ++++++++++++++++++++++++++++++++ src/include/commands/extension.h | 1 + 2 files changed, 51 insertions(+) diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 02ff4a9a7f..ea347750fe 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -256,6 +256,56 @@ get_extension_schema(Oid ext_oid) return result; } +/* + * get_extension_version - given an extension OID, look up the version + * + * Returns a palloc'd string, or NULL if no such extension. + */ +char * +get_extension_version(Oid ext_oid) +{ + char *result; + Relation rel; + SysScanDesc scandesc; + HeapTuple tuple; + ScanKeyData entry[1]; + + rel = table_open(ExtensionRelationId, AccessShareLock); + + ScanKeyInit(&entry[0], + Anum_pg_extension_oid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(ext_oid)); + + scandesc = systable_beginscan(rel, ExtensionOidIndexId, true, + NULL, 1, entry); + + tuple = systable_getnext(scandesc); + + /* We assume that there can be at most one matching tuple */ + if (HeapTupleIsValid(tuple)) + { + Datum datum; + bool isnull; + + datum = heap_getattr(tuple, Anum_pg_extension_extversion, + RelationGetDescr(rel), &isnull); + + if (isnull) + elog(ERROR, "extversion is null"); + + result = text_to_cstring(DatumGetTextPP(datum)); + } + else + result = NULL; + + systable_endscan(scandesc); + + table_close(rel, AccessShareLock); + + return result; +} + /* * Utility functions to check validity of extension and version names */ diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h index 74ae391395..3563e07b9f 100644 --- a/src/include/commands/extension.h +++ b/src/include/commands/extension.h @@ -48,6 +48,7 @@ extern ObjectAddress ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt * extern Oid get_extension_oid(const char *extname, bool missing_ok); extern char *get_extension_name(Oid ext_oid); extern Oid get_extension_schema(Oid ext_oid); +extern char *get_extension_version(Oid ext_oid); extern bool extension_file_exists(const char *extensionName); extern ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, -- 2.39.2