object_classes array is broken, again

Started by Robert Haasover 10 years ago12 messages
#1Robert Haas
robertmhaas@gmail.com

The transforms patch seems to have forgotten to add
TransformRelationId to object_classes[], much like the RLS patch
forgot to add PolicyRelationId in the same place.

Fixing this is easy, but ISTM that we need to insert some sort of a
guard to prevent people from continuing to forget this, because it's
apparently quite easy to do. Perhaps add_object_address should
Assert(OidIsValid(object_classes[oclass])), plus a (static?) assert
someplace checking that OidIsValid(object_classes[MAX_OCLASS - 1])?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#2Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Robert Haas (#1)
1 attachment(s)
Re: object_classes array is broken, again

On 6/24/15 2:11 PM, Robert Haas wrote:

Fixing this is easy, but ISTM that we need to insert some sort of a
guard to prevent people from continuing to forget this, because it's
apparently quite easy to do. Perhaps add_object_address should
Assert(OidIsValid(object_classes[oclass])), plus a (static?) assert
someplace checking that OidIsValid(object_classes[MAX_OCLASS - 1])?

I tried doing this and I'm getting a "static_assert expression is not an
integral constant expression" error, even when I reduce it to a simple
constant comparison. Maybe I'm just doing something dumb...

If I replace the StaticAssert with
Assert(OidIsValid(object_classes[MAX_OCLASS - 1])) it works find and
initdb will fail if that assert trips.

I've attached the broken StaticAssert version. Also added a warning
comment to the enum.
--
Jim Nasby, Data Architect, Blue Treble Consulting, Austin TX
Data in Trouble? Get it in Treble! http://BlueTreble.com

Attachments:

