From b12a43d885af4311dbb61684d65b6f5fc41b60d2 Mon Sep 17 00:00:00 2001
From: "okbob@github.com" <pavel.stehule@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

