Add a function to get the version of installed extension
Hi,
When an extension module is updated, first the new binary is installed, then
ALTER EXTENSION UPDATE is executed to create or modify SQL objects. Between
these two steps, users could see an error, or in worst case segfalut, during
a query execution due to the lack or incompatibility of SQL objects.
This might be avoidable if the binary is made carefully to check the existing
of objects, but I think it is useful if an extension module function can check
the current extension version. So, I would like to propose a new function to
return the current extension version, get_extension_version. I've attached a
patch.
Also, as an application of this function, how about allowing to include versions
in the "requires" list in the control file? It seems useful when an extension
requires other extension with a certain version. The proposed
get_extension_version can be used to check the versions of existing extensions.
This is just an idea and a patch is not created yet.
Regards,
Yugo Nagata
--
Yugo Nagata <nagata@sraoss.co.jp>
Attachments:
get_extension_version.patchtext/x-diff; name=get_extension_version.patchDownload
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index ba540e3de5..48c9109c31 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -215,6 +215,28 @@ 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;
+ HeapTuple tuple;
+
+ tuple = SearchSysCache1(EXTENSIONOID, ObjectIdGetDatum(ext_oid));
+
+ if (!HeapTupleIsValid(tuple))
+ return NULL;
+
+ result = pstrdup(NameStr(((Form_pg_extension) GETSTRUCT(tuple))->extversion));
+ ReleaseSysCache(tuple);
+
+ 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 0b63640512..43a55adea7 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,
Yugo Nagata <nagata@sraoss.co.jp> writes:
This might be avoidable if the binary is made carefully to check the existing
of objects, but I think it is useful if an extension module function can check
the current extension version. So, I would like to propose a new function to
return the current extension version, get_extension_version. I've attached a
patch.
While I don't say this is a bad idea, I do say you've not made a very
good case for it. How would an extension know its own OID in order
to call the function? If it did manage to call the function, what
exactly would it do with the result, and how would that be easier than
maintaining backwards compatibility with its old SQL definitions?
We've not found the backwards-compatibility requirement to be hugely
onerous in our contrib extensions.
A concrete example use-case would make this a lot more convincing.
Also, as an application of this function, how about allowing to include versions
in the "requires" list in the control file?
That could be a good feature, but it doesn't follow that an
implementation of it would have any use for this exact function.
It might well be, for example, that the code would need to fetch
the pg_extension catalog entry for other purposes and so could
read the extversion field "for free" then.
BTW, the cfbot claims that this patch doesn't compile. The
error is a little confusing, but I'm suspicious that it somehow
traces to the fact that you applied NameStr to a field that is
not of type "name". See ExecAlterExtensionStmt for known-to-work
code for fetching extversion.
regards, tom lane
On Sun, 2 Feb 2025 00:15:25 -0500
Tom Lane <tgl@sss.pgh.pa.us> wrote:
Yugo Nagata <nagata@sraoss.co.jp> writes:
This might be avoidable if the binary is made carefully to check the existing
of objects, but I think it is useful if an extension module function can check
the current extension version. So, I would like to propose a new function to
return the current extension version, get_extension_version. I've attached a
patch.While I don't say this is a bad idea, I do say you've not made a very
good case for it. How would an extension know its own OID in order
to call the function? If it did manage to call the function, what
exactly would it do with the result, and how would that be easier than
maintaining backwards compatibility with its old SQL definitions?
We've not found the backwards-compatibility requirement to be hugely
onerous in our contrib extensions.A concrete example use-case would make this a lot more convincing.
An OID of an extension can be get from the name using get_extension_oid()
because the name is unique in a database. But, after second thought, this
might not be so useful because the version of an extension is just a text
and would not comparable as a number, so it is hard to say "if the version
is 10.0 or later" and so on.
I'll withdraw this proposal for now until I get a good example use-case.
Regards,
Yugo Nagata
--
Yugo NAGATA <nagata@sraoss.co.jp>