Postgres C-API: How to get the Oid for a custom type defined in a schema outside of the current search path

Started by Michael Krügerover 5 years ago5 messagesgeneral
Jump to latest
#1Michael Krüger
michael@kruegers.email

Dear all,

I need to find out the Oid of a custom type in C programming language. This type is defined in a schema, outside of the standard search path, e.g. public.
I know that I can call TypenameGetTypid to find out an Oid. But this is not working for me if the type is not in the public namespace.
How can I query a non-public Oid? Do I have to change the search path? If yes how do I do it? As mentioned I need to do this with the C interface.

Regards,
Michael

Email: michael@kruegers.email

#2Pavel Stehule
pavel.stehule@gmail.com
In reply to: Michael Krüger (#1)
Re: Postgres C-API: How to get the Oid for a custom type defined in a schema outside of the current search path

Hi

čt 3. 12. 2020 v 10:32 odesílatel Michael Krüger <michael@kruegers.email>
napsal:

Dear all,

I need to find out the Oid of a custom type in C programming language.
This type is defined in a schema, outside of the standard search path, e.g.
public.
I know that I can call TypenameGetTypid to find out an Oid. But this is
not working for me if the type is not in the public namespace.
How can I query a non-public Oid? Do I have to change the search path? If
yes how do I do it? As mentioned I need to do this with the C interface.

I looking to source code

Oid
TypenameGetTypidExtended(const char *typname, bool temp_ok)
{
<-->Oid><--><-->typid;
<-->ListCell *l;

<-->recomputeNamespacePath();

<-->foreach(l, activeSearchPath)
<-->{
<--><-->Oid><--><-->namespaceId = lfirst_oid(l);

<--><-->if (!temp_ok && namespaceId == myTempNamespace)
<--><--><-->continue;<-><--><-->/* do not look in temp namespace */

<--><-->typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
<--><--><--><--><--><--><--><-->PointerGetDatum(typname),
<--><--><--><--><--><--><--><-->ObjectIdGetDatum(namespaceId));
<--><-->if (OidIsValid(typid))
<--><--><-->return typid;
<-->}

<-->/* Not found in path */
<-->return InvalidOid;
}

You can get the value from sys cache by call GetSysCacheOid2. It can looks
like

<--><-->char<--> *schemaname;
<--><-->char<--> *typname;
<--><--><-->namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
<--><--><-->if (OidIsValid(namespaceId))
<--><--><--><-->typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
<--><--><--><--><--><--><--><--><--><--> PointerGetDatum(typname),
<--><--><--><--><--><--><--><--><--><--> ObjectIdGetDatum(namespaceId));
<--><--><-->else
<--><--><--><-->typoid = InvalidOid;

Regards

Pavel

Show quoted text

Regards,
Michael

Email: michael@kruegers.email

#3Michael Krüger
michael@kruegers.email
In reply to: Pavel Stehule (#2)
Re: Postgres C-API: How to get the Oid for a custom type defined in a schema outside of the current search path

Hi,

Am 03.12.2020 um 11:01 schrieb Pavel Stehule <pavel.stehule@gmail.com>:

Hi

čt 3. 12. 2020 v 10:32 odesílatel Michael Krüger <michael@kruegers.email> napsal:
Dear all,

I need to find out the Oid of a custom type in C programming language. This type is defined in a schema, outside of the standard search path, e.g. public.
I know that I can call TypenameGetTypid to find out an Oid. But this is not working for me if the type is not in the public namespace.
How can I query a non-public Oid? Do I have to change the search path? If yes how do I do it? As mentioned I need to do this with the C interface.

I looking to source code

Oid
TypenameGetTypidExtended(const char *typname, bool temp_ok)
{
<-->Oid><--><-->typid;
<-->ListCell *l;

<-->recomputeNamespacePath();

<-->foreach(l, activeSearchPath)
<-->{
<--><-->Oid><--><-->namespaceId = lfirst_oid(l);

<--><-->if (!temp_ok && namespaceId == myTempNamespace)
<--><--><-->continue;<-><--><-->/* do not look in temp namespace */

<--><-->typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
<--><--><--><--><--><--><--><-->PointerGetDatum(typname),
<--><--><--><--><--><--><--><-->ObjectIdGetDatum(namespaceId));
<--><-->if (OidIsValid(typid))
<--><--><-->return typid;
<-->}

<-->/* Not found in path */
<-->return InvalidOid;
}

