Here are two patches that refactor the mostly repetitive "${object} is
visible" and get_${object}_oid() functions in namespace.c. This uses
the functions in objectaddress.c to look up the appropriate per-catalog
system caches and attribute numbers, similar to other refactoring
patches I have posted recently.
In both cases, there are some functions that have special behaviors that
are not easy to unify, so I left those alone for now.
Notes on 0001-Refactor-is-visible-functions.patch:
Among the functions that are being unified, some check temp schemas and
some skip them. I suppose that this is because some (most) object types
cannot normally be in temp schemas, but this isn't made explicit in the
code. I added a code comment about this, the way I understand it.
That said, you can create objects explicitly in temp schemas, so I'm not
sure the existing code is completely correct.
Notes on 0002-Refactor-common-parts-of-get_-_oid-functions.patch:
Here, I only extracted the common parts of each function but left the
actual functions alone, because they each have to produce their own
error message. There is a possibility to generalize this further,
perhaps in the style of does_not_exist_skipping(), but that looked like
a separate step to me.
From dbbba36ba506c44baa90feabf3857ced3de87c78 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 14 Feb 2023 12:16:36 +0100
Subject: [PATCH 1/2] Refactor "is visible" functions
---
contrib/dblink/dblink.c | 2 +-
src/backend/catalog/namespace.c | 545 ++--------------------------
src/backend/catalog/objectaddress.c | 14 +-
src/backend/utils/adt/format_type.c | 2 +-
src/backend/utils/adt/regproc.c | 6 +-
src/backend/utils/adt/ruleutils.c | 2 +-
src/include/catalog/namespace.h | 12 +-
7 files changed, 50 insertions(+), 533 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 78a8bcee6e..3f345ea540 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -2491,7 +2491,7 @@ generate_relation_name(Relation rel)
char *result;
/* Qualify the name if not visible in search path */
- if (RelationIsVisible(RelationGetRelid(rel)))
+ if (ObjectIsVisible(RelationRelationId, RelationGetRelid(rel)))
nspname = NULL;
else
nspname = get_namespace_name(rel->rd_rel->relnamespace);
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 14e57adee2..6179c3f678 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -701,71 +701,6 @@ RelnameGetRelid(const char *relname)
}
-/*
- * RelationIsVisible
- * Determine whether a relation (identified by OID) is visible in
the
- * current search path. Visible means "would be found by searching
- * for the unqualified relation name".
- */
-bool
-RelationIsVisible(Oid relid)
-{
- HeapTuple reltup;
- Form_pg_class relform;
- Oid relnamespace;
- bool visible;
-
- reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
- if (!HeapTupleIsValid(reltup))
- elog(ERROR, "cache lookup failed for relation %u", relid);
- relform = (Form_pg_class) GETSTRUCT(reltup);
-
- recomputeNamespacePath();
-
- /*
- * Quick check: if it ain't in the path at all, it ain't visible. Items
in
- * the system namespace are surely in the path and so we needn't even do
- * list_member_oid() for them.
- */
- relnamespace = relform->relnamespace;
- if (relnamespace != PG_CATALOG_NAMESPACE &&
- !list_member_oid(activeSearchPath, relnamespace))
- visible = false;
- else
- {
- /*
- * If it is in the path, it might still not be visible; it
could be
- * hidden by another relation of the same name earlier in the
path. So
- * we must do a slow check for conflicting relations.
- */
- char *relname = NameStr(relform->relname);
- ListCell *l;
-
- visible = false;
- foreach(l, activeSearchPath)
- {
- Oid namespaceId = lfirst_oid(l);
-
- if (namespaceId == relnamespace)
- {
- /* Found it first in path */
- visible = true;
- break;
- }
- if (OidIsValid(get_relname_relid(relname, namespaceId)))
- {
- /* Found something else first in path */
- break;
- }
- }
- }
-
- ReleaseSysCache(reltup);
-
- return visible;
-}
-
-
/*
* TypenameGetTypid
* Wrapper for binary compatibility.
@@ -809,72 +744,6 @@ TypenameGetTypidExtended(const char *typname, bool temp_ok)
return InvalidOid;
}
-/*
- * TypeIsVisible
- * Determine whether a type (identified by OID) is visible in the
- * current search path. Visible means "would be found by searching
- * for the unqualified type name".
- */
-bool
-TypeIsVisible(Oid typid)
-{
- HeapTuple typtup;
- Form_pg_type typform;
- Oid typnamespace;
- bool visible;
-
- typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
- if (!HeapTupleIsValid(typtup))
- elog(ERROR, "cache lookup failed for type %u", typid);
- typform = (Form_pg_type) GETSTRUCT(typtup);
-
- recomputeNamespacePath();
-
- /*
- * Quick check: if it ain't in the path at all, it ain't visible. Items
in
- * the system namespace are surely in the path and so we needn't even do
- * list_member_oid() for them.
- */
- typnamespace = typform->typnamespace;
- if (typnamespace != PG_CATALOG_NAMESPACE &&
- !list_member_oid(activeSearchPath, typnamespace))
- visible = false;
- else
- {
- /*
- * If it is in the path, it might still not be visible; it
could be
- * hidden by another type of the same name earlier in the path.
So we
- * must do a slow check for conflicting types.
- */
- char *typname = NameStr(typform->typname);
- ListCell *l;
-
- visible = false;
- foreach(l, activeSearchPath)
- {
- Oid namespaceId = lfirst_oid(l);
-
- if (namespaceId == typnamespace)
- {
- /* Found it first in path */
- visible = true;
- break;
- }
- if (SearchSysCacheExists2(TYPENAMENSP,
-
PointerGetDatum(typname),
-
ObjectIdGetDatum(namespaceId)))
- {
- /* Found something else first in path */
- break;
- }
- }
- }
-
- ReleaseSysCache(typtup);
-
- return visible;
-}
-
/*
* FuncnameGetCandidates
@@ -2130,88 +1999,6 @@ CollationIsVisible(Oid collid)
return visible;
}
-
-/*
- * ConversionGetConid
- * Try to resolve an unqualified conversion name.
- * Returns OID if conversion found in search path, else InvalidOid.
- *
- * This is essentially the same as RelnameGetRelid.
- */
-Oid
-ConversionGetConid(const char *conname)
-{
- Oid conid;
- ListCell *l;
-
- recomputeNamespacePath();
-
- foreach(l, activeSearchPath)
- {
- Oid namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
-
- conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
-
PointerGetDatum(conname),
-
ObjectIdGetDatum(namespaceId));
- if (OidIsValid(conid))
- return conid;
- }
-
- /* Not found in path */
- return InvalidOid;
-}
-
-/*
- * ConversionIsVisible
- * Determine whether a conversion (identified by OID) is visible
in the
- * current search path. Visible means "would be found by searching
- * for the unqualified conversion name".
- */
-bool
-ConversionIsVisible(Oid conid)
-{
- HeapTuple contup;
- Form_pg_conversion conform;
- Oid connamespace;
- bool visible;
-
- contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
- if (!HeapTupleIsValid(contup))
- elog(ERROR, "cache lookup failed for conversion %u", conid);
- conform = (Form_pg_conversion) GETSTRUCT(contup);
-
- recomputeNamespacePath();
-
- /*
- * Quick check: if it ain't in the path at all, it ain't visible. Items
in
- * the system namespace are surely in the path and so we needn't even do
- * list_member_oid() for them.
- */
- connamespace = conform->connamespace;
- if (connamespace != PG_CATALOG_NAMESPACE &&
- !list_member_oid(activeSearchPath, connamespace))
- visible = false;
- else
- {
- /*
- * If it is in the path, it might still not be visible; it
could be
- * hidden by another conversion of the same name earlier in the
path.
- * So we must do a slow check to see if this conversion would
be found
- * by ConversionGetConid.
- */
- char *conname = NameStr(conform->conname);
-
- visible = (ConversionGetConid(conname) == conid);
- }
-
- ReleaseSysCache(contup);
-
- return visible;
-}
-
/*
* get_statistics_object_oid - find a statistics object by possibly qualified
name
*
@@ -2268,72 +2055,6 @@ get_statistics_object_oid(List *names, bool missing_ok)
return stats_oid;
}
-/*
- * StatisticsObjIsVisible
- * Determine whether a statistics object (identified by OID) is
visible in
- * the current search path. Visible means "would be found by
searching
- * for the unqualified statistics object name".
- */
-bool
-StatisticsObjIsVisible(Oid relid)
-{
- HeapTuple stxtup;
- Form_pg_statistic_ext stxform;
- Oid stxnamespace;
- bool visible;
-
- stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
- if (!HeapTupleIsValid(stxtup))
- elog(ERROR, "cache lookup failed for statistics object %u",
relid);
- stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
-
- recomputeNamespacePath();
-
- /*
- * Quick check: if it ain't in the path at all, it ain't visible. Items
in
- * the system namespace are surely in the path and so we needn't even do
- * list_member_oid() for them.
- */
- stxnamespace = stxform->stxnamespace;
- if (stxnamespace != PG_CATALOG_NAMESPACE &&
- !list_member_oid(activeSearchPath, stxnamespace))
- visible = false;
- else
- {
- /*
- * If it is in the path, it might still not be visible; it
could be
- * hidden by another statistics object of the same name earlier
in the
- * path. So we must do a slow check for conflicting objects.
- */
- char *stxname = NameStr(stxform->stxname);
- ListCell *l;
-
- visible = false;
- foreach(l, activeSearchPath)
- {
- Oid namespaceId = lfirst_oid(l);
-
- if (namespaceId == stxnamespace)
- {
- /* Found it first in path */
- visible = true;
- break;
- }
- if (SearchSysCacheExists2(STATEXTNAMENSP,
-
PointerGetDatum(stxname),
-
ObjectIdGetDatum(namespaceId)))
- {
- /* Found something else first in path */
- break;
- }
- }
- }
-
- ReleaseSysCache(stxtup);
-
- return visible;
-}
-
/*
* get_ts_parser_oid - find a TS parser by possibly qualified name
*
@@ -2391,75 +2112,6 @@ get_ts_parser_oid(List *names, bool missing_ok)
return prsoid;
}
-/*
- * TSParserIsVisible
- * Determine whether a parser (identified by OID) is visible in the
- * current search path. Visible means "would be found by searching
- * for the unqualified parser name".
- */
-bool
-TSParserIsVisible(Oid prsId)
-{
- HeapTuple tup;
- Form_pg_ts_parser form;
- Oid namespace;
- bool visible;
-
- tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId));
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search parser %u",
prsId);
- form = (Form_pg_ts_parser) GETSTRUCT(tup);
-
- recomputeNamespacePath();
-
- /*
- * Quick check: if it ain't in the path at all, it ain't visible. Items
in
- * the system namespace are surely in the path and so we needn't even do
- * list_member_oid() for them.
- */
- namespace = form->prsnamespace;
- if (namespace != PG_CATALOG_NAMESPACE &&
- !list_member_oid(activeSearchPath, namespace))
- visible = false;
- else
- {
- /*
- * If it is in the path, it might still not be visible; it
could be
- * hidden by another parser of the same name earlier in the
path. So
- * we must do a slow check for conflicting parsers.
- */
- char *name = NameStr(form->prsname);
- ListCell *l;
-
- visible = false;
- foreach(l, activeSearchPath)
- {
- Oid namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
-
- if (namespaceId == namespace)
- {
- /* Found it first in path */
- visible = true;
- break;
- }
- if (SearchSysCacheExists2(TSPARSERNAMENSP,
-
PointerGetDatum(name),
-
ObjectIdGetDatum(namespaceId)))
- {
- /* Found something else first in path */
- break;
- }
- }
- }
-
- ReleaseSysCache(tup);
-
- return visible;
-}
-
/*
* get_ts_dict_oid - find a TS dictionary by possibly qualified name
*
@@ -2517,76 +2169,6 @@ get_ts_dict_oid(List *names, bool missing_ok)
return dictoid;
}
-/*
- * TSDictionaryIsVisible
- * Determine whether a dictionary (identified by OID) is visible
in the
- * current search path. Visible means "would be found by searching
- * for the unqualified dictionary name".
- */
-bool
-TSDictionaryIsVisible(Oid dictId)
-{
- HeapTuple tup;
- Form_pg_ts_dict form;
- Oid namespace;
- bool visible;
-
- tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search dictionary %u",
- dictId);
- form = (Form_pg_ts_dict) GETSTRUCT(tup);
-
- recomputeNamespacePath();
-
- /*
- * Quick check: if it ain't in the path at all, it ain't visible. Items
in
- * the system namespace are surely in the path and so we needn't even do
- * list_member_oid() for them.
- */
- namespace = form->dictnamespace;
- if (namespace != PG_CATALOG_NAMESPACE &&
- !list_member_oid(activeSearchPath, namespace))
- visible = false;
- else
- {
- /*
- * If it is in the path, it might still not be visible; it
could be
- * hidden by another dictionary of the same name earlier in the
path.
- * So we must do a slow check for conflicting dictionaries.
- */
- char *name = NameStr(form->dictname);
- ListCell *l;
-
- visible = false;
- foreach(l, activeSearchPath)
- {
- Oid namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
-
- if (namespaceId == namespace)
- {
- /* Found it first in path */
- visible = true;
- break;
- }
- if (SearchSysCacheExists2(TSDICTNAMENSP,
-
PointerGetDatum(name),
-
ObjectIdGetDatum(namespaceId)))
- {
- /* Found something else first in path */
- break;
- }
- }
- }
-
- ReleaseSysCache(tup);
-
- return visible;
-}
-
/*
* get_ts_template_oid - find a TS template by possibly qualified name
*
@@ -2644,75 +2226,6 @@ get_ts_template_oid(List *names, bool missing_ok)
return tmploid;
}
-/*
- * TSTemplateIsVisible
- * Determine whether a template (identified by OID) is visible in
the
- * current search path. Visible means "would be found by searching
- * for the unqualified template name".
- */
-bool
-TSTemplateIsVisible(Oid tmplId)
-{
- HeapTuple tup;
- Form_pg_ts_template form;
- Oid namespace;
- bool visible;
-
- tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search template %u",
tmplId);
- form = (Form_pg_ts_template) GETSTRUCT(tup);
-
- recomputeNamespacePath();
-
- /*
- * Quick check: if it ain't in the path at all, it ain't visible. Items
in
- * the system namespace are surely in the path and so we needn't even do
- * list_member_oid() for them.
- */
- namespace = form->tmplnamespace;
- if (namespace != PG_CATALOG_NAMESPACE &&
- !list_member_oid(activeSearchPath, namespace))
- visible = false;
- else
- {
- /*
- * If it is in the path, it might still not be visible; it
could be
- * hidden by another template of the same name earlier in the
path. So
- * we must do a slow check for conflicting templates.
- */
- char *name = NameStr(form->tmplname);
- ListCell *l;
-
- visible = false;
- foreach(l, activeSearchPath)
- {
- Oid namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
-
- if (namespaceId == namespace)
- {
- /* Found it first in path */
- visible = true;
- break;
- }
- if (SearchSysCacheExists2(TSTEMPLATENAMENSP,
-
PointerGetDatum(name),
-
ObjectIdGetDatum(namespaceId)))
- {
- /* Found something else first in path */
- break;
- }
- }
- }
-
- ReleaseSysCache(tup);
-
- return visible;
-}
-
/*
* get_ts_config_oid - find a TS config by possibly qualified name
*
@@ -2770,25 +2283,25 @@ get_ts_config_oid(List *names, bool missing_ok)
return cfgoid;
}
+
/*
- * TSConfigIsVisible
- * Determine whether a text search configuration (identified by
OID)
+ * ObjectIsVisible
+ * Determine whether an object (identified by class ID and OID)
* is visible in the current search path. Visible means "would be
found
- * by searching for the unqualified text search configuration
name".
+ * by searching for the unqualified object name".
*/
bool
-TSConfigIsVisible(Oid cfgid)
+ObjectIsVisible(Oid classid, Oid objectid)
{
+ int oid_cacheid = get_object_catcache_oid(classid);
HeapTuple tup;
- Form_pg_ts_config form;
+ bool isnull;
Oid namespace;
bool visible;
- tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid));
+ tup = SearchSysCache1(oid_cacheid, ObjectIdGetDatum(objectid));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search configuration
%u",
- cfgid);
- form = (Form_pg_ts_config) GETSTRUCT(tup);
+ elog(ERROR, "cache lookup failed for %s %u",
get_object_class_descr(classid), objectid);
recomputeNamespacePath();
@@ -2797,7 +2310,11 @@ TSConfigIsVisible(Oid cfgid)
* the system namespace are surely in the path and so we needn't even do
* list_member_oid() for them.
*/
- namespace = form->cfgnamespace;
+ namespace = DatumGetObjectId(SysCacheGetAttr(oid_cacheid,
+
tup,
+
get_object_attnum_namespace(classid),
+
&isnull));
+ Assert(!isnull);
if (namespace != PG_CATALOG_NAMESPACE &&
!list_member_oid(activeSearchPath, namespace))
visible = false;
@@ -2808,16 +2325,24 @@ TSConfigIsVisible(Oid cfgid)
* hidden by another configuration of the same name earlier in
the
* path. So we must do a slow check for conflicting
configurations.
*/
- char *name = NameStr(form->cfgname);
+ Datum name_datum;
ListCell *l;
+ name_datum = SysCacheGetAttr(oid_cacheid, tup,
get_object_attnum_name(classid), &isnull);
+ Assert(!isnull);
+
visible = false;
foreach(l, activeSearchPath)
{
Oid namespaceId = lfirst_oid(l);
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
+ /*
+ * Do not look in temp namespace for object types that
don't
+ * support temporary objects
+ */
+ if (!(classid == RelationRelationId || classid ==
TypeRelationId) &&
+ namespaceId == myTempNamespace)
+ continue;
if (namespaceId == namespace)
{
@@ -2825,8 +2350,8 @@ TSConfigIsVisible(Oid cfgid)
visible = true;
break;
}
- if (SearchSysCacheExists2(TSCONFIGNAMENSP,
-
PointerGetDatum(name),
+ if
(SearchSysCacheExists2(get_object_catcache_name(classid),
+
name_datum,
ObjectIdGetDatum(namespaceId)))
{
/* Found something else first in path */
@@ -4509,7 +4034,7 @@ pg_table_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(RelationIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(RelationRelationId, oid));
}
Datum
@@ -4520,7 +4045,7 @@ pg_type_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(TypeIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(TypeRelationId, oid));
}
Datum
@@ -4586,7 +4111,7 @@ pg_conversion_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(CONVOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(ConversionIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(ConversionRelationId, oid));
}
Datum
@@ -4597,7 +4122,7 @@ pg_statistics_obj_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(STATEXTOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(StatisticsObjIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(StatisticExtRelationId, oid));
}
Datum
@@ -4608,7 +4133,7 @@ pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TSPARSEROID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(TSParserIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(TSParserRelationId, oid));
}
Datum
@@ -4619,7 +4144,7 @@ pg_ts_dict_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TSDICTOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(TSDictionaryIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(TSDictionaryRelationId, oid));
}
Datum
@@ -4630,7 +4155,7 @@ pg_ts_template_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TSTEMPLATEOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(TSTemplateIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(TSTemplateRelationId, oid));
}
Datum
@@ -4641,7 +4166,7 @@ pg_ts_config_is_visible(PG_FUNCTION_ARGS)
if (!SearchSysCacheExists1(TSCONFIGOID, ObjectIdGetDatum(oid)))
PG_RETURN_NULL();
- PG_RETURN_BOOL(TSConfigIsVisible(oid));
+ PG_RETURN_BOOL(ObjectIsVisible(TSConfigRelationId, oid));
}
Datum
diff --git a/src/backend/catalog/objectaddress.c
b/src/backend/catalog/objectaddress.c
index 2f688166e1..15ba7ee316 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -3097,7 +3097,7 @@ getObjectDescription(const ObjectAddress *object, bool
missing_ok)
conv = (Form_pg_conversion) GETSTRUCT(conTup);
/* Qualify the name if not visible in search
path */
- if (ConversionIsVisible(object->objectId))
+ if (ObjectIsVisible(ConversionRelationId,
object->objectId))
nspname = NULL;
else
nspname =
get_namespace_name(conv->connamespace);
@@ -3468,7 +3468,7 @@ getObjectDescription(const ObjectAddress *object, bool
missing_ok)
stxForm = (Form_pg_statistic_ext)
GETSTRUCT(stxTup);
/* Qualify the name if not visible in search
path */
- if (StatisticsObjIsVisible(object->objectId))
+ if (ObjectIsVisible(StatisticExtRelationId,
object->objectId))
nspname = NULL;
else
nspname =
get_namespace_name(stxForm->stxnamespace);
@@ -3499,7 +3499,7 @@ getObjectDescription(const ObjectAddress *object, bool
missing_ok)
prsForm = (Form_pg_ts_parser) GETSTRUCT(tup);
/* Qualify the name if not visible in search
path */
- if (TSParserIsVisible(object->objectId))
+ if (ObjectIsVisible(TSParserRelationId,
object->objectId))
nspname = NULL;
else
nspname =
get_namespace_name(prsForm->prsnamespace);
@@ -3530,7 +3530,7 @@ getObjectDescription(const ObjectAddress *object, bool
missing_ok)
dictForm = (Form_pg_ts_dict) GETSTRUCT(tup);
/* Qualify the name if not visible in search
path */
- if (TSDictionaryIsVisible(object->objectId))
+ if (ObjectIsVisible(TSDictionaryRelationId,
object->objectId))
nspname = NULL;
else
nspname =
get_namespace_name(dictForm->dictnamespace);
@@ -3561,7 +3561,7 @@ getObjectDescription(const ObjectAddress *object, bool
missing_ok)
tmplForm = (Form_pg_ts_template) GETSTRUCT(tup);
/* Qualify the name if not visible in search
path */
- if (TSTemplateIsVisible(object->objectId))
+ if (ObjectIsVisible(TSTemplateRelationId,
object->objectId))
nspname = NULL;
else
nspname =
get_namespace_name(tmplForm->tmplnamespace);
@@ -3592,7 +3592,7 @@ getObjectDescription(const ObjectAddress *object, bool
missing_ok)
cfgForm = (Form_pg_ts_config) GETSTRUCT(tup);
/* Qualify the name if not visible in search
path */
- if (TSConfigIsVisible(object->objectId))
+ if (ObjectIsVisible(TSConfigRelationId,
object->objectId))
nspname = NULL;
else
nspname =
get_namespace_name(cfgForm->cfgnamespace);
@@ -4102,7 +4102,7 @@ getRelationDescription(StringInfo buffer, Oid relid, bool
missing_ok)
relForm = (Form_pg_class) GETSTRUCT(relTup);
/* Qualify the name if not visible in search path */
- if (RelationIsVisible(relid))
+ if (ObjectIsVisible(RelationRelationId, relid))
nspname = NULL;
else
nspname = get_namespace_name(relForm->relnamespace);
diff --git a/src/backend/utils/adt/format_type.c
b/src/backend/utils/adt/format_type.c
index 12402a0637..1e880d4dec 100644
--- a/src/backend/utils/adt/format_type.c
+++ b/src/backend/utils/adt/format_type.c
@@ -308,7 +308,7 @@ format_type_extended(Oid type_oid, int32 typemod, bits16
flags)
char *typname;
if ((flags & FORMAT_TYPE_FORCE_QUALIFY) == 0 &&
- TypeIsVisible(type_oid))
+ ObjectIsVisible(TypeRelationId, type_oid))
nspname = NULL;
else
nspname =
get_namespace_name_or_temp(typeform->typnamespace);
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 296930eb3b..4e65dfe10a 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -973,7 +973,7 @@ regclassout(PG_FUNCTION_ARGS)
/*
* Would this class be found by regclassin? If not,
qualify it.
*/
- if (RelationIsVisible(classid))
+ if (ObjectIsVisible(RelationRelationId, classid))
nspname = NULL;
else
nspname =
get_namespace_name(classform->relnamespace);
@@ -1359,7 +1359,7 @@ regconfigout(PG_FUNCTION_ARGS)
/*
* Would this config be found by regconfigin? If not, qualify
it.
*/
- if (TSConfigIsVisible(cfgid))
+ if (ObjectIsVisible(TSConfigRelationId, cfgid))
nspname = NULL;
else
nspname = get_namespace_name(cfgform->cfgnamespace);
@@ -1470,7 +1470,7 @@ regdictionaryout(PG_FUNCTION_ARGS)
* Would this dictionary be found by regdictionaryin? If not,
qualify
* it.
*/
- if (TSDictionaryIsVisible(dictid))
+ if (ObjectIsVisible(TSDictionaryRelationId, dictid))
nspname = NULL;
else
nspname = get_namespace_name(dictform->dictnamespace);
diff --git a/src/backend/utils/adt/ruleutils.c
b/src/backend/utils/adt/ruleutils.c
index 9ac42efdbc..3ad0f45454 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -11689,7 +11689,7 @@ generate_relation_name(Oid relid, List *namespaces)
/* Otherwise, qualify the name if not visible in search path */
if (!need_qual)
- need_qual = !RelationIsVisible(relid);
+ need_qual = !ObjectIsVisible(RelationRelationId, relid);
if (need_qual)
nspname = get_namespace_name_or_temp(reltup->relnamespace);
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index f64a0ec26b..eb23b35e4b 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -90,11 +90,9 @@ extern Oid RangeVarGetAndCheckCreationNamespace(RangeVar
*relation,
Oid *existing_relation_id);
extern void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid
nspid);
extern Oid RelnameGetRelid(const char *relname);
-extern bool RelationIsVisible(Oid relid);
extern Oid TypenameGetTypid(const char *typname);
extern Oid TypenameGetTypidExtended(const char *typname, bool temp_ok);
-extern bool TypeIsVisible(Oid typid);
extern FuncCandidateList FuncnameGetCandidates(List *names,
int nargs, List *argnames,
@@ -118,23 +116,17 @@ extern bool OpfamilyIsVisible(Oid opfid);
extern Oid CollationGetCollid(const char *collname);
extern bool CollationIsVisible(Oid collid);
-extern Oid ConversionGetConid(const char *conname);
-extern bool ConversionIsVisible(Oid conid);
-
extern Oid get_statistics_object_oid(List *names, bool missing_ok);
-extern bool StatisticsObjIsVisible(Oid relid);
extern Oid get_ts_parser_oid(List *names, bool missing_ok);
-extern bool TSParserIsVisible(Oid prsId);
extern Oid get_ts_dict_oid(List *names, bool missing_ok);
-extern bool TSDictionaryIsVisible(Oid dictId);
extern Oid get_ts_template_oid(List *names, bool missing_ok);
-extern bool TSTemplateIsVisible(Oid tmplId);
extern Oid get_ts_config_oid(List *names, bool missing_ok);
-extern bool TSConfigIsVisible(Oid cfgid);
+
+extern bool ObjectIsVisible(Oid classid, Oid objectid);
extern void DeconstructQualifiedName(List *names,
char
**nspname_p,
base-commit: 3b12e68a5c4609deb9fc69607e0aec072700c0a9
--
2.39.1
From 483fada9676f5c9b48ca5d30e1708fe41928a178 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 14 Feb 2023 13:28:42 +0100
Subject: [PATCH 2/2] Refactor common parts of get_*_oid() functions
---
src/backend/catalog/namespace.c | 204 ++++++--------------------------
1 file changed, 39 insertions(+), 165 deletions(-)
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 6179c3f678..289b0b7d1a 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -2000,32 +2000,34 @@ CollationIsVisible(Oid collid)
}
/*
- * get_statistics_object_oid - find a statistics object by possibly qualified
name
+ * get_object_oid_common - find an object by possibly qualified name
*
- * If not found, returns InvalidOid if missing_ok, else throws error
+ * If not found, returns InvalidOid. The argument missing_ok only applies to
+ * the namespace lookup.
*/
-Oid
-get_statistics_object_oid(List *names, bool missing_ok)
+static Oid
+get_object_oid_common(Oid classid, List *names, bool missing_ok)
{
char *schemaname;
- char *stats_name;
+ char *objectname;
Oid namespaceId;
- Oid stats_oid = InvalidOid;
+ Oid objectid = InvalidOid;
ListCell *l;
/* deconstruct the name list */
- DeconstructQualifiedName(names, &schemaname, &stats_name);
+ DeconstructQualifiedName(names, &schemaname, &objectname);
if (schemaname)
{
/* use exact schema given */
namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
if (missing_ok && !OidIsValid(namespaceId))
- stats_oid = InvalidOid;
+ objectid = InvalidOid;
else
- stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
Anum_pg_statistic_ext_oid,
-
PointerGetDatum(stats_name),
-
ObjectIdGetDatum(namespaceId));
+ objectid =
GetSysCacheOid2(get_object_catcache_name(classid),
+
get_object_attnum_oid(classid),
+
PointerGetDatum(objectname),
+
ObjectIdGetDatum(namespaceId));
}
else
{
@@ -2038,14 +2040,30 @@ get_statistics_object_oid(List *names, bool missing_ok)
if (namespaceId == myTempNamespace)
continue; /* do not look in temp
namespace */
- stats_oid = GetSysCacheOid2(STATEXTNAMENSP,
Anum_pg_statistic_ext_oid,
-
PointerGetDatum(stats_name),
-
ObjectIdGetDatum(namespaceId));
- if (OidIsValid(stats_oid))
+ objectid =
GetSysCacheOid2(get_object_catcache_name(classid),
+
get_object_attnum_oid(classid),
+
PointerGetDatum(objectname),
+
ObjectIdGetDatum(namespaceId));
+ if (OidIsValid(objectid))
break;
}
}
+ return objectid;
+}
+
+/*
+ * get_statistics_object_oid - find a statistics object by possibly qualified
name
+ *
+ * If not found, returns InvalidOid if missing_ok, else throws error
+ */
+Oid
+get_statistics_object_oid(List *names, bool missing_ok)
+{
+ Oid stats_oid;
+
+ stats_oid = get_object_oid_common(StatisticExtRelationId, names,
missing_ok);
+
if (!OidIsValid(stats_oid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -2063,45 +2081,9 @@ get_statistics_object_oid(List *names, bool missing_ok)
Oid
get_ts_parser_oid(List *names, bool missing_ok)
{
- char *schemaname;
- char *parser_name;
- Oid namespaceId;
- Oid prsoid = InvalidOid;
- ListCell *l;
-
- /* deconstruct the name list */
- DeconstructQualifiedName(names, &schemaname, &parser_name);
+ Oid prsoid;
- if (schemaname)
- {
- /* use exact schema given */
- namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
- if (missing_ok && !OidIsValid(namespaceId))
- prsoid = InvalidOid;
- else
- prsoid = GetSysCacheOid2(TSPARSERNAMENSP,
Anum_pg_ts_parser_oid,
-
PointerGetDatum(parser_name),
-
ObjectIdGetDatum(namespaceId));
- }
- else
- {
- /* search for it in search path */
- recomputeNamespacePath();
-
- foreach(l, activeSearchPath)
- {
- namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
-
- prsoid = GetSysCacheOid2(TSPARSERNAMENSP,
Anum_pg_ts_parser_oid,
-
PointerGetDatum(parser_name),
-
ObjectIdGetDatum(namespaceId));
- if (OidIsValid(prsoid))
- break;
- }
- }
+ prsoid = get_object_oid_common(TSParserRelationId, names, missing_ok);
if (!OidIsValid(prsoid) && !missing_ok)
ereport(ERROR,
@@ -2120,45 +2102,9 @@ get_ts_parser_oid(List *names, bool missing_ok)
Oid
get_ts_dict_oid(List *names, bool missing_ok)
{
- char *schemaname;
- char *dict_name;
- Oid namespaceId;
- Oid dictoid = InvalidOid;
- ListCell *l;
-
- /* deconstruct the name list */
- DeconstructQualifiedName(names, &schemaname, &dict_name);
+ Oid dictoid;
- if (schemaname)
- {
- /* use exact schema given */
- namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
- if (missing_ok && !OidIsValid(namespaceId))
- dictoid = InvalidOid;
- else
- dictoid = GetSysCacheOid2(TSDICTNAMENSP,
Anum_pg_ts_dict_oid,
-
PointerGetDatum(dict_name),
-
ObjectIdGetDatum(namespaceId));
- }
- else
- {
- /* search for it in search path */
- recomputeNamespacePath();
-
- foreach(l, activeSearchPath)
- {
- namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
-
- dictoid = GetSysCacheOid2(TSDICTNAMENSP,
Anum_pg_ts_dict_oid,
-
PointerGetDatum(dict_name),
-
ObjectIdGetDatum(namespaceId));
- if (OidIsValid(dictoid))
- break;
- }
- }
+ dictoid = get_object_oid_common(TSDictionaryRelationId, names,
missing_ok);
if (!OidIsValid(dictoid) && !missing_ok)
ereport(ERROR,
@@ -2177,45 +2123,9 @@ get_ts_dict_oid(List *names, bool missing_ok)
Oid
get_ts_template_oid(List *names, bool missing_ok)
{
- char *schemaname;
- char *template_name;
- Oid namespaceId;
Oid tmploid = InvalidOid;
- ListCell *l;
-
- /* deconstruct the name list */
- DeconstructQualifiedName(names, &schemaname, &template_name);
-
- if (schemaname)
- {
- /* use exact schema given */
- namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
- if (missing_ok && !OidIsValid(namespaceId))
- tmploid = InvalidOid;
- else
- tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP,
Anum_pg_ts_template_oid,
-
PointerGetDatum(template_name),
-
ObjectIdGetDatum(namespaceId));
- }
- else
- {
- /* search for it in search path */
- recomputeNamespacePath();
-
- foreach(l, activeSearchPath)
- {
- namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
- tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP,
Anum_pg_ts_template_oid,
-
PointerGetDatum(template_name),
-
ObjectIdGetDatum(namespaceId));
- if (OidIsValid(tmploid))
- break;
- }
- }
+ tmploid = get_object_oid_common(TSTemplateRelationId, names,
missing_ok);
if (!OidIsValid(tmploid) && !missing_ok)
ereport(ERROR,
@@ -2234,45 +2144,9 @@ get_ts_template_oid(List *names, bool missing_ok)
Oid
get_ts_config_oid(List *names, bool missing_ok)
{
- char *schemaname;
- char *config_name;
- Oid namespaceId;
Oid cfgoid = InvalidOid;
- ListCell *l;
-
- /* deconstruct the name list */
- DeconstructQualifiedName(names, &schemaname, &config_name);
- if (schemaname)
- {
- /* use exact schema given */
- namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
- if (missing_ok && !OidIsValid(namespaceId))
- cfgoid = InvalidOid;
- else
- cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP,
Anum_pg_ts_config_oid,
-
PointerGetDatum(config_name),
-
ObjectIdGetDatum(namespaceId));
- }
- else
- {
- /* search for it in search path */
- recomputeNamespacePath();
-
- foreach(l, activeSearchPath)
- {
- namespaceId = lfirst_oid(l);
-
- if (namespaceId == myTempNamespace)
- continue; /* do not look in temp
namespace */
-
- cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP,
Anum_pg_ts_config_oid,
-
PointerGetDatum(config_name),
-
ObjectIdGetDatum(namespaceId));
- if (OidIsValid(cfgoid))
- break;
- }
- }
+ cfgoid = get_object_oid_common(TSConfigRelationId, names, missing_ok);
if (!OidIsValid(cfgoid) && !missing_ok)
ereport(ERROR,
--
2.39.1