Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

Started by Peter Smithover 3 years ago12 messages
#1Peter Smith
smithpb2250@gmail.com
1 attachment(s)

During a recent review, I happened to notice that in the file
src/backend/catalog/pg_publication.c the two functions
'is_publishable_class' and 'is_publishable_relation' used to be [1]https://github.com/postgres/postgres/blame/f0b051e322d530a340e62f2ae16d99acdbcb3d05/src/backend/catalog/pg_publication.c
adjacent in the source code. This is also evident in
'is_publishable_relation' because the wording of the function comment
just refers to the prior function (e.g. "Another variant of this,
taking a Relation.") and also this just "wraps" the prior function.

It seems that sometime last year another commit [2]https://github.com/postgres/postgres/commit/5a2832465fd8984d089e8c44c094e6900d987fcd#diff-1ecc273c7808aba21749ea2718482c153cd6c4dc9d90c69124f3a7c5963b2b4a inadvertently
inserted another function ('filter_partitions') between those
aforementioned, and that means the "Another variant of this" comment
doesn't make much sense anymore.

PSA a patch just to put those original 2 functions back together
again. No code is "changed" - only moved.

------

[1]: https://github.com/postgres/postgres/blame/f0b051e322d530a340e62f2ae16d99acdbcb3d05/src/backend/catalog/pg_publication.c
[2]: https://github.com/postgres/postgres/commit/5a2832465fd8984d089e8c44c094e6900d987fcd#diff-1ecc273c7808aba21749ea2718482c153cd6c4dc9d90c69124f3a7c5963b2b4a

Kind Regards,
Peter Smith.
Fujitsu Australia

Attachments:

v1-0001-Functions-is_publishable_class-and-is_publishable.patchapplication/octet-stream; name=v1-0001-Functions-is_publishable_class-and-is_publishable.patchDownload
From 872dfb5da2e62134cb8286f3a0ce2897a141db17 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.b.smith@fujitsu.com>
Date: Fri, 29 Jul 2022 09:06:26 +1000
Subject: [PATCH v1] Functions 'is_publishable_class' and
 'is_publishable_relation' should be together.

---
 src/backend/catalog/pg_publication.c | 58 ++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index ade3bf3..7af903d 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -112,35 +112,6 @@ check_publication_add_schema(Oid schemaid)
 }
 
 /*
- * Returns if relation represented by oid and Form_pg_class entry
- * is publishable.
- *
- * Does same checks as the above, but does not need relation to be opened
- * and also does not throw errors.
- *
- * XXX  This also excludes all tables with relid < FirstNormalObjectId,
- * ie all tables created during initdb.  This mainly affects the preinstalled
- * information_schema.  IsCatalogRelationOid() only excludes tables with
- * relid < FirstUnpinnedObjectId, making that test rather redundant,
- * but really we should get rid of the FirstNormalObjectId test not
- * IsCatalogRelationOid.  We can't do so today because we don't want
- * information_schema tables to be considered publishable; but this test
- * is really inadequate for that, since the information_schema could be
- * dropped and reloaded and then it'll be considered publishable.  The best
- * long-term solution may be to add a "relispublishable" bool to pg_class,
- * and depend on that instead of OID checks.
- */
-static bool
-is_publishable_class(Oid relid, Form_pg_class reltuple)
-{
-	return (reltuple->relkind == RELKIND_RELATION ||
-			reltuple->relkind == RELKIND_PARTITIONED_TABLE) &&
-		!IsCatalogRelationOid(relid) &&
-		reltuple->relpersistence == RELPERSISTENCE_PERMANENT &&
-		relid >= FirstNormalObjectId;
-}
-
-/*
  * Filter out the partitions whose parent tables were also specified in
  * the publication.
  */