You can get the value from sys cache by call GetSysCacheOid2. It can looks like

<--><-->char<--> *schemaname;
<--><-->char<--> *typname;
<--><--><-->namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
<--><--><-->if (OidIsValid(namespaceId))
<--><--><--><-->typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
<--><--><--><--><--><--><--><--><--><--> PointerGetDatum(typname),
<--><--><--><--><--><--><--><--><--><--> ObjectIdGetDatum(namespaceId));
<--><--><-->else
<--><--><--><-->typoid = InvalidOid;

Thank you so much. That worked.

Regards,
Michael

#4Pavel Stehule
pavel.stehule@gmail.com
In reply to: Michael Krüger (#3)
Re: Postgres C-API: How to get the Oid for a custom type defined in a schema outside of the current search path

čt 3. 12. 2020 v 11:44 odesílatel Michael Krüger <michael@kruegers.email>
napsal:

Hi,

Am 03.12.2020 um 11:01 schrieb Pavel Stehule <pavel.stehule@gmail.com>:

Hi

čt 3. 12. 2020 v 10:32 odesílatel Michael Krüger <michael@kruegers.email>
napsal:

Dear all,

I need to find out the Oid of a custom type in C programming language.
This type is defined in a schema, outside of the standard search path, e.g.
public.
I know that I can call TypenameGetTypid to find out an Oid. But this is
not working for me if the type is not in the public namespace.
How can I query a non-public Oid? Do I have to change the search path? If
yes how do I do it? As mentioned I need to do this with the C interface.

I looking to source code

Oid
TypenameGetTypidExtended(const char *typname, bool temp_ok)
{
<-->Oid><--><-->typid;
<-->ListCell *l;

<-->recomputeNamespacePath();

<-->foreach(l, activeSearchPath)
<-->{
<--><-->Oid><--><-->namespaceId = lfirst_oid(l);

<--><-->if (!temp_ok && namespaceId == myTempNamespace)
<--><--><-->continue;<-><--><-->/* do not look in temp namespace */

<--><-->typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
<--><--><--><--><--><--><--><-->PointerGetDatum(typname),
<--><--><--><--><--><--><--><-->ObjectIdGetDatum(namespaceId));
<--><-->if (OidIsValid(typid))
<--><--><-->return typid;
<-->}

<-->/* Not found in path */
<-->return InvalidOid;
}

You can get the value from sys cache by call GetSysCacheOid2. It can looks
like

<--><-->char<--> *schemaname;
<--><-->char<--> *typname;
<--><--><-->namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
<--><--><-->if (OidIsValid(namespaceId))
<--><--><--><-->typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
<--><--><--><--><--><--><--><--><--><--> PointerGetDatum(typname),
<--><--><--><--><--><--><--><--><--><--> ObjectIdGetDatum(namespaceId));
<--><--><-->else
<--><--><--><-->typoid = InvalidOid;

Thank you so much. That worked.

with pleasure.

When you write C extensions for Postgres, then PostgreSQL source code is
the best source of inspiration.

Regards

Pavel

Show quoted text

Regards,
Michael

#5Michael Paquier
michael@paquier.xyz
In reply to: Pavel Stehule (#4)
Re: Postgres C-API: How to get the Oid for a custom type defined in a schema outside of the current search path

On Thu, Dec 03, 2020 at 01:45:05PM +0100, Pavel Stehule wrote:

When you write C extensions for Postgres, then PostgreSQL source code is
the best source of inspiration.

One common source of inspiration for such cases is regproc.c. For a
type, you can for example look at what to_regtype() uses for a
conversion from a name string to an OID, aka parseTypeString().
--
Michael