Support opfamily members in get_object_address

In the spirit of 890192e99a 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
This commit is contained in:
Alvaro Herrera 2015-03-16 12:06:34 -03:00
parent 8d1f239003
commit a61fd5334e
7 changed files with 264 additions and 117 deletions

View File

@ -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)
{
@ -1384,6 +1390,114 @@ get_object_address_opcf(ObjectType objtype,
return address;
}
/*
* 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.
*/
@ -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);

View File

@ -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:

View File

@ -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:

View File

@ -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;
}

View File

@ -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,

View File

@ -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

View File

@ -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