Commit a61fd533 authored by Alvaro Herrera's avatar Alvaro Herrera

Support opfamily members in get_object_address

In the spirit of 890192e9 and 44643034: 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
parent 8d1f2390
This diff is collapsed.
......@@ -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))
{
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(objname);
args = strVal(linitial(objargs));
name = NameListToString(opcname);
args = strVal(linitial(objname));
}
}
break;
case OBJECT_OPFAMILY:
if (!schema_does_not_exist_skipping(objname, &msg, &name))
{
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(objname);
args = strVal(linitial(objargs));
name = NameListToString(opfname);
args = strVal(linitial(objname));
}
}
break;
default:
......
......@@ -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:
......
......@@ -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;
}
......
......@@ -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,
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment