Update extension lookup routines to use the syscache

The following routines are changed to use the syscache entries added for
pg_extension in 490f869d92:
- get_extension_oid()
- get_extension_name()
- get_extension_schema()

A catalog scan is costly and could easily lead to a noticeable
performance impact when called once or more per query, so this is going
to be helpful for developers for extension data lookups.

Author: Andrei Lepikhov
Reviewed-by: Jelte Fennema-Nio
Discussion: https://postgr.es/m/529295b2-6ba9-4dae-acd1-20a9c6fb8f9a@gmail.com
This commit is contained in:
Michael Paquier 2024-09-07 20:20:46 +09:00
parent 51edc4ca54
commit d8df7ac5c0

View File

@ -64,6 +64,7 @@
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "utils/snapmgr.h" #include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/varlena.h" #include "utils/varlena.h"
@ -145,33 +146,10 @@ Oid
get_extension_oid(const char *extname, bool missing_ok) get_extension_oid(const char *extname, bool missing_ok)
{ {
Oid result; Oid result;
Relation rel;
SysScanDesc scandesc;
HeapTuple tuple;
ScanKeyData entry[1];
rel = table_open(ExtensionRelationId, AccessShareLock); result = GetSysCacheOid1(EXTENSIONNAME, Anum_pg_extension_oid,
ScanKeyInit(&entry[0],
Anum_pg_extension_extname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(extname)); CStringGetDatum(extname));
scandesc = systable_beginscan(rel, ExtensionNameIndexId, true,
NULL, 1, entry);
tuple = systable_getnext(scandesc);
/* We assume that there can be at most one matching tuple */
if (HeapTupleIsValid(tuple))
result = ((Form_pg_extension) GETSTRUCT(tuple))->oid;
else
result = InvalidOid;
systable_endscan(scandesc);
table_close(rel, AccessShareLock);
if (!OidIsValid(result) && !missing_ok) if (!OidIsValid(result) && !missing_ok)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
@ -190,32 +168,15 @@ char *
get_extension_name(Oid ext_oid) get_extension_name(Oid ext_oid)
{ {
char *result; char *result;
Relation rel;
SysScanDesc scandesc;
HeapTuple tuple; HeapTuple tuple;
ScanKeyData entry[1];
rel = table_open(ExtensionRelationId, AccessShareLock); tuple = SearchSysCache1(EXTENSIONOID, ObjectIdGetDatum(ext_oid));
ScanKeyInit(&entry[0], if (!HeapTupleIsValid(tuple))
Anum_pg_extension_oid, return NULL;
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))
result = pstrdup(NameStr(((Form_pg_extension) GETSTRUCT(tuple))->extname)); result = pstrdup(NameStr(((Form_pg_extension) GETSTRUCT(tuple))->extname));
else ReleaseSysCache(tuple);
result = NULL;
systable_endscan(scandesc);
table_close(rel, AccessShareLock);
return result; return result;
} }
@ -229,32 +190,15 @@ Oid
get_extension_schema(Oid ext_oid) get_extension_schema(Oid ext_oid)
{ {
Oid result; Oid result;
Relation rel;
SysScanDesc scandesc;
HeapTuple tuple; HeapTuple tuple;
ScanKeyData entry[1];
rel = table_open(ExtensionRelationId, AccessShareLock); tuple = SearchSysCache1(EXTENSIONOID, ObjectIdGetDatum(ext_oid));
ScanKeyInit(&entry[0], if (!HeapTupleIsValid(tuple))
Anum_pg_extension_oid, return InvalidOid;
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))
result = ((Form_pg_extension) GETSTRUCT(tuple))->extnamespace; result = ((Form_pg_extension) GETSTRUCT(tuple))->extnamespace;
else ReleaseSysCache(tuple);
result = InvalidOid;
systable_endscan(scandesc);
table_close(rel, AccessShareLock);
return result; return result;
} }