@@ -180,6 +151,35 @@ filter_partitions(List *relids)
 }
 
 /*
+ * Returns if relation represented by oid and Form_pg_class entry
+ * is publishable.
+ *
+ * Does same checks as the above, but does not need relation to be opened
+ * and also does not throw errors.
+ *
+ * XXX  This also excludes all tables with relid < FirstNormalObjectId,
+ * ie all tables created during initdb.  This mainly affects the preinstalled
+ * information_schema.  IsCatalogRelationOid() only excludes tables with
+ * relid < FirstUnpinnedObjectId, making that test rather redundant,
+ * but really we should get rid of the FirstNormalObjectId test not
+ * IsCatalogRelationOid.  We can't do so today because we don't want
+ * information_schema tables to be considered publishable; but this test
+ * is really inadequate for that, since the information_schema could be
+ * dropped and reloaded and then it'll be considered publishable.  The best
+ * long-term solution may be to add a "relispublishable" bool to pg_class,
+ * and depend on that instead of OID checks.
+ */
+static bool
+is_publishable_class(Oid relid, Form_pg_class reltuple)
+{
+	return (reltuple->relkind == RELKIND_RELATION ||
+			reltuple->relkind == RELKIND_PARTITIONED_TABLE) &&
+		!IsCatalogRelationOid(relid) &&
+		reltuple->relpersistence == RELPERSISTENCE_PERMANENT &&
+		relid >= FirstNormalObjectId;
+}
+
+/*
  * Another variant of this, taking a Relation.
  */
 bool
-- 
1.8.3.1