oclass_broken.patchtext/plain; charset=UTF-8; name=oclass_broken.patch; x-mac-creator=0; x-mac-type=0Download
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index c1212e9..7adc216 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -2037,6 +2037,15 @@ add_object_address(ObjectClass oclass, Oid objectId, int32 subId,
 {
 	ObjectAddress *item;
 
+	/*
+	 * Ensure object_classes is properly sized. Can't use OidIsValid here
+	 * because it's not marked as static (nor should it be).
+	 */
+	StaticAssertStmt(object_classes[MAX_OCLASS - 1] != 0,
+			"last OID in object_classes[] is invalid (did you forget to add a new entry to it?)");
+
+	Assert(OidIsValid(object_classes[oclass]));
+
 	/* enlarge array if needed */
 	if (addrs->numrefs >= addrs->maxrefs)
 	{
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 5da18c2..515417d 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -149,6 +149,8 @@ typedef enum ObjectClass
 	OCLASS_EVENT_TRIGGER,		/* pg_event_trigger */
 	OCLASS_POLICY,				/* pg_policy */
 	OCLASS_TRANSFORM,			/* pg_transform */
+	
+	/* New classes need to be added to object_classes[] too. */
 	MAX_OCLASS					/* MUST BE LAST */
 } ObjectClass;
 
#3Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Robert Haas (#1)
1 attachment(s)
Re: object_classes array is broken, again

Robert Haas wrote:

The transforms patch seems to have forgotten to add
TransformRelationId to object_classes[], much like the RLS patch
forgot to add PolicyRelationId in the same place.

Fixing this is easy, but ISTM that we need to insert some sort of a
guard to prevent people from continuing to forget this, because it's
apparently quite easy to do. Perhaps add_object_address should
Assert(OidIsValid(object_classes[oclass])),

The problem is that there aren't enough callers of add_object_address:
there are many indexes of that array that aren't ever accessed and so
it's not obvious when the array is broken. If we were to put
OCLASS_CLASS at the end instead of at the beginning, that would fix the
problem by making it immediately obvious when things get broken this
way, because the value used in the most common case would shift around
every time we add another value. (Of course, we'd have to instruct
people to not add new members after the pg_class entry.)

I just tried this, and it's a bit nasty: while it does causes the tests
to fail, it's not at all obvious that there's a connection between the
failure and object_classes[]. I think we can solve that by adding a
comment to ObjectClass. Here's the first hunk in the large regression
failure:

*** /pgsql/source/master/src/test/regress/expected/triggers.out 2015-05-22 20:09:28.936186873 +0200
--- /home/alvherre/Code/pgsql/build/master/src/test/regress/results/triggers.out    2015-07-18 17:26:13.
664764070 +0200
***************
*** 1429,1437 ****
  (4 rows)
  DROP TABLE city_table CASCADE;
- NOTICE:  drop cascades to 2 other objects
- DETAIL:  drop cascades to view city_view
- drop cascades to view european_city_view
  DROP TABLE country_table;
  -- Test pg_trigger_depth()
  create table depth_a (id int not null primary key);
--- 1429,1434 ----

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

objclass.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index c1212e9..0107c53 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -127,7 +127,6 @@ typedef struct
  * See also getObjectClass().
  */
 static const Oid object_classes[MAX_OCLASS] = {
-	RelationRelationId,			/* OCLASS_CLASS */
 	ProcedureRelationId,		/* OCLASS_PROC */
 	TypeRelationId,				/* OCLASS_TYPE */
 	CastRelationId,				/* OCLASS_CAST */
@@ -158,7 +157,9 @@ static const Oid object_classes[MAX_OCLASS] = {
 	DefaultAclRelationId,		/* OCLASS_DEFACL */
 	ExtensionRelationId,		/* OCLASS_EXTENSION */
 	EventTriggerRelationId,		/* OCLASS_EVENT_TRIGGER */
-	PolicyRelationId			/* OCLASS_POLICY */
+	PolicyRelationId,			/* OCLASS_POLICY */
+	TransformRelationId,		/* OCLASS_POLICY */
+	RelationRelationId			/* OCLASS_CLASS */
 };
 
 
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 5da18c2..6f4802d 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -112,11 +112,10 @@ typedef struct ObjectAddresses ObjectAddresses;
 
 /*
  * This enum covers all system catalogs whose OIDs can appear in
- * pg_depend.classId or pg_shdepend.classId.
+ * pg_depend.classId or pg_shdepend.classId.  See also object_classes[].
  */
 typedef enum ObjectClass
 {
-	OCLASS_CLASS,				/* pg_class */
 	OCLASS_PROC,				/* pg_proc */
 	OCLASS_TYPE,				/* pg_type */
 	OCLASS_CAST,				/* pg_cast */
@@ -149,6 +148,11 @@ typedef enum ObjectClass
 	OCLASS_EVENT_TRIGGER,		/* pg_event_trigger */
 	OCLASS_POLICY,				/* pg_policy */
 	OCLASS_TRANSFORM,			/* pg_transform */
+	/*
+	 * Keep this previous-to-last, see
+	 * https://www.postgresql.org/message-id/
+	 */
+	OCLASS_CLASS,				/* pg_class */
 	MAX_OCLASS					/* MUST BE LAST */
 } ObjectClass;
 
#4Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#3)
Re: [HACKERS] object_classes array is broken, again

Any opinions on this idea? I don't like it all that much, but it's
plenty effective.

Alvaro Herrera wrote:

The problem is that there aren't enough callers of add_object_address:
there are many indexes of that array that aren't ever accessed and so
it's not obvious when the array is broken. If we were to put
OCLASS_CLASS at the end instead of at the beginning, that would fix the
problem by making it immediately obvious when things get broken this
way, because the value used in the most common case would shift around
every time we add another value. (Of course, we'd have to instruct
people to not add new members after the pg_class entry.)

diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index c1212e9..0107c53 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -127,7 +127,6 @@ typedef struct
* See also getObjectClass().
*/
static const Oid object_classes[MAX_OCLASS] = {
-	RelationRelationId,			/* OCLASS_CLASS */
ProcedureRelationId,		/* OCLASS_PROC */
TypeRelationId,				/* OCLASS_TYPE */
CastRelationId,				/* OCLASS_CAST */
@@ -158,7 +157,9 @@ static const Oid object_classes[MAX_OCLASS] = {
DefaultAclRelationId,		/* OCLASS_DEFACL */
ExtensionRelationId,		/* OCLASS_EXTENSION */
EventTriggerRelationId,		/* OCLASS_EVENT_TRIGGER */
-	PolicyRelationId			/* OCLASS_POLICY */
+	PolicyRelationId,			/* OCLASS_POLICY */
+	TransformRelationId,		/* OCLASS_POLICY */
+	RelationRelationId			/* OCLASS_CLASS */
};
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 5da18c2..6f4802d 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -112,11 +112,10 @@ typedef struct ObjectAddresses ObjectAddresses;
/*
* This enum covers all system catalogs whose OIDs can appear in
- * pg_depend.classId or pg_shdepend.classId.
+ * pg_depend.classId or pg_shdepend.classId.  See also object_classes[].
*/
typedef enum ObjectClass
{
-	OCLASS_CLASS,				/* pg_class */
OCLASS_PROC,				/* pg_proc */
OCLASS_TYPE,				/* pg_type */
OCLASS_CAST,				/* pg_cast */
@@ -149,6 +148,11 @@ typedef enum ObjectClass
OCLASS_EVENT_TRIGGER,		/* pg_event_trigger */
OCLASS_POLICY,				/* pg_policy */
OCLASS_TRANSFORM,			/* pg_transform */
+	/*
+	 * Keep this previous-to-last, see
+	 * https://www.postgresql.org/message-id/
+	 */
+	OCLASS_CLASS,				/* pg_class */
MAX_OCLASS					/* MUST BE LAST */
} ObjectClass;

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#4)
Re: [HACKERS] object_classes array is broken, again

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

Any opinions on this idea? I don't like it all that much, but it's
plenty effective.

I don't like it much either.

What about adding StaticAsserts that lengthof() the relevant constant
arrays is equal to MAX_OCLASS? (Or other similar ways of checking
that they have the right number of entries.)

regards, tom lane

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#6Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#5)
1 attachment(s)
Re: [BUGS] object_classes array is broken, again

Tom Lane wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

Any opinions on this idea? I don't like it all that much, but it's
plenty effective.

I don't like it much either.

What about adding StaticAsserts that lengthof() the relevant constant
arrays is equal to MAX_OCLASS? (Or other similar ways of checking
that they have the right number of entries.)

Well, the array itself is declared like this:
static const Oid object_classes[MAX_OCLASS] = {
so testing lengthof() of it is useless because it's a constant and the
assertion always holds. If it were declared like this instead:
static const Oid object_classes[] = {
then we could use lengthof().

I don't see any drawwbacks to that.

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

objclass-2.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index c1212e9..de2e2f2 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -126,7 +126,7 @@ typedef struct
  * This constant table maps ObjectClasses to the corresponding catalog OIDs.
  * See also getObjectClass().
  */
-static const Oid object_classes[MAX_OCLASS] = {
+static const Oid object_classes[] = {
 	RelationRelationId,			/* OCLASS_CLASS */
 	ProcedureRelationId,		/* OCLASS_PROC */
 	TypeRelationId,				/* OCLASS_TYPE */
@@ -158,7 +158,8 @@ static const Oid object_classes[MAX_OCLASS] = {
 	DefaultAclRelationId,		/* OCLASS_DEFACL */
 	ExtensionRelationId,		/* OCLASS_EXTENSION */
 	EventTriggerRelationId,		/* OCLASS_EVENT_TRIGGER */
-	PolicyRelationId			/* OCLASS_POLICY */
+	PolicyRelationId,			/* OCLASS_POLICY */
+	TransformRelationId			/* OCLASS_TRANSFORM */
 };
 
 
@@ -2037,6 +2038,12 @@ add_object_address(ObjectClass oclass, Oid objectId, int32 subId,
 {
 	ObjectAddress *item;
 
+	/*
+	 * Make sure object_classes is kept up to date with the ObjectClass enum.
+	 */
+	StaticAssertStmt((lengthof(object_classes) == MAX_OCLASS),
+					 "object_classes[] must cover all ObjectClasses");
+
 	/* enlarge array if needed */
 	if (addrs->numrefs >= addrs->maxrefs)
 	{
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 5da18c2..138788e 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -112,7 +112,7 @@ typedef struct ObjectAddresses ObjectAddresses;
 
 /*
  * This enum covers all system catalogs whose OIDs can appear in
- * pg_depend.classId or pg_shdepend.classId.
+ * pg_depend.classId or pg_shdepend.classId.  See object_classes[].
  */
 typedef enum ObjectClass
 {
#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#6)
Re: [HACKERS] object_classes array is broken, again

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

Tom Lane wrote:

What about adding StaticAsserts that lengthof() the relevant constant
arrays is equal to MAX_OCLASS? (Or other similar ways of checking
that they have the right number of entries.)

Well, the array itself is declared like this:
static const Oid object_classes[MAX_OCLASS] = {
so testing lengthof() of it is useless because it's a constant and the
assertion always holds. If it were declared like this instead:
static const Oid object_classes[] = {
then we could use lengthof().

Ah. I think the point of using MAX_OCLASS there was to get a warning
if the array was too short, but evidently it doesn't work like that.

I don't see any drawwbacks to that.

+1 to this patch, in fact I think we could remove MAX_OCLASS altogether
which would be very nice for switch purposes.

Are there any other arrays that need such tests?

regards, tom lane

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#7)
Re: [BUGS] object_classes array is broken, again

I wrote:

+1 to this patch, in fact I think we could remove MAX_OCLASS altogether
which would be very nice for switch purposes.

Oh, wait, I forgot that the patch itself introduces another reference to
MAX_OCLASS. I wonder though if we should get rid of that as an enum value
in favor of #define'ing a LAST_OCLASS macro referencing the last enum
item, or some other trick like that. It's certainly inconvenient in
event_trigger.c to have a phony member of the enum.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#8)
Re: [BUGS] object_classes array is broken, again

Tom Lane wrote:

I wrote:

+1 to this patch, in fact I think we could remove MAX_OCLASS altogether
which would be very nice for switch purposes.

Oh, wait, I forgot that the patch itself introduces another reference to
MAX_OCLASS. I wonder though if we should get rid of that as an enum value
in favor of #define'ing a LAST_OCLASS macro referencing the last enum
item, or some other trick like that. It's certainly inconvenient in
event_trigger.c to have a phony member of the enum.

Yeah, that works well enough. Pushed that way.

Are there any other arrays that need such tests?

I looked around with this:

git grep 'const.*\[.*[^][0-9].*\].*=.*{'

and found one suspicious-looking use of MAX_ACL_KIND which we could
perhaps define in a way equivalent to what we've done here. We also
have RM_MAX_ID in a couple of arrays but that looks safe because both
the values and the arrays are auto-generated.

We also have MAX_TIME_PRECISION, MAX_TIMESTAMP_PRECISION,
MAX_INTERVAL_PRECISION, MAXDATEFIELDS, KeyWord_INDEX_SIZE, but these
don't look likely to actually cause any trouble.

(There are many arrays sized to numerical constants, but there are about
5000 of those and I'm not in a hurry to verify how they are used.)

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Jaimin Pan
jaimin.pan@gmail.com
In reply to: Alvaro Herrera (#9)
1 attachment(s)
Re: [HACKERS] object_classes array is broken, again

Hi all,

How about this patch. I believe it will never missing someone and be
detected while compiling.

2015-07-21 19:38 GMT+08:00 Alvaro Herrera <alvherre@2ndquadrant.com>:

Show quoted text

Tom Lane wrote:

I wrote:

+1 to this patch, in fact I think we could remove MAX_OCLASS altogether
which would be very nice for switch purposes.

Oh, wait, I forgot that the patch itself introduces another reference to
MAX_OCLASS. I wonder though if we should get rid of that as an enum

value

in favor of #define'ing a LAST_OCLASS macro referencing the last enum
item, or some other trick like that. It's certainly inconvenient in
event_trigger.c to have a phony member of the enum.

Yeah, that works well enough. Pushed that way.

Are there any other arrays that need such tests?

I looked around with this:

git grep 'const.*\[.*[^][0-9].*\].*=.*{'

and found one suspicious-looking use of MAX_ACL_KIND which we could
perhaps define in a way equivalent to what we've done here. We also
have RM_MAX_ID in a couple of arrays but that looks safe because both
the values and the arrays are auto-generated.

We also have MAX_TIME_PRECISION, MAX_TIMESTAMP_PRECISION,
MAX_INTERVAL_PRECISION, MAXDATEFIELDS, KeyWord_INDEX_SIZE, but these
don't look likely to actually cause any trouble.

(There are many arrays sized to numerical constants, but there are about
5000 of those and I'm not in a hurry to verify how they are used.)

--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Attachments:

fix.patchapplication/octet-stream; name=fix.patchDownload
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 5d7c441..2d74f25 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -127,39 +127,9 @@ typedef struct
  * See also getObjectClass().
  */
 static const Oid object_classes[] = {
-	RelationRelationId,			/* OCLASS_CLASS */
-	ProcedureRelationId,		/* OCLASS_PROC */
-	TypeRelationId,				/* OCLASS_TYPE */
-	CastRelationId,				/* OCLASS_CAST */
-	CollationRelationId,		/* OCLASS_COLLATION */
-	ConstraintRelationId,		/* OCLASS_CONSTRAINT */
-	ConversionRelationId,		/* OCLASS_CONVERSION */
-	AttrDefaultRelationId,		/* OCLASS_DEFAULT */
-	LanguageRelationId,			/* OCLASS_LANGUAGE */
-	LargeObjectRelationId,		/* OCLASS_LARGEOBJECT */
-	OperatorRelationId,			/* OCLASS_OPERATOR */
-	OperatorClassRelationId,	/* OCLASS_OPCLASS */
-	OperatorFamilyRelationId,	/* OCLASS_OPFAMILY */
-	AccessMethodOperatorRelationId,		/* OCLASS_AMOP */
-	AccessMethodProcedureRelationId,	/* OCLASS_AMPROC */
-	RewriteRelationId,			/* OCLASS_REWRITE */
-	TriggerRelationId,			/* OCLASS_TRIGGER */
-	NamespaceRelationId,		/* OCLASS_SCHEMA */
-	TSParserRelationId,			/* OCLASS_TSPARSER */
-	TSDictionaryRelationId,		/* OCLASS_TSDICT */
-	TSTemplateRelationId,		/* OCLASS_TSTEMPLATE */
-	TSConfigRelationId,			/* OCLASS_TSCONFIG */
-	AuthIdRelationId,			/* OCLASS_ROLE */
-	DatabaseRelationId,			/* OCLASS_DATABASE */
-	TableSpaceRelationId,		/* OCLASS_TBLSPACE */
-	ForeignDataWrapperRelationId,		/* OCLASS_FDW */
-	ForeignServerRelationId,	/* OCLASS_FOREIGN_SERVER */
-	UserMappingRelationId,		/* OCLASS_USER_MAPPING */
-	DefaultAclRelationId,		/* OCLASS_DEFACL */
-	ExtensionRelationId,		/* OCLASS_EXTENSION */
-	EventTriggerRelationId,		/* OCLASS_EVENT_TRIGGER */
-	PolicyRelationId,			/* OCLASS_POLICY */
-	TransformRelationId			/* OCLASS_TRANSFORM */
+#define PG_DEPMAP(symname,relid) relid,
+#include "catalog/deplist.h"
+#undef PG_DEPMAP
 };
 
 
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index aa3f3d9..fd1f420 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -116,39 +116,9 @@ typedef struct ObjectAddresses ObjectAddresses;
  */
 typedef enum ObjectClass
 {
-	OCLASS_CLASS,				/* pg_class */
-	OCLASS_PROC,				/* pg_proc */
-	OCLASS_TYPE,				/* pg_type */
-	OCLASS_CAST,				/* pg_cast */
-	OCLASS_COLLATION,			/* pg_collation */
-	OCLASS_CONSTRAINT,			/* pg_constraint */
-	OCLASS_CONVERSION,			/* pg_conversion */
-	OCLASS_DEFAULT,				/* pg_attrdef */
-	OCLASS_LANGUAGE,			/* pg_language */
-	OCLASS_LARGEOBJECT,			/* pg_largeobject */
-	OCLASS_OPERATOR,			/* pg_operator */
-	OCLASS_OPCLASS,				/* pg_opclass */
-	OCLASS_OPFAMILY,			/* pg_opfamily */
-	OCLASS_AMOP,				/* pg_amop */
-	OCLASS_AMPROC,				/* pg_amproc */
-	OCLASS_REWRITE,				/* pg_rewrite */
-	OCLASS_TRIGGER,				/* pg_trigger */
-	OCLASS_SCHEMA,				/* pg_namespace */
-	OCLASS_TSPARSER,			/* pg_ts_parser */
-	OCLASS_TSDICT,				/* pg_ts_dict */
-	OCLASS_TSTEMPLATE,			/* pg_ts_template */
-	OCLASS_TSCONFIG,			/* pg_ts_config */
-	OCLASS_ROLE,				/* pg_authid */
-	OCLASS_DATABASE,			/* pg_database */
-	OCLASS_TBLSPACE,			/* pg_tablespace */
-	OCLASS_FDW,					/* pg_foreign_data_wrapper */
-	OCLASS_FOREIGN_SERVER,		/* pg_foreign_server */
-	OCLASS_USER_MAPPING,		/* pg_user_mapping */
-	OCLASS_DEFACL,				/* pg_default_acl */
-	OCLASS_EXTENSION,			/* pg_extension */
-	OCLASS_EVENT_TRIGGER,		/* pg_event_trigger */
-	OCLASS_POLICY,				/* pg_policy */
-	OCLASS_TRANSFORM			/* pg_transform */
+#define PG_DEPMAP(symname,relid) symname,
+#include "catalog/deplist.h"
+#undef PG_DEPMAP
 } ObjectClass;
 
 #define LAST_OCLASS		OCLASS_TRANSFORM
diff --git a/src/include/catalog/deplist.h b/src/include/catalog/deplist.h
new file mode 100644
index 0000000..ab6cc2d
--- /dev/null
+++ b/src/include/catalog/deplist.h
@@ -0,0 +1,54 @@
+/*---------------------------------------------------------------------------
+ * deplist.h
+ *
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/catalog/deplist.h
+ *---------------------------------------------------------------------------
+ */
+
+/* there is deliberately not an #ifndef DEPLIST_H here */
+
+/*
+ * List of dependency entries.  Note that order of entries defines the
+ * numerical values of each ID
+ *
+ */
+
+/* symbol name, textual name, redo, desc, identify, startup, cleanup */
+PG_DEPMAP(OCLASS_CLASS,			RelationRelationId)
+PG_DEPMAP(OCLASS_PROC,			ProcedureRelationId)
+PG_DEPMAP(OCLASS_TYPE,			TypeRelationId)
+PG_DEPMAP(OCLASS_CAST,			CastRelationId)
+PG_DEPMAP(OCLASS_COLLATION,		CollationRelationId)
+PG_DEPMAP(OCLASS_CONSTRAINT,	ConstraintRelationId)
+PG_DEPMAP(OCLASS_CONVERSION,	ConversionRelationId)
+PG_DEPMAP(OCLASS_DEFAULT,		AttrDefaultRelationId)
+PG_DEPMAP(OCLASS_LANGUAGE,		LanguageRelationId)
+PG_DEPMAP(OCLASS_LARGEOBJECT,	LargeObjectRelationId)
+PG_DEPMAP(OCLASS_OPERATOR,		OperatorRelationId)
+PG_DEPMAP(OCLASS_OPCLASS,		OperatorClassRelationId)
+PG_DEPMAP(OCLASS_OPFAMILY,		OperatorFamilyRelationId)
+PG_DEPMAP(OCLASS_AMOP,			AccessMethodOperatorRelationId)
+PG_DEPMAP(OCLASS_AMPROC,		AccessMethodProcedureRelationId)
+PG_DEPMAP(OCLASS_REWRITE,		RewriteRelationId)
+PG_DEPMAP(OCLASS_TRIGGER,		TriggerRelationId)
+PG_DEPMAP(OCLASS_SCHEMA,		NamespaceRelationId)
+PG_DEPMAP(OCLASS_TSPARSER,		TSParserRelationId)
+PG_DEPMAP(OCLASS_TSDICT,		TSDictionaryRelationId)
+PG_DEPMAP(OCLASS_TSTEMPLATE,	TSTemplateRelationId)
+PG_DEPMAP(OCLASS_TSCONFIG,		TSConfigRelationId)
+PG_DEPMAP(OCLASS_ROLE,			AuthIdRelationId)
+PG_DEPMAP(OCLASS_DATABASE,		DatabaseRelationId)
+PG_DEPMAP(OCLASS_TBLSPACE,		TableSpaceRelationId)
+PG_DEPMAP(OCLASS_FDW,			ForeignDataWrapperRelationId)
+PG_DEPMAP(OCLASS_FOREIGN_SERVER,ForeignServerRelationId)
+PG_DEPMAP(OCLASS_USER_MAPPING,	UserMappingRelationId)
+PG_DEPMAP(OCLASS_DEFACL,		DefaultAclRelationId)
+PG_DEPMAP(OCLASS_EXTENSION,		ExtensionRelationId)
+PG_DEPMAP(OCLASS_EVENT_TRIGGER,	EventTriggerRelationId)
+PG_DEPMAP(OCLASS_POLICY,		PolicyRelationId)
+PG_DEPMAP(OCLASS_TRANSFORM,		TransformRelationId)
+
#11Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Jaimin Pan (#10)
Re: [HACKERS] object_classes array is broken, again

Jaimin Pan wrote:

Hi all,

How about this patch. I believe it will never missing someone and be
detected while compiling.

Hmm, yeah this looks like something that's worth considering going
forward. I can't think of any reason not to do this. Perhaps we can
write getObjectClass using this, too.

The new file has a wrong comment above the list, copy-pasted from
rmgrlist.h.

I've always wondered about unifying OCLASS with OBJECT, but that's
probably a completely independent topic.

--
�lvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#12Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Alvaro Herrera (#11)
Re: [BUGS] object_classes array is broken, again

Alvaro Herrera wrote:

Jaimin Pan wrote:

Hi all,

How about this patch. I believe it will never missing someone and be
detected while compiling.

Hmm, yeah this looks like something that's worth considering going
forward. I can't think of any reason not to do this. Perhaps we can
write getObjectClass using this, too.

I just noticed a lot of the DropFooById() functions consist of just
"open catalog, lookup tuple by OID, delete tuple, close catalog". Which
I think we could rewrite in a generic manner using the table proposed by
this patch, and save some boilerplate code. Now there's a portion of
the functions that have some code in addition to that, but we can still
call the generic one and then do the rest of the stuff in the
class-specific function. Looks like a pretty easy code removal project.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers