summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlvaro Herrera2015-03-16 15:06:34 +0000
committerAlvaro Herrera2015-03-16 15:06:34 +0000
commita61fd5334eb1040d0dcec0368702398a5b49152c (patch)
treeb7976f69848c8b072cef4104208e5834ec4d93b2 /src
parent8d1f239003d0245dda636dfa6cf0add13bee69d6 (diff)
Support opfamily members in get_object_address
In the spirit of 890192e99af and 4464303405f: have get_object_address understand individual pg_amop and pg_amproc objects. There is no way to refer to such objects directly in the grammar -- rather, they are almost always considered an integral part of the opfamily that contains them. (The only case that deals with them individually is ALTER OPERATOR FAMILY ADD/DROP, which carries the opfamily address separately and thus does not need it to be part of each added/dropped element's address.) In event triggers it becomes possible to become involved with individual amop/amproc elements, and this commit enables pg_get_object_address to do so as well. To make the overall coding simpler, this commit also slightly changes the get_object_address representation for opclasses and opfamilies: instead of having the AM name in the objargs array, I moved it as the first element of the objnames array. This enables the new code to use objargs for the type names used by pg_amop and pg_amproc. Reviewed by: Stephen Frost
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/objectaddress.c234
-rw-r--r--src/backend/commands/dropcmds.c24
-rw-r--r--src/backend/commands/event_trigger.c2
-rw-r--r--src/backend/parser/gram.y43
-rw-r--r--src/include/nodes/parsenodes.h2
-rw-r--r--src/test/regress/expected/object_address.out60
-rw-r--r--src/test/regress/sql/object_address.sql16
7 files changed, 264 insertions, 117 deletions
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 142bc689e95..46ea09a6118 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -492,9 +492,9 @@ ObjectTypeMap[] =
/* OCLASS_OPFAMILY */
{ "operator family", OBJECT_OPFAMILY },
/* OCLASS_AMOP */
- { "operator of access method", -1 }, /* unmapped */
+ { "operator of access method", OBJECT_AMOP },
/* OCLASS_AMPROC */
- { "function of access method", -1 }, /* unmapped */
+ { "function of access method", OBJECT_AMPROC },
/* OCLASS_REWRITE */
{ "rule", OBJECT_RULE },
/* OCLASS_TRIGGER */
@@ -552,9 +552,12 @@ static ObjectAddress get_object_address_attrdef(ObjectType objtype,
List *objname, Relation *relp, LOCKMODE lockmode,
bool missing_ok);
static ObjectAddress get_object_address_type(ObjectType objtype,
- List *objname, bool missing_ok);
+ ListCell *typecell, bool missing_ok);
static ObjectAddress get_object_address_opcf(ObjectType objtype, List *objname,
- List *objargs, bool missing_ok);
+ bool missing_ok);
+static ObjectAddress get_object_address_opf_member(ObjectType objtype,
+ List *objname, List *objargs, bool missing_ok);
+
static ObjectAddress get_object_address_usermapping(List *objname,
List *objargs, bool missing_ok);
static ObjectAddress get_object_address_defacl(List *objname, List *objargs,
@@ -567,8 +570,7 @@ static void getRelationTypeDescription(StringInfo buffer, Oid relid,
int32 objectSubId);
static void getProcedureTypeDescription(StringInfo buffer, Oid procid);
static void getConstraintTypeDescription(StringInfo buffer, Oid constroid);
-static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **objname,
- List **objargs);
+static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **objname);
static void getRelationIdentity(StringInfo buffer, Oid relid, List **objname);
/*
@@ -661,7 +663,8 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
ObjectAddress domaddr;
char *constrname;
- domaddr = get_object_address_type(OBJECT_DOMAIN, objname, missing_ok);
+ domaddr = get_object_address_type(OBJECT_DOMAIN,
+ list_head(objname), missing_ok);
constrname = strVal(linitial(objargs));
address.classId = ConstraintRelationId;
@@ -685,7 +688,7 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
break;
case OBJECT_TYPE:
case OBJECT_DOMAIN:
- address = get_object_address_type(objtype, objname, missing_ok);
+ address = get_object_address_type(objtype, list_head(objname), missing_ok);
break;
case OBJECT_AGGREGATE:
address.classId = ProcedureRelationId;
@@ -721,8 +724,12 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
break;
case OBJECT_OPCLASS:
case OBJECT_OPFAMILY:
- address = get_object_address_opcf(objtype,
- objname, objargs, missing_ok);
+ address = get_object_address_opcf(objtype, objname, missing_ok);
+ break;
+ case OBJECT_AMOP:
+ case OBJECT_AMPROC:
+ address = get_object_address_opf_member(objtype, objname,
+ objargs, missing_ok);
break;
case OBJECT_LARGEOBJECT:
Assert(list_length(objname) == 1);
@@ -1309,13 +1316,13 @@ get_object_address_attrdef(ObjectType objtype, List *objname,
* Find the ObjectAddress for a type or domain
*/
static ObjectAddress
-get_object_address_type(ObjectType objtype, List *objname, bool missing_ok)
+get_object_address_type(ObjectType objtype, ListCell *typecell, bool missing_ok)
{
ObjectAddress address;
TypeName *typename;
Type tup;
- typename = (TypeName *) linitial(objname);
+ typename = (TypeName *) lfirst(typecell);
address.classId = TypeRelationId;
address.objectId = InvalidOid;
@@ -1351,15 +1358,14 @@ get_object_address_type(ObjectType objtype, List *objname, bool missing_ok)
* Find the ObjectAddress for an opclass or opfamily.
*/
static ObjectAddress
-get_object_address_opcf(ObjectType objtype,
- List *objname, List *objargs, bool missing_ok)
+get_object_address_opcf(ObjectType objtype, List *objname, bool missing_ok)
{
Oid amoid;
ObjectAddress address;
- Assert(list_length(objargs) == 1);
/* XXX no missing_ok support here */
- amoid = get_am_oid(strVal(linitial(objargs)), false);
+ amoid = get_am_oid(strVal(linitial(objname)), false);
+ objname = list_copy_tail(objname, 1);
switch (objtype)
{
@@ -1385,6 +1391,114 @@ get_object_address_opcf(ObjectType objtype,
}
/*
+ * Find the ObjectAddress for an opclass/opfamily member.
+ *
+ * (The returned address corresponds to a pg_amop/pg_amproc object).
+ */
+static ObjectAddress
+get_object_address_opf_member(ObjectType objtype,
+ List *objname, List *objargs, bool missing_ok)
+{
+ ObjectAddress famaddr;
+ ObjectAddress address;
+ ListCell *cell;
+ List *copy;
+ char *typenames[2];
+ Oid typeoids[2];
+ int membernum;
+ int i;
+
+ /*
+ * The last element of the objname list contains the strategy or procedure
+ * number. We need to strip that out before getting the opclass/family
+ * address. The rest can be used directly by get_object_address_opcf().
+ */
+ membernum = atoi(strVal(llast(objname)));
+ copy = list_truncate(list_copy(objname), list_length(objname) - 1);
+
+ /* no missing_ok support here */
+ famaddr = get_object_address_opcf(OBJECT_OPFAMILY, copy, false);
+
+ /* find out left/right type names and OIDs */
+ i = 0;
+ foreach (cell, objargs)
+ {
+ ObjectAddress typaddr;
+
+ typenames[i] = strVal(lfirst(cell));
+ typaddr = get_object_address_type(OBJECT_TYPE, cell, missing_ok);
+ typeoids[i] = typaddr.objectId;
+ if (i++ >= 2)
+ break;
+ }
+
+ switch (objtype)
+ {
+ case OBJECT_AMOP:
+ {
+ HeapTuple tp;
+
+ ObjectAddressSet(address, AccessMethodOperatorRelationId,
+ InvalidOid);
+
+ tp = SearchSysCache4(AMOPSTRATEGY,
+ ObjectIdGetDatum(famaddr.objectId),
+ ObjectIdGetDatum(typeoids[0]),
+ ObjectIdGetDatum(typeoids[1]),
+ Int16GetDatum(membernum));
+ if (!HeapTupleIsValid(tp))
+ {
+ if (!missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("operator %d (%s, %s) of %s does not exist",
+ membernum, typenames[0], typenames[1],
+ getObjectDescription(&famaddr))));
+ }
+ else
+ {
+ address.objectId = HeapTupleGetOid(tp);
+ ReleaseSysCache(tp);
+ }
+ }
+ break;
+
+ case OBJECT_AMPROC:
+ {
+ HeapTuple tp;
+
+ ObjectAddressSet(address, AccessMethodProcedureRelationId,
+ InvalidOid);
+
+ tp = SearchSysCache4(AMPROCNUM,
+ ObjectIdGetDatum(famaddr.objectId),
+ ObjectIdGetDatum(typeoids[0]),
+ ObjectIdGetDatum(typeoids[1]),
+ Int16GetDatum(membernum));
+ if (!HeapTupleIsValid(tp))
+ {
+ if (!missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("function %d (%s, %s) of %s does not exist",
+ membernum, typenames[0], typenames[1],
+ getObjectDescription(&famaddr))));
+ }
+ else
+ {
+ address.objectId = HeapTupleGetOid(tp);
+ ReleaseSysCache(tp);
+ }
+ }
+ break;
+ default:
+ elog(ERROR, "unrecognized objtype: %d", (int) objtype);
+ }
+
+ return address;
+}
+
+/*
* Find the ObjectAddress for a user mapping.
*/
static ObjectAddress
@@ -1673,7 +1787,9 @@ pg_get_object_address(PG_FUNCTION_ARGS)
if (type == OBJECT_AGGREGATE ||
type == OBJECT_FUNCTION ||
type == OBJECT_OPERATOR ||
- type == OBJECT_CAST)
+ type == OBJECT_CAST ||
+ type == OBJECT_AMOP ||
+ type == OBJECT_AMPROC)
{
/* in these cases, the args list must be of TypeName */
Datum *elems;
@@ -1708,8 +1824,6 @@ pg_get_object_address(PG_FUNCTION_ARGS)
switch (type)
{
case OBJECT_DOMCONSTRAINT:
- case OBJECT_OPCLASS:
- case OBJECT_OPFAMILY:
case OBJECT_CAST:
case OBJECT_USER_MAPPING:
case OBJECT_DEFACL:
@@ -1718,6 +1832,20 @@ pg_get_object_address(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("argument list length must be exactly %d", 1)));
break;
+ case OBJECT_OPFAMILY:
+ case OBJECT_OPCLASS:
+ if (list_length(name) < 2)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("name list length must be at least %d", 2)));
+ break;
+ case OBJECT_AMOP:
+ case OBJECT_AMPROC:
+ if (list_length(name) < 3)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("name list length must be at least %d", 3)));
+ /* fall through to check args length */
case OBJECT_OPERATOR:
if (list_length(args) != 2)
ereport(ERROR,
@@ -3730,24 +3858,22 @@ getObjectIdentityParts(const ObjectAddress *object,
opcForm->opcmethod);
amForm = (Form_pg_am) GETSTRUCT(amTup);
- appendStringInfoString(&buffer,
- quote_qualified_identifier(schema,
- NameStr(opcForm->opcname)));
- appendStringInfo(&buffer, " USING %s",
+ appendStringInfo(&buffer, "%s USING %s",
+ quote_qualified_identifier(schema,
+ NameStr(opcForm->opcname)),
quote_identifier(NameStr(amForm->amname)));
if (objname)
- {
- *objname = list_make2(pstrdup(schema),
+ *objname = list_make3(pstrdup(NameStr(amForm->amname)),
+ schema,
pstrdup(NameStr(opcForm->opcname)));
- *objargs = list_make1(pstrdup(NameStr(amForm->amname)));
- }
+
ReleaseSysCache(amTup);
ReleaseSysCache(opcTup);
break;
}
case OCLASS_OPFAMILY:
- getOpFamilyIdentity(&buffer, object->objectId, objname, objargs);
+ getOpFamilyIdentity(&buffer, object->objectId, objname);
break;
case OCLASS_AMOP:
@@ -3758,10 +3884,8 @@ getObjectIdentityParts(const ObjectAddress *object,
SysScanDesc amscan;
Form_pg_amop amopForm;
StringInfoData opfam;
-
- /* no objname support here */
- if (objname)
- *objname = NIL;
+ char *ltype;
+ char *rtype;
amopDesc = heap_open(AccessMethodOperatorRelationId,
AccessShareLock);
@@ -3783,13 +3907,21 @@ getObjectIdentityParts(const ObjectAddress *object,
amopForm = (Form_pg_amop) GETSTRUCT(tup);
initStringInfo(&opfam);
- getOpFamilyIdentity(&opfam, amopForm->amopfamily, NULL, NULL);
+ getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname);
+
+ ltype = format_type_be_qualified(amopForm->amoplefttype);
+ rtype = format_type_be_qualified(amopForm->amoprighttype);
+
+ if (objname)
+ {
+ *objname = lappend(*objname,
+ psprintf("%d", amopForm->amopstrategy));
+ *objargs = list_make2(ltype, rtype);
+ }
appendStringInfo(&buffer, "operator %d (%s, %s) of %s",
amopForm->amopstrategy,
- format_type_be_qualified(amopForm->amoplefttype),
- format_type_be_qualified(amopForm->amoprighttype),
- opfam.data);
+ ltype, rtype, opfam.data);
pfree(opfam.data);
@@ -3806,10 +3938,8 @@ getObjectIdentityParts(const ObjectAddress *object,
HeapTuple tup;
Form_pg_amproc amprocForm;
StringInfoData opfam;
-
- /* no objname support here */
- if (objname)
- *objname = NIL;
+ char *ltype;
+ char *rtype;
amprocDesc = heap_open(AccessMethodProcedureRelationId,
AccessShareLock);
@@ -3831,13 +3961,21 @@ getObjectIdentityParts(const ObjectAddress *object,
amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
initStringInfo(&opfam);
- getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, NULL, NULL);
+ getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname);
+
+ ltype = format_type_be_qualified(amprocForm->amproclefttype);
+ rtype = format_type_be_qualified(amprocForm->amprocrighttype);
+
+ if (objname)
+ {
+ *objname = lappend(*objname,
+ psprintf("%d", amprocForm->amprocnum));
+ *objargs = list_make2(ltype, rtype);
+ }
appendStringInfo(&buffer, "function %d (%s, %s) of %s",
amprocForm->amprocnum,
- format_type_be_qualified(amprocForm->amproclefttype),
- format_type_be_qualified(amprocForm->amprocrighttype),
- opfam.data);
+ ltype, rtype, opfam.data);
pfree(opfam.data);
@@ -4263,7 +4401,7 @@ getObjectIdentityParts(const ObjectAddress *object,
}
static void
-getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **objname, List **objargs)
+getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **objname)
{
HeapTuple opfTup;
Form_pg_opfamily opfForm;
@@ -4289,11 +4427,9 @@ getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **objname, List **objargs
NameStr(amForm->amname));
if (objname)
- {
- *objname = list_make2(pstrdup(schema),
+ *objname = list_make3(pstrdup(NameStr(amForm->amname)),
+ pstrdup(schema),
pstrdup(NameStr(opfForm->opfname)));
- *objargs = list_make1(pstrdup(NameStr(amForm->amname)));
- }
ReleaseSysCache(amTup);
ReleaseSysCache(opfTup);
diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c
index e5185ba34d2..a1b0d4d2fa2 100644
--- a/src/backend/commands/dropcmds.c
+++ b/src/backend/commands/dropcmds.c
@@ -406,19 +406,27 @@ does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs)
name = NameListToString(objname);
break;
case OBJECT_OPCLASS:
- if (!schema_does_not_exist_skipping(objname, &msg, &name))
{
- msg = gettext_noop("operator class \"%s\" does not exist for access method \"%s\", skipping");
- name = NameListToString(objname);
- args = strVal(linitial(objargs));
+ List *opcname = list_copy_tail(objname, 1);
+
+ if (!schema_does_not_exist_skipping(opcname, &msg, &name))
+ {
+ msg = gettext_noop("operator class \"%s\" does not exist for access method \"%s\", skipping");
+ name = NameListToString(opcname);
+ args = strVal(linitial(objname));
+ }
}
break;
case OBJECT_OPFAMILY:
- if (!schema_does_not_exist_skipping(objname, &msg, &name))
{
- msg = gettext_noop("operator family \"%s\" does not exist for access method \"%s\", skipping");
- name = NameListToString(objname);
- args = strVal(linitial(objargs));
+ List *opfname = list_copy_tail(objname, 1);
+
+ if (!schema_does_not_exist_skipping(opfname, &msg, &name))
+ {
+ msg = gettext_noop("operator family \"%s\" does not exist for access method \"%s\", skipping");
+ name = NameListToString(opfname);
+ args = strVal(linitial(objname));
+ }
}
break;
default:
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index 3fec57ea237..4bcc327a2b5 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -1060,6 +1060,8 @@ EventTriggerSupportsObjectType(ObjectType obtype)
/* no support for event triggers on event triggers */
return false;
case OBJECT_AGGREGATE:
+ case OBJECT_AMOP:
+ case OBJECT_AMPROC:
case OBJECT_ATTRIBUTE:
case OBJECT_CAST:
case OBJECT_COLUMN:
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index cf0d31744e1..149962035dc 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3950,8 +3950,7 @@ AlterExtensionContentsStmt:
n->extname = $3;
n->action = $4;
n->objtype = OBJECT_OPCLASS;
- n->objname = $7;
- n->objargs = list_make1(makeString($9));
+ n->objname = lcons(makeString($9), $7);
$$ = (Node *)n;
}
| ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING access_method
@@ -3960,8 +3959,7 @@ AlterExtensionContentsStmt:
n->extname = $3;
n->action = $4;
n->objtype = OBJECT_OPFAMILY;
- n->objname = $7;
- n->objargs = list_make1(makeString($9));
+ n->objname = lcons(makeString($9), $7);
$$ = (Node *)n;
}
| ALTER EXTENSION name add_drop SCHEMA name
@@ -5362,8 +5360,7 @@ DropOpClassStmt:
DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
- n->objects = list_make1($4);
- n->arguments = list_make1(list_make1(makeString($6)));
+ n->objects = list_make1(lcons(makeString($6), $4));
n->removeType = OBJECT_OPCLASS;
n->behavior = $7;
n->missing_ok = false;
@@ -5373,8 +5370,7 @@ DropOpClassStmt:
| DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
- n->objects = list_make1($6);
- n->arguments = list_make1(list_make1(makeString($8)));
+ n->objects = list_make1(lcons(makeString($8), $6));
n->removeType = OBJECT_OPCLASS;
n->behavior = $9;
n->missing_ok = true;
@@ -5387,8 +5383,7 @@ DropOpFamilyStmt:
DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
- n->objects = list_make1($4);
- n->arguments = list_make1(list_make1(makeString($6)));
+ n->objects = list_make1(lcons(makeString($6), $4));
n->removeType = OBJECT_OPFAMILY;
n->behavior = $7;
n->missing_ok = false;
@@ -5398,8 +5393,7 @@ DropOpFamilyStmt:
| DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
- n->objects = list_make1($6);
- n->arguments = list_make1(list_make1(makeString($8)));
+ n->objects = list_make1(lcons(makeString($8), $6));
n->removeType = OBJECT_OPFAMILY;
n->behavior = $9;
n->missing_ok = true;
@@ -5741,8 +5735,7 @@ CommentStmt:
{
CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_OPCLASS;
- n->objname = $5;
- n->objargs = list_make1(makeString($7));
+ n->objname = lcons(makeString($7), $5);
n->comment = $9;
$$ = (Node *) n;
}
@@ -5750,8 +5743,8 @@ CommentStmt:
{
CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_OPFAMILY;
- n->objname = $5;
- n->objargs = list_make1(makeString($7));
+ n->objname = lcons(makeString($7), $5);
+ n->objargs = NIL;
n->comment = $9;
$$ = (Node *) n;
}
@@ -7476,8 +7469,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_OPCLASS;
- n->object = $4;
- n->objarg = list_make1(makeString($6));
+ n->object = lcons(makeString($6), $4);
n->newname = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -7486,8 +7478,7 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_OPFAMILY;
- n->object = $4;
- n->objarg = list_make1(makeString($6));
+ n->object = lcons(makeString($6), $4);
n->newname = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -7924,8 +7915,7 @@ AlterObjectSchemaStmt:
{
AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
n->objectType = OBJECT_OPCLASS;
- n->object = $4;
- n->objarg = list_make1(makeString($6));
+ n->object = lcons(makeString($6), $4);
n->newschema = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -7934,8 +7924,7 @@ AlterObjectSchemaStmt:
{
AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
n->objectType = OBJECT_OPFAMILY;
- n->object = $4;
- n->objarg = list_make1(makeString($6));
+ n->object = lcons(makeString($6), $4);
n->newschema = $9;
n->missing_ok = false;
$$ = (Node *)n;
@@ -8162,8 +8151,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPCLASS;
- n->object = $4;
- n->objarg = list_make1(makeString($6));
+ n->object = lcons(makeString($6), $4);
n->newowner = $9;
$$ = (Node *)n;
}
@@ -8171,8 +8159,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPFAMILY;
- n->object = $4;
- n->objarg = list_make1(makeString($6));
+ n->object = lcons(makeString($6), $4);
n->newowner = $9;
$$ = (Node *)n;
}
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 50e98291bda..a5753539a30 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1223,6 +1223,8 @@ typedef struct SetOperationStmt
typedef enum ObjectType
{
OBJECT_AGGREGATE,
+ OBJECT_AMOP,
+ OBJECT_AMPROC,
OBJECT_ATTRIBUTE, /* type's attribute, when distinct from column */
OBJECT_CAST,
OBJECT_COLUMN,
diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out
index 3bcbcd8b65f..365dcca7183 100644
--- a/src/test/regress/expected/object_address.out
+++ b/src/test/regress/expected/object_address.out
@@ -45,8 +45,7 @@ DECLARE
objtype text;
BEGIN
FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'),
- ('toast table column'), ('view column'), ('materialized view column'),
- ('operator of access method'), ('function of access method')
+ ('toast table column'), ('view column'), ('materialized view column')
LOOP
BEGIN
PERFORM pg_get_object_address(objtype, '{one}', '{}');
@@ -62,8 +61,6 @@ WARNING: error for sequence column: unsupported object type "sequence column"
WARNING: error for toast table column: unsupported object type "toast table column"
WARNING: error for view column: unsupported object type "view column"
WARNING: error for materialized view column: unsupported object type "materialized view column"
-WARNING: error for operator of access method: unsupported object type "operator of access method"
-WARNING: error for function of access method: unsupported object type "function of access method"
DO $$
DECLARE
objtype text;
@@ -79,7 +76,8 @@ BEGIN
('operator'), ('operator class'), ('operator family'), ('rule'), ('trigger'),
('text search parser'), ('text search dictionary'),
('text search template'), ('text search configuration'),
- ('policy'), ('user mapping'), ('default acl')
+ ('policy'), ('user mapping'), ('default acl'),
+ ('operator of access method'), ('function of access method')
LOOP
FOR names IN VALUES ('{eins}'), ('{addr_nsp, zwei}'), ('{eins, zwei, drei}')
LOOP
@@ -197,18 +195,18 @@ WARNING: error for operator,{addr_nsp,zwei},{}: argument list length must be ex
WARNING: error for operator,{addr_nsp,zwei},{integer}: argument list length must be exactly 2
WARNING: error for operator,{eins,zwei,drei},{}: argument list length must be exactly 2
WARNING: error for operator,{eins,zwei,drei},{integer}: argument list length must be exactly 2
-WARNING: error for operator class,{eins},{}: argument list length must be exactly 1
-WARNING: error for operator class,{eins},{integer}: access method "integer" does not exist
-WARNING: error for operator class,{addr_nsp,zwei},{}: argument list length must be exactly 1
-WARNING: error for operator class,{addr_nsp,zwei},{integer}: access method "integer" does not exist
-WARNING: error for operator class,{eins,zwei,drei},{}: argument list length must be exactly 1
-WARNING: error for operator class,{eins,zwei,drei},{integer}: access method "integer" does not exist
-WARNING: error for operator family,{eins},{}: argument list length must be exactly 1
-WARNING: error for operator family,{eins},{integer}: access method "integer" does not exist
-WARNING: error for operator family,{addr_nsp,zwei},{}: argument list length must be exactly 1
-WARNING: error for operator family,{addr_nsp,zwei},{integer}: access method "integer" does not exist
-WARNING: error for operator family,{eins,zwei,drei},{}: argument list length must be exactly 1
-WARNING: error for operator family,{eins,zwei,drei},{integer}: access method "integer" does not exist
+WARNING: error for operator class,{eins},{}: name list length must be at least 2
+WARNING: error for operator class,{eins},{integer}: name list length must be at least 2
+WARNING: error for operator class,{addr_nsp,zwei},{}: access method "addr_nsp" does not exist
+WARNING: error for operator class,{addr_nsp,zwei},{integer}: access method "addr_nsp" does not exist
+WARNING: error for operator class,{eins,zwei,drei},{}: access method "eins" does not exist
+WARNING: error for operator class,{eins,zwei,drei},{integer}: access method "eins" does not exist
+WARNING: error for operator family,{eins},{}: name list length must be at least 2
+WARNING: error for operator family,{eins},{integer}: name list length must be at least 2
+WARNING: error for operator family,{addr_nsp,zwei},{}: access method "addr_nsp" does not exist
+WARNING: error for operator family,{addr_nsp,zwei},{integer}: access method "addr_nsp" does not exist
+WARNING: error for operator family,{eins,zwei,drei},{}: access method "eins" does not exist
+WARNING: error for operator family,{eins,zwei,drei},{integer}: access method "eins" does not exist
WARNING: error for rule,{eins},{}: rule "eins" does not exist
WARNING: error for rule,{eins},{integer}: rule "eins" does not exist
WARNING: error for rule,{addr_nsp,zwei},{}: relation "addr_nsp" does not exist
@@ -263,6 +261,18 @@ WARNING: error for default acl,{addr_nsp,zwei},{}: argument list length must be
WARNING: error for default acl,{addr_nsp,zwei},{integer}: unrecognized default ACL object type i
WARNING: error for default acl,{eins,zwei,drei},{}: argument list length must be exactly 1
WARNING: error for default acl,{eins,zwei,drei},{integer}: unrecognized default ACL object type i
+WARNING: error for operator of access method,{eins},{}: name list length must be at least 3
+WARNING: error for operator of access method,{eins},{integer}: name list length must be at least 3
+WARNING: error for operator of access method,{addr_nsp,zwei},{}: name list length must be at least 3
+WARNING: error for operator of access method,{addr_nsp,zwei},{integer}: name list length must be at least 3
+WARNING: error for operator of access method,{eins,zwei,drei},{}: argument list length must be exactly 2
+WARNING: error for operator of access method,{eins,zwei,drei},{integer}: argument list length must be exactly 2
+WARNING: error for function of access method,{eins},{}: name list length must be at least 3
+WARNING: error for function of access method,{eins},{integer}: name list length must be at least 3
+WARNING: error for function of access method,{addr_nsp,zwei},{}: name list length must be at least 3
+WARNING: error for function of access method,{addr_nsp,zwei},{integer}: name list length must be at least 3
+WARNING: error for function of access method,{eins,zwei,drei},{}: argument list length must be exactly 2
+WARNING: error for function of access method,{eins,zwei,drei},{integer}: argument list length must be exactly 2
-- these object types cannot be qualified names
SELECT pg_get_object_address('language', '{one}', '{}');
ERROR: language "one" does not exist
@@ -332,10 +342,10 @@ WITH objects (type, name, args) AS (VALUES
('language', '{plpgsql}', '{}'),
-- large object
('operator', '{+}', '{int4, int4}'),
- ('operator class', '{int4_ops}', '{btree}'),
- ('operator family', '{integer_ops}', '{btree}'),
- -- operator of access method
- -- function of access method
+ ('operator class', '{btree, int4_ops}', '{}'),
+ ('operator family', '{btree, integer_ops}', '{}'),
+ ('operator of access method', '{btree,integer_ops,1}', '{integer,integer}'),
+ ('function of access method', '{btree,integer_ops,2}', '{integer,integer}'),
('rule', '{addr_nsp, genview, _RETURN}', '{}'),
('trigger', '{addr_nsp, gentable, t}', '{}'),
('schema', '{addr_nsp}', '{}'),
@@ -362,7 +372,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.subobjid)).*,
FROM objects, pg_get_object_address(type, name, args) addr1,
pg_identify_object_as_address(classid, objid, subobjid) ioa(typ,nms,args),
pg_get_object_address(typ, nms, ioa.args) as addr2
- ORDER BY addr1.classid, addr1.objid;
+ ORDER BY addr1.classid, addr1.objid, addr1.subobjid;
type | schema | name | identity | ?column?
---------------------------+------------+-------------------+----------------------------------------------------------------------+----------
default acl | | | for role regtest_addr_user in schema public on tables | t
@@ -379,12 +389,14 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.subobjid)).*,
index | addr_nsp | gentable_pkey | addr_nsp.gentable_pkey | t
view | addr_nsp | genview | addr_nsp.genview | t
materialized view | addr_nsp | genmatview | addr_nsp.genmatview | t
- foreign table column | addr_nsp | genftable | addr_nsp.genftable.a | t
foreign table | addr_nsp | genftable | addr_nsp.genftable | t
+ foreign table column | addr_nsp | genftable | addr_nsp.genftable.a | t
role | | regtest_addr_user | regtest_addr_user | t
server | | addr_fserv | addr_fserv | t
user mapping | | | regtest_addr_user on server integer | t
foreign-data wrapper | | addr_fdw | addr_fdw | t
+ operator of access method | | | operator 1 (integer, integer) of pg_catalog.integer_ops USING btree | t
+ function of access method | | | function 2 (integer, integer) of pg_catalog.integer_ops USING btree | t
default value | | | for addr_nsp.gentable.b | t
cast | | | (bigint AS integer) | t
table constraint | addr_nsp | | a_chk on addr_nsp.gentable | t
@@ -403,7 +415,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.subobjid)).*,
text search parser | addr_nsp | addr_ts_prs | addr_nsp.addr_ts_prs | t
text search configuration | addr_nsp | addr_ts_conf | addr_nsp.addr_ts_conf | t
text search template | addr_nsp | addr_ts_temp | addr_nsp.addr_ts_temp | t
-(38 rows)
+(40 rows)
---
--- Cleanup resources
diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql
index a49f03fdf7d..9cf80971241 100644
--- a/src/test/regress/sql/object_address.sql
+++ b/src/test/regress/sql/object_address.sql
@@ -48,8 +48,7 @@ DECLARE
objtype text;
BEGIN
FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'),
- ('toast table column'), ('view column'), ('materialized view column'),
- ('operator of access method'), ('function of access method')
+ ('toast table column'), ('view column'), ('materialized view column')
LOOP
BEGIN
PERFORM pg_get_object_address(objtype, '{one}', '{}');
@@ -75,7 +74,8 @@ BEGIN
('operator'), ('operator class'), ('operator family'), ('rule'), ('trigger'),
('text search parser'), ('text search dictionary'),
('text search template'), ('text search configuration'),
- ('policy'), ('user mapping'), ('default acl')
+ ('policy'), ('user mapping'), ('default acl'),
+ ('operator of access method'), ('function of access method')
LOOP
FOR names IN VALUES ('{eins}'), ('{addr_nsp, zwei}'), ('{eins, zwei, drei}')
LOOP
@@ -141,10 +141,10 @@ WITH objects (type, name, args) AS (VALUES
('language', '{plpgsql}', '{}'),
-- large object
('operator', '{+}', '{int4, int4}'),
- ('operator class', '{int4_ops}', '{btree}'),
- ('operator family', '{integer_ops}', '{btree}'),
- -- operator of access method
- -- function of access method
+ ('operator class', '{btree, int4_ops}', '{}'),
+ ('operator family', '{btree, integer_ops}', '{}'),
+ ('operator of access method', '{btree,integer_ops,1}', '{integer,integer}'),
+ ('function of access method', '{btree,integer_ops,2}', '{integer,integer}'),
('rule', '{addr_nsp, genview, _RETURN}', '{}'),
('trigger', '{addr_nsp, gentable, t}', '{}'),
('schema', '{addr_nsp}', '{}'),
@@ -171,7 +171,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.subobjid)).*,
FROM objects, pg_get_object_address(type, name, args) addr1,
pg_identify_object_as_address(classid, objid, subobjid) ioa(typ,nms,args),
pg_get_object_address(typ, nms, ioa.args) as addr2
- ORDER BY addr1.classid, addr1.objid;
+ ORDER BY addr1.classid, addr1.objid, addr1.subobjid;
---
--- Cleanup resources