diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 7cb46e1278..9ca609d886 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -646,13 +646,11 @@ get_object_address(ObjectType objtype, List *objname, List *objargs, break; case OBJECT_DOMCONSTRAINT: { - List *domname; ObjectAddress domaddr; char *constrname; - domname = list_truncate(list_copy(objname), list_length(objname) - 1); - constrname = strVal(llast(objname)); - domaddr = get_object_address_type(OBJECT_DOMAIN, domname, missing_ok); + domaddr = get_object_address_type(OBJECT_DOMAIN, objname, missing_ok); + constrname = strVal(linitial(objargs)); address.classId = ConstraintRelationId; address.objectId = get_domain_constraint_oid(domaddr.objectId, @@ -1291,14 +1289,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, List *objname, bool missing_ok) { ObjectAddress address; TypeName *typename; Type tup; - typename = makeTypeNameFromNameList(objname); + typename = (TypeName *) linitial(objname); address.classId = TypeRelationId; address.objectId = InvalidOid; @@ -1428,27 +1425,8 @@ pg_get_object_address(PG_FUNCTION_ARGS) * given object type. Most use a simple string Values list, but there * are some exceptions. */ - if (type == OBJECT_TYPE || type == OBJECT_DOMAIN) - { - Datum *elems; - bool *nulls; - int nelems; - TypeName *typname; - - deconstruct_array(namearr, TEXTOID, -1, false, 'i', - &elems, &nulls, &nelems); - if (nelems != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("name list length must be exactly %d", 1))); - if (nulls[0]) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("name or argument lists may not contain nulls"))); - typname = typeStringToTypeName(TextDatumGetCString(elems[0])); - name = typname->names; - } - else if (type == OBJECT_CAST) + if (type == OBJECT_TYPE || type == OBJECT_DOMAIN || type == OBJECT_CAST || + type == OBJECT_DOMCONSTRAINT) { Datum *elems; bool *nulls; @@ -1533,18 +1511,13 @@ pg_get_object_address(PG_FUNCTION_ARGS) */ switch (type) { - case OBJECT_DOMCONSTRAINT: - 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_LARGEOBJECT: if (list_length(name) != 1) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("name list length must be %d", 1))); + errmsg("name list length must be exactly %d", 1))); break; + case OBJECT_DOMCONSTRAINT: case OBJECT_OPCLASS: case OBJECT_OPFAMILY: case OBJECT_CAST: diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index 858358166d..21a2ae441a 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -264,10 +264,14 @@ does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs) { case OBJECT_TYPE: case OBJECT_DOMAIN: - if (!schema_does_not_exist_skipping(objname, &msg, &name)) { - msg = gettext_noop("type \"%s\" does not exist, skipping"); - name = TypeNameToString(makeTypeNameFromNameList(objname)); + TypeName *typ = linitial(objname); + + if (!schema_does_not_exist_skipping(typ->names, &msg, &name)) + { + msg = gettext_noop("type \"%s\" does not exist, skipping"); + name = TypeNameToString(typ); + } } break; case OBJECT_COLLATION: diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 6431601c66..eaaf2c2333 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -351,7 +351,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); opt_column_list columnList opt_name_list sort_clause opt_sort_clause sortby_list index_params name_list role_list from_clause from_list opt_array_bounds - qualified_name_list any_name any_name_list + qualified_name_list any_name any_name_list type_name_list any_operator expr_list attrs target_list opt_target_list insert_column_list set_target_list set_clause_list set_clause multiple_set_clause @@ -5471,6 +5471,46 @@ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior n->concurrent = false; $$ = (Node *)n; } + | DROP TYPE_P type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_TYPE; + n->missing_ok = FALSE; + n->objects = $3; + n->behavior = $4; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP TYPE_P IF_P EXISTS type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_TYPE; + n->missing_ok = TRUE; + n->objects = $5; + n->behavior = $6; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP DOMAIN_P type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_DOMAIN; + n->missing_ok = FALSE; + n->objects = $3; + n->behavior = $4; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP DOMAIN_P IF_P EXISTS type_name_list opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_DOMAIN; + n->missing_ok = TRUE; + n->objects = $5; + n->behavior = $6; + n->concurrent = false; + $$ = (Node *) n; + } | DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); @@ -5503,8 +5543,6 @@ drop_type: TABLE { $$ = OBJECT_TABLE; } | INDEX { $$ = OBJECT_INDEX; } | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } - | TYPE_P { $$ = OBJECT_TYPE; } - | DOMAIN_P { $$ = OBJECT_DOMAIN; } | COLLATION { $$ = OBJECT_COLLATION; } | CONVERSION_P { $$ = OBJECT_CONVERSION; } | SCHEMA { $$ = OBJECT_SCHEMA; } @@ -5530,6 +5568,9 @@ attrs: '.' attr_name { $$ = lappend($1, makeString($3)); } ; +type_name_list: + Typename { $$ = list_make1(list_make1($1)); } + | type_name_list ',' Typename { $$ = lappend($1, list_make1($3)); } /***************************************************************************** * @@ -5594,6 +5635,24 @@ CommentStmt: n->comment = $6; $$ = (Node *) n; } + | COMMENT ON TYPE_P Typename IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_TYPE; + n->objname = list_make1($4); + n->objargs = NIL; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON DOMAIN_P Typename IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_DOMAIN; + n->objname = list_make1($4); + n->objargs = NIL; + n->comment = $6; + $$ = (Node *) n; + } | COMMENT ON AGGREGATE func_name aggr_args IS comment_text { CommentStmt *n = makeNode(CommentStmt); @@ -5634,8 +5693,13 @@ CommentStmt: { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJECT_DOMCONSTRAINT; - n->objname = lappend($7, makeString($4)); - n->objargs = NIL; + /* + * should use Typename not any_name in the production, but + * there's a shift/reduce conflict if we do that, so fix it + * up here. + */ + n->objname = list_make1(makeTypeNameFromNameList($7)); + n->objargs = list_make1(makeString($4)); n->comment = $9; $$ = (Node *) n; } @@ -5730,8 +5794,6 @@ comment_type: | INDEX { $$ = OBJECT_INDEX; } | SEQUENCE { $$ = OBJECT_SEQUENCE; } | TABLE { $$ = OBJECT_TABLE; } - | DOMAIN_P { $$ = OBJECT_DOMAIN; } - | TYPE_P { $$ = OBJECT_TYPE; } | VIEW { $$ = OBJECT_VIEW; } | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } | COLLATION { $$ = OBJECT_COLLATION; } @@ -5776,6 +5838,28 @@ SecLabelStmt: n->label = $8; $$ = (Node *) n; } + | SECURITY LABEL opt_provider ON TYPE_P Typename + IS security_label + { + SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; + n->objtype = OBJECT_TYPE; + n->objname = list_make1($6); + n->objargs = NIL; + n->label = $8; + $$ = (Node *) n; + } + | SECURITY LABEL opt_provider ON DOMAIN_P Typename + IS security_label + { + SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; + n->objtype = OBJECT_TYPE; + n->objname = list_make1($6); + n->objargs = NIL; + n->label = $8; + $$ = (Node *) n; + } | SECURITY LABEL opt_provider ON AGGREGATE func_name aggr_args IS security_label { @@ -5834,10 +5918,8 @@ security_label_type: | SCHEMA { $$ = OBJECT_SCHEMA; } | SEQUENCE { $$ = OBJECT_SEQUENCE; } | TABLE { $$ = OBJECT_TABLE; } - | DOMAIN_P { $$ = OBJECT_TYPE; } | ROLE { $$ = OBJECT_ROLE; } | TABLESPACE { $$ = OBJECT_TABLESPACE; } - | TYPE_P { $$ = OBJECT_TYPE; } | VIEW { $$ = OBJECT_VIEW; } | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } ; diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql index e5209b9e44..dc55895d93 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -132,7 +132,7 @@ WITH objects (type, name, args) AS (VALUES ('cast', '{int8}', '{int4}'), ('collation', '{default}', '{}'), ('table constraint', '{addr_nsp, gentable, a_chk}', '{}'), - ('domain constraint', '{addr_nsp, gendomain, domconstr}', '{}'), + ('domain constraint', '{addr_nsp.gendomain}', '{domconstr}'), ('conversion', '{pg_catalog, ascii_to_mic}', '{}'), ('default value', '{addr_nsp, gentable, b}', '{}'), ('language', '{plpgsql}', '{}'),