Get TupleDesc for extension-defined types

Started by Florents Tselaiover 1 year ago5 messages
#1Florents Tselai
florents.tselai@gmail.com
1 attachment(s)

Correct me if I'm wrong,
but for an extension that defines composite types,
there's currently no easy way to get a TupleDesc, even for its own types.

Something like
TupleDesc get_extension_type_tupledesc(const char *extname, const char
*typname)

Here's a routine I've stolen borrowed from pramsey's code and have been
using ever since.

Could this be exposed in extension.h ? (probably without the version check)

Attachments:

v1-0001-First-implementation-for-get_extension_type_tuple.patchapplication/octet-stream; name=v1-0001-First-implementation-for-get_extension_type_tuple.patchDownload
From 5dbe1e1ecfea702b4137258071e6d1ef62b0c254 Mon Sep 17 00:00:00 2001
From: Florents Tselai <florents.tselai@gmail.com>
Date: Wed, 18 Sep 2024 09:58:22 +0300
Subject: [PATCH v1] First implementation for get_extension_type_tupledesc

---
 src/backend/commands/extension.c | 35 ++++++++++++++++++++++++++++++++
 src/include/commands/extension.h |  1 +
 2 files changed, 36 insertions(+)

diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index fab59ad5f6..f305eb122e 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -203,6 +203,41 @@ get_extension_schema(Oid ext_oid)
 	return result;
 }
 
+/* TupleDesc for an extension-defined type */
+TupleDesc get_extension_type_tupledesc(const char *extname, const char *typname)
+{
+	Oid extoid = get_extension_oid(extname, true);
+	Oid extschemaoid;
+	Oid typoid;
+
+	if ( ! OidIsValid(extoid) )
+		elog(ERROR, "could not lookup '%s' extension oid", extname);
+
+	extschemaoid = get_extension_schema(extoid);
+
+#if PG_VERSION_NUM >= 120000
+	typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
+				   PointerGetDatum(typname),
+				   ObjectIdGetDatum(extschemaoid));
+#else
+	typoid = GetSysCacheOid2(TYPENAMENSP,
+				   PointerGetDatum(typname),
+				   ObjectIdGetDatum(extschemaoid));
+#endif
+
+	if ( OidIsValid(typoid) )
+	{
+		// Oid typ_oid = get_typ_typrelid(rel_oid);
+		Oid relextoid = getExtensionOfObject(TypeRelationId, typoid);
+		if ( relextoid == extoid )
+		{
+			return TypeGetTupleDesc(typoid, NIL);
+		}
+	}
+
+	elog(ERROR, "could not lookup '%s' tuple desc", typname);
+}
+
 /*
  * 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 c6f3f867eb..e968fcb762 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 TupleDesc get_extension_type_tupledesc(const char *extname, const char *typname);
 extern bool extension_file_exists(const char *extensionName);
 
 extern ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema,
-- 
2.46.1

#2Pavel Stehule
pavel.stehule@gmail.com
In reply to: Florents Tselai (#1)
Re: Get TupleDesc for extension-defined types

Hi

st 18. 9. 2024 v 9:04 odesílatel Florents Tselai <florents.tselai@gmail.com>
napsal:

Correct me if I'm wrong,
but for an extension that defines composite types,
there's currently no easy way to get a TupleDesc, even for its own types.

Something like
TupleDesc get_extension_type_tupledesc(const char *extname, const char
*typname)

Here's a routine I've stolen borrowed from pramsey's code and have been
using ever since.

Could this be exposed in extension.h ? (probably without the version check)

I don't think this functionality is generally useful. Wrapping
TypeGetTupleDesc(typoid, NIL) is very specific, and probably this code
should be inside the extension.

Different question is API for searching in system catalog and dependencies.
I can imagine some functions like

Oid extid = get_extension_id(extname);
Oid objid = get_extension_object_id(extid, schema_can_be_null, name,
TYPEOID); // can be used for routine, table, ...

tupdesc = TypeGetTupleDesc(objid, NIL);

Regards

Pavel

#3Pavel Stehule
pavel.stehule@gmail.com
In reply to: Florents Tselai (#1)
Re: Get TupleDesc for extension-defined types

st 18. 9. 2024 v 9:04 odesílatel Florents Tselai <florents.tselai@gmail.com>
napsal:

Correct me if I'm wrong,
but for an extension that defines composite types,
there's currently no easy way to get a TupleDesc, even for its own types.

Something like
TupleDesc get_extension_type_tupledesc(const char *extname, const char
*typname)

Here's a routine I've stolen borrowed from pramsey's code and have been
using ever since.

Could this be exposed in extension.h ? (probably without the version check)

Another significant issue - an only name is not a unique identifier in an
extension.

Regards

Pavel

#4Florents Tselai
florents.tselai@gmail.com
In reply to: Pavel Stehule (#2)
Re: Get TupleDesc for extension-defined types

On Wed, Sep 18, 2024 at 1:09 PM Pavel Stehule <pavel.stehule@gmail.com>
wrote:

Hi

st 18. 9. 2024 v 9:04 odesílatel Florents Tselai <
florents.tselai@gmail.com> napsal:

Correct me if I'm wrong,
but for an extension that defines composite types,
there's currently no easy way to get a TupleDesc, even for its own types.

Something like
TupleDesc get_extension_type_tupledesc(const char *extname, const char
*typname)

Here's a routine I've stolen borrowed from pramsey's code and have been
using ever since.

Could this be exposed in extension.h ? (probably without the version
check)

I don't think this functionality is generally useful. Wrapping
TypeGetTupleDesc(typoid, NIL) is very specific, and probably this code
should be inside the extension.

Different question is API for searching in system catalog and
dependencies. I can imagine some functions like

That's a better phrasing

Oid extid = get_extension_id(extname);
Oid objid = get_extension_object_id(extid, schema_can_be_null, name,
TYPEOID); // can be used for routine, table, ...

tupdesc = TypeGetTupleDesc(objid, NIL);

These are valid.
For context:
The "problem" (inconvenience really) I'm trying to solve is this:
Most extensions define some convenient PG_GETARG_MYTYPE(n) macros.
When these types are varlena, things are easy.

When they're composite types though things get more verbose.
i.e. the lines of code the author needs to get from a Datum argument to
struct MyType are too many
and multiple extensions copy-paste the same logic.

My hope is we could come up with a few routines that ease and standardize
this a bit.

You're right that extname isn't unique, so Oid should be the argument for
extension, rather than char *extname,
but in my mind the "default" is "the current extension" , but no arguing
about that.

Show quoted text

Regards

Pavel

#5Pavel Stehule
pavel.stehule@gmail.com
In reply to: Florents Tselai (#4)
Re: Get TupleDesc for extension-defined types

st 18. 9. 2024 v 16:25 odesílatel Florents Tselai <florents.tselai@gmail.com>
napsal:

On Wed, Sep 18, 2024 at 1:09 PM Pavel Stehule <pavel.stehule@gmail.com>
wrote:

Hi

st 18. 9. 2024 v 9:04 odesílatel Florents Tselai <
florents.tselai@gmail.com> napsal:

Correct me if I'm wrong,
but for an extension that defines composite types,
there's currently no easy way to get a TupleDesc, even for its own types.

Something like
TupleDesc get_extension_type_tupledesc(const char *extname, const char
*typname)

Here's a routine I've stolen borrowed from pramsey's code and have been
using ever since.

Could this be exposed in extension.h ? (probably without the version
check)

I don't think this functionality is generally useful. Wrapping
TypeGetTupleDesc(typoid, NIL) is very specific, and probably this code
should be inside the extension.

Different question is API for searching in system catalog and
dependencies. I can imagine some functions like

That's a better phrasing

Oid extid = get_extension_id(extname);
Oid objid = get_extension_object_id(extid, schema_can_be_null, name,
TYPEOID); // can be used for routine, table, ...

tupdesc = TypeGetTupleDesc(objid, NIL);

These are valid.
For context:
The "problem" (inconvenience really) I'm trying to solve is this:
Most extensions define some convenient PG_GETARG_MYTYPE(n) macros.
When these types are varlena, things are easy.

When they're composite types though things get more verbose.
i.e. the lines of code the author needs to get from a Datum argument to
struct MyType are too many
and multiple extensions copy-paste the same logic.

My hope is we could come up with a few routines that ease and standardize
this a bit.

You're right that extname isn't unique, so Oid should be the argument for
extension, rather than char *extname,
but in my mind the "default" is "the current extension" , but no arguing
about that.

what you mean "the current extension" - there is nothing like this. The
functions have not any information without searching in the catalog about
their extension. Function knows just its own oid and arguments. I can
imagine so fmgr can be enhanced by it - it can reduce some searching, but
currently there is nothing like current or owner extension (extension id).

Show quoted text

Regards

Pavel