diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 142bc689e9..46ea09a611 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) { @@ -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); diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index e5185ba34d..a1b0d4d2fa 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 3fec57ea23..4bcc327a2b 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 cf0d31744e..149962035d 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 50e98291bd..a5753539a3 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 3bcbcd8b65..365dcca718 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 a49f03fdf7..9cf8097124 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