From 7742b326de1e56b0731fcdfc4447a65c5899c8c1 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 10 Apr 2020 11:02:16 +0200 Subject: [PATCH v1 5/6] Grammar object type refactoring Unify the grammar of COMMENT, DROP, and SECURITY LABEL further. They all effectively just take an object address for later processing, so we can make the grammar more generalized. Some extra checking about which object types are supported can be done later in the statement execution. --- src/backend/commands/seclabel.c | 74 +++++++++++++++ src/backend/parser/gram.y | 161 ++++++++++---------------------- 2 files changed, 121 insertions(+), 114 deletions(-) diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c index b497c06f1a..ee036e9087 100644 --- a/src/backend/commands/seclabel.c +++ b/src/backend/commands/seclabel.c @@ -33,6 +33,75 @@ typedef struct static List *label_provider_list = NIL; +static bool +SecLabelSupportsObjectType(ObjectType objtype) +{ + switch (objtype) + { + case OBJECT_AGGREGATE: + case OBJECT_COLUMN: + case OBJECT_DATABASE: + case OBJECT_DOMAIN: + case OBJECT_EVENT_TRIGGER: + case OBJECT_FOREIGN_TABLE: + case OBJECT_FUNCTION: + case OBJECT_LANGUAGE: + case OBJECT_LARGEOBJECT: + case OBJECT_MATVIEW: + case OBJECT_PROCEDURE: + case OBJECT_PUBLICATION: + case OBJECT_ROLE: + case OBJECT_ROUTINE: + case OBJECT_SCHEMA: + case OBJECT_SEQUENCE: + case OBJECT_SUBSCRIPTION: + case OBJECT_TABLE: + case OBJECT_TABLESPACE: + case OBJECT_TYPE: + case OBJECT_VIEW: + return true; + + case OBJECT_ACCESS_METHOD: + case OBJECT_AMOP: + case OBJECT_AMPROC: + case OBJECT_ATTRIBUTE: + case OBJECT_CAST: + case OBJECT_COLLATION: + case OBJECT_CONVERSION: + case OBJECT_DEFAULT: + case OBJECT_DEFACL: + case OBJECT_DOMCONSTRAINT: + case OBJECT_EXTENSION: + case OBJECT_FDW: + case OBJECT_FOREIGN_SERVER: + case OBJECT_INDEX: + case OBJECT_OPCLASS: + case OBJECT_OPERATOR: + case OBJECT_OPFAMILY: + case OBJECT_POLICY: + case OBJECT_PUBLICATION_REL: + case OBJECT_RULE: + case OBJECT_STATISTIC_EXT: + case OBJECT_TABCONSTRAINT: + case OBJECT_TRANSFORM: + case OBJECT_TRIGGER: + case OBJECT_TSCONFIGURATION: + case OBJECT_TSDICTIONARY: + case OBJECT_TSPARSER: + case OBJECT_TSTEMPLATE: + case OBJECT_USER_MAPPING: + return false; + + /* + * There's intentionally no default: case here; we want the + * compiler to warn if a new ObjectType hasn't been handled above. + */ + } + + /* Shouldn't get here, but if we do, say "no support" */ + return false; +} + /* * ExecSecLabelStmt -- * @@ -83,6 +152,11 @@ ExecSecLabelStmt(SecLabelStmt *stmt) stmt->provider))); } + if (!SecLabelSupportsObjectType(stmt->objtype)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("security labels are not supported for this type of object"))); + /* * Translate the parser representation which identifies this object into * an ObjectAddress. get_object_address() will throw an error if the diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 002b3ce01d..a1229ebddf 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -463,9 +463,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type copy_from opt_program %type opt_column event cursor_options opt_hold opt_set_data -%type drop_type_any_name drop_type_name drop_type_name_on_any_name - comment_type_any_name comment_type_name - security_label_type_any_name security_label_type_name +%type object_type_any_name object_type_name object_type_name_on_any_name + drop_type_name %type fetch_args select_limit_value offset_clause select_offset_value @@ -6195,7 +6194,7 @@ ReassignOwnedStmt: * *****************************************************************************/ -DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior +DropStmt: DROP object_type_any_name IF_P EXISTS any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = $2; @@ -6205,7 +6204,7 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior n->concurrent = false; $$ = (Node *)n; } - | DROP drop_type_any_name any_name_list opt_drop_behavior + | DROP object_type_any_name any_name_list opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = $2; @@ -6235,7 +6234,7 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior n->concurrent = false; $$ = (Node *)n; } - | DROP drop_type_name_on_any_name name ON any_name opt_drop_behavior + | DROP object_type_name_on_any_name name ON any_name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = $2; @@ -6245,7 +6244,7 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior n->concurrent = false; $$ = (Node *) n; } - | DROP drop_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior + | DROP object_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = $2; @@ -6317,8 +6316,8 @@ DropStmt: DROP drop_type_any_name IF_P EXISTS any_name_list opt_drop_behavior } ; -/* object types taking any_name_list */ -drop_type_any_name: +/* object types taking any_name/any_name_list */ +object_type_any_name: TABLE { $$ = OBJECT_TABLE; } | SEQUENCE { $$ = OBJECT_SEQUENCE; } | VIEW { $$ = OBJECT_VIEW; } @@ -6334,7 +6333,19 @@ drop_type_any_name: | TEXT_P SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; } ; -/* object types taking name_list */ +/* + * object types taking name/name_list + * + * DROP handles some of them separately + */ + +object_type_name: + drop_type_name { $$ = $1; } + | DATABASE { $$ = OBJECT_DATABASE; } + | ROLE { $$ = OBJECT_ROLE; } + | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; } + | TABLESPACE { $$ = OBJECT_TABLESPACE; } + ; drop_type_name: ACCESS METHOD { $$ = OBJECT_ACCESS_METHOD; } | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } @@ -6347,7 +6358,7 @@ drop_type_name: ; /* object types attached to a table */ -drop_type_name_on_any_name: +object_type_name_on_any_name: POLICY { $$ = OBJECT_POLICY; } | RULE { $$ = OBJECT_RULE; } | TRIGGER { $$ = OBJECT_TRIGGER; } @@ -6399,36 +6410,12 @@ opt_restart_seqs: /***************************************************************************** * - * The COMMENT ON statement can take different forms based upon the type of - * the object associated with the comment. The form of the statement is: - * - * COMMENT ON [ [ ACCESS METHOD | CONVERSION | COLLATION | - * DATABASE | DOMAIN | - * EXTENSION | EVENT TRIGGER | FOREIGN DATA WRAPPER | - * FOREIGN TABLE | INDEX | [PROCEDURAL] LANGUAGE | - * MATERIALIZED VIEW | POLICY | ROLE | SCHEMA | SEQUENCE | - * SERVER | STATISTICS | TABLE | TABLESPACE | - * TEXT SEARCH CONFIGURATION | TEXT SEARCH DICTIONARY | - * TEXT SEARCH PARSER | TEXT SEARCH TEMPLATE | TYPE | - * VIEW] | - * AGGREGATE (arg1, ...) | - * CAST ( AS ) | - * COLUMN . | - * CONSTRAINT ON | - * CONSTRAINT ON DOMAIN | - * FUNCTION (arg1, arg2, ...) | - * LARGE OBJECT | - * OPERATOR (leftoperand_typ, rightoperand_typ) | - * OPERATOR CLASS USING | - * OPERATOR FAMILY USING | - * RULE ON | - * TRIGGER ON ] - * IS { 'text' | NULL } + * COMMENT ON IS * *****************************************************************************/ CommentStmt: - COMMENT ON comment_type_any_name any_name IS comment_text + COMMENT ON object_type_any_name any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = $3; @@ -6436,7 +6423,15 @@ CommentStmt: n->comment = $6; $$ = (Node *) n; } - | COMMENT ON comment_type_name name IS comment_text + | COMMENT ON COLUMN any_name IS comment_text + { + CommentStmt *n = makeNode(CommentStmt); + n->objtype = OBJECT_COLUMN; + n->object = (Node *) $4; + n->comment = $6; + $$ = (Node *) n; + } + | COMMENT ON object_type_name name IS comment_text { CommentStmt *n = makeNode(CommentStmt); n->objtype = $3; @@ -6505,10 +6500,10 @@ CommentStmt: n->comment = $9; $$ = (Node *) n; } - | COMMENT ON POLICY name ON any_name IS comment_text + | COMMENT ON object_type_name_on_any_name name ON any_name IS comment_text { CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_POLICY; + n->objtype = $3; n->object = (Node *) lappend($6, makeString($4)); n->comment = $8; $$ = (Node *) n; @@ -6529,14 +6524,6 @@ CommentStmt: n->comment = $6; $$ = (Node *) n; } - | COMMENT ON RULE name ON any_name IS comment_text - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_RULE; - n->object = (Node *) lappend($6, makeString($4)); - n->comment = $8; - $$ = (Node *) n; - } | COMMENT ON TRANSFORM FOR Typename LANGUAGE name IS comment_text { CommentStmt *n = makeNode(CommentStmt); @@ -6545,14 +6532,6 @@ CommentStmt: n->comment = $9; $$ = (Node *) n; } - | COMMENT ON TRIGGER name ON any_name IS comment_text - { - CommentStmt *n = makeNode(CommentStmt); - n->objtype = OBJECT_TRIGGER; - n->object = (Node *) lappend($6, makeString($4)); - n->comment = $8; - $$ = (Node *) n; - } | COMMENT ON OPERATOR CLASS any_name USING name IS comment_text { CommentStmt *n = makeNode(CommentStmt); @@ -6587,40 +6566,6 @@ CommentStmt: } ; -/* object types taking any_name */ -comment_type_any_name: - COLUMN { $$ = OBJECT_COLUMN; } - | INDEX { $$ = OBJECT_INDEX; } - | SEQUENCE { $$ = OBJECT_SEQUENCE; } - | STATISTICS { $$ = OBJECT_STATISTIC_EXT; } - | TABLE { $$ = OBJECT_TABLE; } - | VIEW { $$ = OBJECT_VIEW; } - | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } - | COLLATION { $$ = OBJECT_COLLATION; } - | CONVERSION_P { $$ = OBJECT_CONVERSION; } - | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } - | TEXT_P SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; } - | TEXT_P SEARCH DICTIONARY { $$ = OBJECT_TSDICTIONARY; } - | TEXT_P SEARCH PARSER { $$ = OBJECT_TSPARSER; } - | TEXT_P SEARCH TEMPLATE { $$ = OBJECT_TSTEMPLATE; } - ; - -/* object types taking name */ -comment_type_name: - ACCESS METHOD { $$ = OBJECT_ACCESS_METHOD; } - | DATABASE { $$ = OBJECT_DATABASE; } - | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } - | EXTENSION { $$ = OBJECT_EXTENSION; } - | FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; } - | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; } - | PUBLICATION { $$ = OBJECT_PUBLICATION; } - | ROLE { $$ = OBJECT_ROLE; } - | SCHEMA { $$ = OBJECT_SCHEMA; } - | SERVER { $$ = OBJECT_FOREIGN_SERVER; } - | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; } - | TABLESPACE { $$ = OBJECT_TABLESPACE; } - ; - comment_text: Sconst { $$ = $1; } | NULL_P { $$ = NULL; } @@ -6637,7 +6582,7 @@ comment_text: *****************************************************************************/ SecLabelStmt: - SECURITY LABEL opt_provider ON security_label_type_any_name any_name + SECURITY LABEL opt_provider ON object_type_any_name any_name IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); @@ -6647,7 +6592,17 @@ SecLabelStmt: n->label = $8; $$ = (Node *) n; } - | SECURITY LABEL opt_provider ON security_label_type_name name + | SECURITY LABEL opt_provider ON COLUMN any_name + IS security_label + { + SecLabelStmt *n = makeNode(SecLabelStmt); + n->provider = $3; + n->objtype = OBJECT_COLUMN; + n->object = (Node *) $6; + n->label = $8; + $$ = (Node *) n; + } + | SECURITY LABEL opt_provider ON object_type_name name IS security_label { SecLabelStmt *n = makeNode(SecLabelStmt); @@ -6733,28 +6688,6 @@ opt_provider: FOR NonReservedWord_or_Sconst { $$ = $2; } | /* empty */ { $$ = NULL; } ; -/* object types taking any_name */ -security_label_type_any_name: - COLUMN { $$ = OBJECT_COLUMN; } - | FOREIGN TABLE { $$ = OBJECT_FOREIGN_TABLE; } - | SEQUENCE { $$ = OBJECT_SEQUENCE; } - | TABLE { $$ = OBJECT_TABLE; } - | VIEW { $$ = OBJECT_VIEW; } - | MATERIALIZED VIEW { $$ = OBJECT_MATVIEW; } - ; - -/* object types taking name */ -security_label_type_name: - DATABASE { $$ = OBJECT_DATABASE; } - | EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; } - | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; } - | PUBLICATION { $$ = OBJECT_PUBLICATION; } - | ROLE { $$ = OBJECT_ROLE; } - | SCHEMA { $$ = OBJECT_SCHEMA; } - | SUBSCRIPTION { $$ = OBJECT_SUBSCRIPTION; } - | TABLESPACE { $$ = OBJECT_TABLESPACE; } - ; - security_label: Sconst { $$ = $1; } | NULL_P { $$ = NULL; } ; -- 2.26.2