#2houzj.fnst@fujitsu.com
houzj.fnst@fujitsu.com
In reply to: Peter Smith (#1)
RE: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Friday, July 29, 2022 7:17 AM Peter Smith <smithpb2250@gmail.com> wrote:

During a recent review, I happened to notice that in the file
src/backend/catalog/pg_publication.c the two functions 'is_publishable_class'
and 'is_publishable_relation' used to be [1] adjacent in the source code. This is
also evident in 'is_publishable_relation' because the wording of the function
comment just refers to the prior function (e.g. "Another variant of this, taking a
Relation.") and also this just "wraps" the prior function.

It seems that sometime last year another commit [2] inadvertently inserted
another function ('filter_partitions') between those aforementioned, and that
means the "Another variant of this" comment doesn't make much sense
anymore.

Agreed.

Personally, I think it would be better to modify the comments of
is_publishable_relation and directly mention the function name it refers to
which can prevent future code to break it again.

Besides,

/*
* Returns if relation represented by oid and Form_pg_class entry
* is publishable.
*
* Does same checks as the above,

This comment was also intended to refer to the function
check_publication_add_relation(), but is invalid now because there is another
function check_publication_add_schema() inserted between them. We'd better fix
this as well.

Best regards,
Hou zj

#3Peter Smith
smithpb2250@gmail.com
In reply to: houzj.fnst@fujitsu.com (#2)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Fri, Jul 29, 2022 at 11:55 AM houzj.fnst@fujitsu.com
<houzj.fnst@fujitsu.com> wrote:

On Friday, July 29, 2022 7:17 AM Peter Smith <smithpb2250@gmail.com> wrote:

During a recent review, I happened to notice that in the file
src/backend/catalog/pg_publication.c the two functions 'is_publishable_class'
and 'is_publishable_relation' used to be [1] adjacent in the source code. This is
also evident in 'is_publishable_relation' because the wording of the function
comment just refers to the prior function (e.g. "Another variant of this, taking a
Relation.") and also this just "wraps" the prior function.

It seems that sometime last year another commit [2] inadvertently inserted
another function ('filter_partitions') between those aforementioned, and that
means the "Another variant of this" comment doesn't make much sense
anymore.

Agreed.

Personally, I think it would be better to modify the comments of
is_publishable_relation and directly mention the function name it refers to
which can prevent future code to break it again.

I'd intended only to make the minimal changes necessary to set things
right again, but your way is better.

Besides,

/*
* Returns if relation represented by oid and Form_pg_class entry
* is publishable.
*
* Does same checks as the above,

This comment was also intended to refer to the function
check_publication_add_relation(), but is invalid now because there is another
function check_publication_add_schema() inserted between them. We'd better fix
this as well.

Thanks, I'll post another patch later to address that one too.

------
Kind Regards,
Peter Smith.
Fujitsu Australia

#4Amit Kapila
amit.kapila16@gmail.com
In reply to: Peter Smith (#3)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Fri, Jul 29, 2022 at 8:26 AM Peter Smith <smithpb2250@gmail.com> wrote:

On Fri, Jul 29, 2022 at 11:55 AM houzj.fnst@fujitsu.com
<houzj.fnst@fujitsu.com> wrote:

On Friday, July 29, 2022 7:17 AM Peter Smith <smithpb2250@gmail.com> wrote:

During a recent review, I happened to notice that in the file
src/backend/catalog/pg_publication.c the two functions 'is_publishable_class'
and 'is_publishable_relation' used to be [1] adjacent in the source code. This is
also evident in 'is_publishable_relation' because the wording of the function
comment just refers to the prior function (e.g. "Another variant of this, taking a
Relation.") and also this just "wraps" the prior function.

It seems that sometime last year another commit [2] inadvertently inserted
another function ('filter_partitions') between those aforementioned, and that
means the "Another variant of this" comment doesn't make much sense
anymore.

Agreed.

Personally, I think it would be better to modify the comments of
is_publishable_relation and directly mention the function name it refers to
which can prevent future code to break it again.

I'd intended only to make the minimal changes necessary to set things
right again, but your way is better.

Yeah, Hou-San's suggestion sounds better to me as well.

Besides,

/*
* Returns if relation represented by oid and Form_pg_class entry
* is publishable.
*
* Does same checks as the above,

This comment was also intended to refer to the function
check_publication_add_relation(), but is invalid now because there is another
function check_publication_add_schema() inserted between them. We'd better fix
this as well.

+1. Here, I think it will be better to add the function name in the
comments and keep the current order as it is.

--
With Regards,
Amit Kapila.

#5Peter Smith
smithpb2250@gmail.com
In reply to: Amit Kapila (#4)
1 attachment(s)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

PSA v2 of this patch, modified as suggested.

------
Kind Regards,
Peter Smith.
Fujitsu Australia

Attachments:

v2-0001-Functions-is_publishable_class-and-is_publishable.patchapplication/octet-stream; name=v2-0001-Functions-is_publishable_class-and-is_publishable.patchDownload
From 2813ed2fd74ad283206b861794b41d558f6eca54 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.b.smith@fujitsu.com>
Date: Fri, 29 Jul 2022 14:31:39 +1000
Subject: [PATCH v2] Functions 'is_publishable_class' and
 'is_publishable_relation' should be together.

---
 src/backend/catalog/pg_publication.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index ade3bf3..e294bea 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -115,8 +115,8 @@ check_publication_add_schema(Oid schemaid)
  * Returns if relation represented by oid and Form_pg_class entry
  * is publishable.
  *
- * Does same checks as the above, but does not need relation to be opened
- * and also does not throw errors.
+ * Does same checks as check_publication_add_relation() above, but does not
+ * need relation to be opened and also does not throw errors.
  *
  * XXX  This also excludes all tables with relid < FirstNormalObjectId,
  * ie all tables created during initdb.  This mainly affects the preinstalled
@@ -141,6 +141,15 @@ is_publishable_class(Oid relid, Form_pg_class reltuple)
 }
 
 /*
+ * Another variant of is_publishable_class(), taking a Relation.
+ */
+bool
+is_publishable_relation(Relation rel)
+{
+	return is_publishable_class(RelationGetRelid(rel), rel->rd_rel);
+}
+
+/*
  * Filter out the partitions whose parent tables were also specified in
  * the publication.
  */
@@ -180,15 +189,6 @@ filter_partitions(List *relids)
 }
 
 /*
- * Another variant of this, taking a Relation.
- */
-bool
-is_publishable_relation(Relation rel)
-{
-	return is_publishable_class(RelationGetRelid(rel), rel->rd_rel);
-}
-
-/*
  * Returns true if any schema is associated with the publication, false if no
  * schema is associated with the publication.
  */
-- 
1.8.3.1

#6Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Peter Smith (#5)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On 2022-Jul-29, Peter Smith wrote:

PSA v2 of this patch, modified as suggested.

I don't object to doing this, but I think these two functions should
stay together nonetheless.

--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
Y una voz del caos me habló y me dijo
"Sonríe y sé feliz, podría ser peor".
Y sonreí. Y fui feliz.
Y fue peor.

#7Peter Smith
smithpb2250@gmail.com
In reply to: Alvaro Herrera (#6)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Fri, Jul 29, 2022 at 7:36 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

On 2022-Jul-29, Peter Smith wrote:

PSA v2 of this patch, modified as suggested.

I don't object to doing this, but I think these two functions should
stay together nonetheless.

Hmm, I think there is some confusion because different people have
mentioned multiple functions.

AFAIK, the patch *does* ensure the 2 functions (is_publishable_class
and is_publishable_relation) stay together.

If you believe there is still a problem after applying the patch
please explicitly name what function(s) you think should be moved.

------
Kind Regards,
Peter Smith.
Fujitsu Australia

#8Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Peter Smith (#7)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On 2022-Jul-29, Peter Smith wrote:

On Fri, Jul 29, 2022 at 7:36 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

I don't object to doing this, but I think these two functions should
stay together nonetheless.

If you believe there is still a problem after applying the patch
please explicitly name what function(s) you think should be moved.

Well, I checked the commit and the functions I was talking about look OK
now. However, looking again, pg_relation_is_publishable is in the wrong
place (should be right below is_publishable_relaton), and I wonder why
aren't get_publication_oid and get_publication_name in lsyscache.c.

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/

#9Amit Kapila
amit.kapila16@gmail.com
In reply to: Alvaro Herrera (#8)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Fri, Jul 29, 2022 at 3:29 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

On 2022-Jul-29, Peter Smith wrote:

On Fri, Jul 29, 2022 at 7:36 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

I don't object to doing this, but I think these two functions should
stay together nonetheless.

If you believe there is still a problem after applying the patch
please explicitly name what function(s) you think should be moved.

Well, I checked the commit and the functions I was talking about look OK
now. However, looking again, pg_relation_is_publishable is in the wrong
place (should be right below is_publishable_relaton), and I wonder why
aren't get_publication_oid and get_publication_name in lsyscache.c.

Right, both these suggestions make sense to me. Similarly, I think
functions get_subscription_name and get_subscription_oid should also
be moved to lsyscache.c.

--
With Regards,
Amit Kapila.

#10Amit Kapila
amit.kapila16@gmail.com
In reply to: Amit Kapila (#9)
1 attachment(s)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Fri, Jul 29, 2022 at 3:55 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Fri, Jul 29, 2022 at 3:29 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

Well, I checked the commit and the functions I was talking about look OK
now. However, looking again, pg_relation_is_publishable is in the wrong
place (should be right below is_publishable_relaton), and I wonder why
aren't get_publication_oid and get_publication_name in lsyscache.c.

Right, both these suggestions make sense to me. Similarly, I think
functions get_subscription_name and get_subscription_oid should also
be moved to lsyscache.c.

Attached, find a patch to address the above comments.

Note that (a) I didn't change the comment atop
pg_relation_is_publishable to refer to the actual function name
instead of 'above' as it seems it can be an SQL variant for both the
above functions. (b) didn't need to include pg_publication.h in
lsyscache.c even after moving code to that file as the code is
compiled even without that.

--
With Regards,
Amit Kapila.

Attachments:

v1-0001-Move-common-catalog-cache-access-routines-to-lsys.patchapplication/octet-stream; name=v1-0001-Move-common-catalog-cache-access-routines-to-lsys.patchDownload
From c387011bdaeb48001a2c5175e74f21e4166de6b1 Mon Sep 17 00:00:00 2001
From: Amit Kapila <akapila@postgresql.org>
Date: Sat, 30 Jul 2022 16:49:55 +0530
Subject: [PATCH v1] Move common catalog cache access routines to lsyscache.c

In passing, move pg_relation_is_publishable next to similar functions.

Suggested-by: Alvaro Herrera
---
 src/backend/catalog/pg_publication.c  |  95 ++++++++------------------------
 src/backend/catalog/pg_subscription.c |  50 -----------------
 src/backend/utils/cache/lsyscache.c   | 101 ++++++++++++++++++++++++++++++++++
 src/include/catalog/pg_publication.h  |   3 -
 src/include/catalog/pg_subscription.h |   2 -
 src/include/utils/lsyscache.h         |   4 ++
 6 files changed, 127 insertions(+), 128 deletions(-)

diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index e294bea..6af3570 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -150,6 +150,28 @@ is_publishable_relation(Relation rel)
 }
 
 /*
+ * SQL-callable variant of the above
+ *
+ * This returns null when the relation does not exist.  This is intended to be
+ * used for example in psql to avoid gratuitous errors when there are
+ * concurrent catalog changes.
+ */
+Datum
+pg_relation_is_publishable(PG_FUNCTION_ARGS)
+{
+	Oid			relid = PG_GETARG_OID(0);
+	HeapTuple	tuple;
+	bool		result;
+
+	tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (!HeapTupleIsValid(tuple))
+		PG_RETURN_NULL();
+	result = is_publishable_class(relid, (Form_pg_class) GETSTRUCT(tuple));
+	ReleaseSysCache(tuple);
+	PG_RETURN_BOOL(result);
+}
+
+/*
  * Filter out the partitions whose parent tables were also specified in
  * the publication.
  */
@@ -220,28 +242,6 @@ is_schema_publication(Oid pubid)
 }
 
 /*
- * SQL-callable variant of the above
- *
- * This returns null when the relation does not exist.  This is intended to be
- * used for example in psql to avoid gratuitous errors when there are
- * concurrent catalog changes.
- */
-Datum
-pg_relation_is_publishable(PG_FUNCTION_ARGS)
-{
-	Oid			relid = PG_GETARG_OID(0);
-	HeapTuple	tuple;
-	bool		result;
-
-	tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
-	if (!HeapTupleIsValid(tuple))
-		PG_RETURN_NULL();
-	result = is_publishable_class(relid, (Form_pg_class) GETSTRUCT(tuple));
-	ReleaseSysCache(tuple);
-	PG_RETURN_BOOL(result);
-}
-
-/*
  * Gets the relations based on the publication partition option for a specified
  * relation.
  */
@@ -1012,7 +1012,6 @@ GetPublication(Oid pubid)
 	return pub;
 }
 
-
 /*
  * Get Publication using name.
  */
@@ -1027,56 +1026,6 @@ GetPublicationByName(const char *pubname, bool missing_ok)
 }
 
 /*
- * get_publication_oid - given a publication name, look up the OID
- *
- * If missing_ok is false, throw an error if name not found.  If true, just
- * return InvalidOid.
- */
-Oid
-get_publication_oid(const char *pubname, bool missing_ok)
-{
-	Oid			oid;
-
-	oid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
-						  CStringGetDatum(pubname));
-	if (!OidIsValid(oid) && !missing_ok)
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("publication \"%s\" does not exist", pubname)));
-	return oid;
-}
-
-/*
- * get_publication_name - given a publication Oid, look up the name
- *
- * If missing_ok is false, throw an error if name not found.  If true, just
- * return NULL.
- */
-char *
-get_publication_name(Oid pubid, bool missing_ok)
-{
-	HeapTuple	tup;
-	char	   *pubname;
-	Form_pg_publication pubform;
-
-	tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
-
-	if (!HeapTupleIsValid(tup))
-	{
-		if (!missing_ok)
-			elog(ERROR, "cache lookup failed for publication %u", pubid);
-		return NULL;
-	}
-
-	pubform = (Form_pg_publication) GETSTRUCT(tup);
-	pubname = pstrdup(NameStr(pubform->pubname));
-
-	ReleaseSysCache(tup);
-
-	return pubname;
-}
-
-/*
  * Returns information of tables in a publication.
  */
 Datum
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index c7d2537..a506fc3 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -206,56 +206,6 @@ DisableSubscription(Oid subid)
 }
 
 /*
- * get_subscription_oid - given a subscription name, look up the OID
- *
- * If missing_ok is false, throw an error if name not found.  If true, just
- * return InvalidOid.
- */
-Oid
-get_subscription_oid(const char *subname, bool missing_ok)
-{
-	Oid			oid;
-
-	oid = GetSysCacheOid2(SUBSCRIPTIONNAME, Anum_pg_subscription_oid,
-						  MyDatabaseId, CStringGetDatum(subname));
-	if (!OidIsValid(oid) && !missing_ok)
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("subscription \"%s\" does not exist", subname)));
-	return oid;
-}
-
-/*
- * get_subscription_name - given a subscription OID, look up the name
- *
- * If missing_ok is false, throw an error if name not found.  If true, just
- * return NULL.
- */
-char *
-get_subscription_name(Oid subid, bool missing_ok)
-{
-	HeapTuple	tup;
-	char	   *subname;
-	Form_pg_subscription subform;
-
-	tup = SearchSysCache1(SUBSCRIPTIONOID, ObjectIdGetDatum(subid));
-
-	if (!HeapTupleIsValid(tup))
-	{
-		if (!missing_ok)
-			elog(ERROR, "cache lookup failed for subscription %u", subid);
-		return NULL;
-	}
-
-	subform = (Form_pg_subscription) GETSTRUCT(tup);
-	subname = pstrdup(NameStr(subform->subname));
-
-	ReleaseSysCache(tup);
-
-	return subname;
-}
-
-/*
  * Convert text array to list of strings.
  *
  * Note: the resulting list of strings is pallocated here.
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 1b7e11b..9daa885 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -33,6 +33,7 @@
 #include "catalog/pg_proc.h"
 #include "catalog/pg_range.h"
 #include "catalog/pg_statistic.h"
+#include "catalog/pg_subscription.h"
 #include "catalog/pg_transform.h"
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
@@ -3578,3 +3579,103 @@ get_index_isclustered(Oid index_oid)
 
 	return isclustered;
 }
+
+/*
+ * get_publication_oid - given a publication name, look up the OID
+ *
+ * If missing_ok is false, throw an error if name not found.  If true, just
+ * return InvalidOid.
+ */
+Oid
+get_publication_oid(const char *pubname, bool missing_ok)
+{
+	Oid			oid;
+
+	oid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
+						  CStringGetDatum(pubname));
+	if (!OidIsValid(oid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("publication \"%s\" does not exist", pubname)));
+	return oid;
+}
+
+/*
+ * get_publication_name - given a publication Oid, look up the name
+ *
+ * If missing_ok is false, throw an error if name not found.  If true, just
+ * return NULL.
+ */
+char *
+get_publication_name(Oid pubid, bool missing_ok)
+{
+	HeapTuple	tup;
+	char	   *pubname;
+	Form_pg_publication pubform;
+
+	tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
+
+	if (!HeapTupleIsValid(tup))
+	{
+		if (!missing_ok)
+			elog(ERROR, "cache lookup failed for publication %u", pubid);
+		return NULL;
+	}
+
+	pubform = (Form_pg_publication) GETSTRUCT(tup);
+	pubname = pstrdup(NameStr(pubform->pubname));
+
+	ReleaseSysCache(tup);
+
+	return pubname;
+}
+
+/*
+ * get_subscription_oid - given a subscription name, look up the OID
+ *
+ * If missing_ok is false, throw an error if name not found.  If true, just
+ * return InvalidOid.
+ */
+Oid
+get_subscription_oid(const char *subname, bool missing_ok)
+{
+	Oid			oid;
+
+	oid = GetSysCacheOid2(SUBSCRIPTIONNAME, Anum_pg_subscription_oid,
+						  MyDatabaseId, CStringGetDatum(subname));
+	if (!OidIsValid(oid) && !missing_ok)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_OBJECT),
+				 errmsg("subscription \"%s\" does not exist", subname)));
+	return oid;
+}
+
+/*
+ * get_subscription_name - given a subscription OID, look up the name
+ *
+ * If missing_ok is false, throw an error if name not found.  If true, just
+ * return NULL.
+ */
+char *
+get_subscription_name(Oid subid, bool missing_ok)
+{
+	HeapTuple	tup;
+	char	   *subname;
+	Form_pg_subscription subform;
+
+	tup = SearchSysCache1(SUBSCRIPTIONOID, ObjectIdGetDatum(subid));
+
+	if (!HeapTupleIsValid(tup))
+	{
+		if (!missing_ok)
+			elog(ERROR, "cache lookup failed for subscription %u", subid);
+		return NULL;
+	}
+
+	subform = (Form_pg_subscription) GETSTRUCT(tup);
+	subname = pstrdup(NameStr(subform->subname));
+
+	ReleaseSysCache(tup);
+
+	return subname;
+}
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index 48205ba..c298327 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -155,7 +155,4 @@ extern ObjectAddress publication_add_schema(Oid pubid, Oid schemaid,
 extern Bitmapset *pub_collist_to_bitmapset(Bitmapset *columns, Datum pubcols,
 										   MemoryContext mcxt);
 
-extern Oid	get_publication_oid(const char *pubname, bool missing_ok);
-extern char *get_publication_name(Oid pubid, bool missing_ok);
-
 #endif							/* PG_PUBLICATION_H */
diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h
index c9a3026..7b98714 100644
--- a/src/include/catalog/pg_subscription.h
+++ b/src/include/catalog/pg_subscription.h
@@ -140,8 +140,6 @@ typedef struct Subscription
 extern Subscription *GetSubscription(Oid subid, bool missing_ok);
 extern void FreeSubscription(Subscription *sub);
 extern void DisableSubscription(Oid subid);
-extern Oid	get_subscription_oid(const char *subname, bool missing_ok);
-extern char *get_subscription_name(Oid subid, bool missing_ok);
 
 extern int	CountDBSubscriptions(Oid dbid);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b8dd27d..50f0288 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -198,6 +198,10 @@ extern Oid	get_index_column_opclass(Oid index_oid, int attno);
 extern bool get_index_isreplident(Oid index_oid);
 extern bool get_index_isvalid(Oid index_oid);
 extern bool get_index_isclustered(Oid index_oid);
+extern Oid	get_publication_oid(const char *pubname, bool missing_ok);
+extern char *get_publication_name(Oid pubid, bool missing_ok);
+extern Oid	get_subscription_oid(const char *subname, bool missing_ok);
+extern char *get_subscription_name(Oid subid, bool missing_ok);
 
 #define type_is_array(typid)  (get_element_type(typid) != InvalidOid)
 /* type_is_array_domain accepts both plain arrays and domains over arrays */
-- 
1.8.3.1

#11houzj.fnst@fujitsu.com
houzj.fnst@fujitsu.com
In reply to: Amit Kapila (#10)
RE: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Saturday, July 30, 2022 7:25 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Fri, Jul 29, 2022 at 3:55 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Fri, Jul 29, 2022 at 3:29 PM Alvaro Herrera <alvherre@alvh.no-ip.org>

wrote:

Well, I checked the commit and the functions I was talking about
look OK now. However, looking again, pg_relation_is_publishable is
in the wrong place (should be right below is_publishable_relaton),
and I wonder why aren't get_publication_oid and get_publication_name in

lsyscache.c.

Right, both these suggestions make sense to me. Similarly, I think
functions get_subscription_name and get_subscription_oid should also
be moved to lsyscache.c.

Attached, find a patch to address the above comments.

Note that (a) I didn't change the comment atop pg_relation_is_publishable to
refer to the actual function name instead of 'above' as it seems it can be an SQL
variant for both the above functions. (b) didn't need to include pg_publication.h
in lsyscache.c even after moving code to that file as the code is compiled even
without that.

The patch LGTM. I also ran the headerscheck and didn't find any problem.

Best regards,
Hou Zhijie

#12Amit Kapila
amit.kapila16@gmail.com
In reply to: houzj.fnst@fujitsu.com (#11)
Re: Functions 'is_publishable_class' and 'is_publishable_relation' should stay together.

On Sat, Jul 30, 2022 at 6:59 PM houzj.fnst@fujitsu.com
<houzj.fnst@fujitsu.com> wrote:

On Saturday, July 30, 2022 7:25 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Fri, Jul 29, 2022 at 3:55 PM Amit Kapila <amit.kapila16@gmail.com> wrote:

On Fri, Jul 29, 2022 at 3:29 PM Alvaro Herrera <alvherre@alvh.no-ip.org>

wrote:

Well, I checked the commit and the functions I was talking about
look OK now. However, looking again, pg_relation_is_publishable is
in the wrong place (should be right below is_publishable_relaton),
and I wonder why aren't get_publication_oid and get_publication_name in

lsyscache.c.

Right, both these suggestions make sense to me. Similarly, I think
functions get_subscription_name and get_subscription_oid should also
be moved to lsyscache.c.

Attached, find a patch to address the above comments.

Note that (a) I didn't change the comment atop pg_relation_is_publishable to
refer to the actual function name instead of 'above' as it seems it can be an SQL
variant for both the above functions. (b) didn't need to include pg_publication.h
in lsyscache.c even after moving code to that file as the code is compiled even
without that.

The patch LGTM. I also ran the headerscheck and didn't find any problem.

Thanks, I have pushed the patch.

--
With Regards,
Amit Kapila.