some grammar refactoring
Here is a series of patches to do some refactoring in the grammar around
the commands COMMENT, DROP, SECURITY LABEL, and ALTER EXTENSION ...
ADD/DROP. In the grammar, these commands (with some exceptions)
basically just take a reference to an object and later look it up in C
code. Some of that was already generalized individually for each
command (drop_type_any_name, drop_type_name, etc.). This patch combines
it into common lists for all these commands.
Advantages:
- Avoids having to list each object type at least four times.
- Object types not supported by security labels or extensions are now
explicitly listed and give a proper error message. Previously, this was
just encoded in the grammar itself and specifying a non-supported object
type would just give a parse error.
- Reduces lines of code in gram.y.
- Removes some old cruft.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:
v1-0003-Remove-deprecated-syntax-from-CREATE-DROP-LANGUAG.patchtext/plain; charset=UTF-8; name=v1-0003-Remove-deprecated-syntax-from-CREATE-DROP-LANGUAG.patch; x-mac-creator=0; x-mac-type=0Download
From 4d98c30c0ab1d60178e9f050491512b691b94b37 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Sat, 9 May 2020 11:01:31 +0200
Subject: [PATCH v1 3/6] Remove deprecated syntax from CREATE/DROP LANGUAGE
Remove the option to specify the language name as a single-quoted
string. This has been obsolete since ee8ed85da3b. Removing it allows
better grammar refactoring.
The syntax of the CREATE FUNCTION LANGUAGE clause is not changed.
---
doc/src/sgml/ref/create_language.sgml | 5 -----
doc/src/sgml/ref/drop_language.sgml | 3 +--
src/backend/parser/gram.y | 8 ++++----
3 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml
index 2243ee6a6c..a457e2558c 100644
--- a/doc/src/sgml/ref/create_language.sgml
+++ b/doc/src/sgml/ref/create_language.sgml
@@ -110,11 +110,6 @@ <title>Parameters</title>
The name of the new procedural language.
The name must be unique among the languages in the database.
</para>
-
- <para>
- For backward compatibility, the name can be enclosed by single
- quotes.
- </para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/drop_language.sgml b/doc/src/sgml/ref/drop_language.sgml
index 976f3a0ce1..4705836ac7 100644
--- a/doc/src/sgml/ref/drop_language.sgml
+++ b/doc/src/sgml/ref/drop_language.sgml
@@ -63,8 +63,7 @@ <title>Parameters</title>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
- The name of an existing procedural language. For backward
- compatibility, the name can be enclosed by single quotes.
+ The name of an existing procedural language.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index f00526e9c6..9af37b2c3d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -4351,7 +4351,7 @@ NumericOnly_list: NumericOnly { $$ = list_make1($1); }
*****************************************************************************/
CreatePLangStmt:
- CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE NonReservedWord_or_Sconst
+ CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name
{
/*
* We now interpret parameterless CREATE LANGUAGE as
@@ -4366,7 +4366,7 @@ CreatePLangStmt:
n->options = NIL;
$$ = (Node *)n;
}
- | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE NonReservedWord_or_Sconst
+ | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name
HANDLER handler_name opt_inline_handler opt_validator
{
CreatePLangStmt *n = makeNode(CreatePLangStmt);
@@ -4410,7 +4410,7 @@ opt_validator:
;
DropPLangStmt:
- DROP opt_procedural LANGUAGE NonReservedWord_or_Sconst opt_drop_behavior
+ DROP opt_procedural LANGUAGE name opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->removeType = OBJECT_LANGUAGE;
@@ -4420,7 +4420,7 @@ DropPLangStmt:
n->concurrent = false;
$$ = (Node *)n;
}
- | DROP opt_procedural LANGUAGE IF_P EXISTS NonReservedWord_or_Sconst opt_drop_behavior
+ | DROP opt_procedural LANGUAGE IF_P EXISTS name opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->removeType = OBJECT_LANGUAGE;
--
2.26.2
v1-0004-Refactor-DROP-LANGUAGE-grammar.patchtext/plain; charset=UTF-8; name=v1-0004-Refactor-DROP-LANGUAGE-grammar.patch; x-mac-creator=0; x-mac-type=0Download
From b4fc3fb474741e73530f4a2a33dc94c511dccaae Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Sat, 9 May 2020 11:09:45 +0200
Subject: [PATCH v1 4/6] Refactor DROP LANGUAGE grammar
Fold it into the generic DropStmt.
---
src/backend/parser/gram.y | 27 ++-------------------------
1 file changed, 2 insertions(+), 25 deletions(-)
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 9af37b2c3d..002b3ce01d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -272,7 +272,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
CreateAssertionStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt
CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt
- DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt
+ DropOpClassStmt DropOpFamilyStmt DropStmt
DropCastStmt DropRoleStmt
DropdbStmt DropTableSpaceStmt
DropTransformStmt
@@ -922,7 +922,6 @@ stmt :
| DropOpClassStmt
| DropOpFamilyStmt
| DropOwnedStmt
- | DropPLangStmt
| DropStmt
| DropSubscriptionStmt
| DropTableSpaceStmt
@@ -4409,29 +4408,6 @@ opt_validator:
| /*EMPTY*/ { $$ = NIL; }
;
-DropPLangStmt:
- DROP opt_procedural LANGUAGE name opt_drop_behavior
- {
- DropStmt *n = makeNode(DropStmt);
- n->removeType = OBJECT_LANGUAGE;
- n->objects = list_make1(makeString($4));
- n->behavior = $5;
- n->missing_ok = false;
- n->concurrent = false;
- $$ = (Node *)n;
- }
- | DROP opt_procedural LANGUAGE IF_P EXISTS name opt_drop_behavior
- {
- DropStmt *n = makeNode(DropStmt);
- n->removeType = OBJECT_LANGUAGE;
- n->objects = list_make1(makeString($6));
- n->behavior = $7;
- n->missing_ok = true;
- n->concurrent = false;
- $$ = (Node *)n;
- }
- ;
-
opt_procedural:
PROCEDURAL {}
| /*EMPTY*/ {}
@@ -6364,6 +6340,7 @@ drop_type_name:
| EVENT TRIGGER { $$ = OBJECT_EVENT_TRIGGER; }
| EXTENSION { $$ = OBJECT_EXTENSION; }
| FOREIGN DATA_P WRAPPER { $$ = OBJECT_FDW; }
+ | opt_procedural LANGUAGE { $$ = OBJECT_LANGUAGE; }
| PUBLICATION { $$ = OBJECT_PUBLICATION; }
| SCHEMA { $$ = OBJECT_SCHEMA; }
| SERVER { $$ = OBJECT_FOREIGN_SERVER; }
--
2.26.2
v1-0005-Grammar-object-type-refactoring.patchtext/plain; charset=UTF-8; name=v1-0005-Grammar-object-type-refactoring.patch; x-mac-creator=0; x-mac-type=0Download
From 7742b326de1e56b0731fcdfc4447a65c5899c8c1 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
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 <boolean> copy_from opt_program
%type <ival> opt_column event cursor_options opt_hold opt_set_data
-%type <objtype> 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 <objtype> object_type_any_name object_type_name object_type_name_on_any_name
+ drop_type_name
%type <node> 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] <objname> |
- * AGGREGATE <aggname> (arg1, ...) |
- * CAST (<src type> AS <dst type>) |
- * COLUMN <relname>.<colname> |
- * CONSTRAINT <constraintname> ON <relname> |
- * CONSTRAINT <constraintname> ON DOMAIN <domainname> |
- * FUNCTION <funcname> (arg1, arg2, ...) |
- * LARGE OBJECT <oid> |
- * OPERATOR <op> (leftoperand_typ, rightoperand_typ) |
- * OPERATOR CLASS <name> USING <access-method> |
- * OPERATOR FAMILY <name> USING <access-method> |
- * RULE <rulename> ON <relname> |
- * TRIGGER <triggername> ON <relname> ]
- * IS { 'text' | NULL }
+ * COMMENT ON <object> IS <text>
*
*****************************************************************************/
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
v1-0006-Refactor-AlterExtensionContentsStmt-grammar.patchtext/plain; charset=UTF-8; name=v1-0006-Refactor-AlterExtensionContentsStmt-grammar.patch; x-mac-creator=0; x-mac-type=0Download
From 4360cec037c868301c82dbbc244fa8b3c8b22615 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 13 Apr 2020 18:35:20 +0200
Subject: [PATCH v1 6/6] Refactor AlterExtensionContentsStmt grammar
Make use of the general object support already used by COMMENT, DROP,
and SECURITY LABEL.
---
src/backend/commands/extension.c | 19 +++
src/backend/parser/gram.y | 157 ++----------------
.../test_pg_dump/expected/test_pg_dump.out | 4 +-
3 files changed, 31 insertions(+), 149 deletions(-)
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 9b669d95b8..472e69fdaf 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -3269,6 +3269,25 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
Relation relation;
Oid oldExtension;
+ switch (stmt->objtype)
+ {
+ case OBJECT_DATABASE:
+ case OBJECT_EXTENSION:
+ case OBJECT_INDEX:
+ case OBJECT_PUBLICATION:
+ case OBJECT_ROLE:
+ case OBJECT_STATISTIC_EXT:
+ case OBJECT_SUBSCRIPTION:
+ case OBJECT_TABLESPACE:
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("cannot add an object of this type to an extension")));
+ break;
+ default:
+ /* OK */
+ break;
+ }
+
extension.classId = ExtensionRelationId;
extension.objectId = get_extension_oid(stmt->extname, false);
extension.objectSubId = 0;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a1229ebddf..8fb7c24a4e 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -4551,50 +4551,41 @@ alter_extension_opt_item:
*****************************************************************************/
AlterExtensionContentsStmt:
- ALTER EXTENSION name add_drop ACCESS METHOD name
+ ALTER EXTENSION name add_drop object_type_name name
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
n->extname = $3;
n->action = $4;
- n->objtype = OBJECT_ACCESS_METHOD;
- n->object = (Node *) makeString($7);
+ n->objtype = $5;
+ n->object = (Node *) makeString($6);
$$ = (Node *)n;
}
- | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes
+ | ALTER EXTENSION name add_drop object_type_any_name any_name
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
n->extname = $3;
n->action = $4;
- n->objtype = OBJECT_AGGREGATE;
+ n->objtype = $5;
n->object = (Node *) $6;
$$ = (Node *)n;
}
- | ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')'
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_CAST;
- n->object = (Node *) list_make2($7, $9);
- $$ = (Node *) n;
- }
- | ALTER EXTENSION name add_drop COLLATION any_name
+ | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
n->extname = $3;
n->action = $4;
- n->objtype = OBJECT_COLLATION;
+ n->objtype = OBJECT_AGGREGATE;
n->object = (Node *) $6;
$$ = (Node *)n;
}
- | ALTER EXTENSION name add_drop CONVERSION_P any_name
+ | ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')'
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
n->extname = $3;
n->action = $4;
- n->objtype = OBJECT_CONVERSION;
- n->object = (Node *) $6;
- $$ = (Node *)n;
+ n->objtype = OBJECT_CAST;
+ n->object = (Node *) list_make2($7, $9);
+ $$ = (Node *) n;
}
| ALTER EXTENSION name add_drop DOMAIN_P Typename
{
@@ -4614,15 +4605,6 @@ AlterExtensionContentsStmt:
n->object = (Node *) $6;
$$ = (Node *)n;
}
- | ALTER EXTENSION name add_drop opt_procedural LANGUAGE name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_LANGUAGE;
- n->object = (Node *) makeString($7);
- $$ = (Node *)n;
- }
| ALTER EXTENSION name add_drop OPERATOR operator_with_argtypes
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
@@ -4668,123 +4650,6 @@ AlterExtensionContentsStmt:
n->object = (Node *) $6;
$$ = (Node *)n;
}
- | ALTER EXTENSION name add_drop SCHEMA name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_SCHEMA;
- n->object = (Node *) makeString($6);
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop EVENT TRIGGER name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_EVENT_TRIGGER;
- n->object = (Node *) makeString($7);
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop TABLE any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_TABLE;
- n->object = (Node *) $6;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop TEXT_P SEARCH PARSER any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_TSPARSER;
- n->object = (Node *) $8;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop TEXT_P SEARCH DICTIONARY any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_TSDICTIONARY;
- n->object = (Node *) $8;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop TEXT_P SEARCH TEMPLATE any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_TSTEMPLATE;
- n->object = (Node *) $8;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop TEXT_P SEARCH CONFIGURATION any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_TSCONFIGURATION;
- n->object = (Node *) $8;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop SEQUENCE any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_SEQUENCE;
- n->object = (Node *) $6;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop VIEW any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_VIEW;
- n->object = (Node *) $6;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop MATERIALIZED VIEW any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_MATVIEW;
- n->object = (Node *) $7;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop FOREIGN TABLE any_name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_FOREIGN_TABLE;
- n->object = (Node *) $7;
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop FOREIGN DATA_P WRAPPER name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_FDW;
- n->object = (Node *) makeString($8);
- $$ = (Node *)n;
- }
- | ALTER EXTENSION name add_drop SERVER name
- {
- AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
- n->extname = $3;
- n->action = $4;
- n->objtype = OBJECT_FOREIGN_SERVER;
- n->object = (Node *) makeString($6);
- $$ = (Node *)n;
- }
| ALTER EXTENSION name add_drop TRANSFORM FOR Typename LANGUAGE name
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
diff --git a/src/test/modules/test_pg_dump/expected/test_pg_dump.out b/src/test/modules/test_pg_dump/expected/test_pg_dump.out
index a50eaf6125..f14f3a6664 100644
--- a/src/test/modules/test_pg_dump/expected/test_pg_dump.out
+++ b/src/test/modules/test_pg_dump/expected/test_pg_dump.out
@@ -1,9 +1,7 @@
CREATE ROLE regress_dump_test_role;
CREATE EXTENSION test_pg_dump;
ALTER EXTENSION test_pg_dump ADD DATABASE postgres; -- error
-ERROR: syntax error at or near "DATABASE"
-LINE 1: ALTER EXTENSION test_pg_dump ADD DATABASE postgres;
- ^
+ERROR: cannot add an object of this type to an extension
CREATE TABLE test_pg_dump_t1 (c1 int, junk text);
ALTER TABLE test_pg_dump_t1 DROP COLUMN junk; -- to exercise dropped-col cases
CREATE VIEW test_pg_dump_v1 AS SELECT * FROM test_pg_dump_t1;
--
2.26.2
v1-0001-Remove-redundant-grammar-symbols.patchtext/plain; charset=UTF-8; name=v1-0001-Remove-redundant-grammar-symbols.patch; x-mac-creator=0; x-mac-type=0Download
From bdd2440c66292eb2464a49fdc57ff5fa86838f0a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 10 Apr 2020 11:22:19 +0200
Subject: [PATCH v1 1/6] Remove redundant grammar symbols
access_method, database_name, and index_name are all just name, and
they are not used consistently for their alleged purpose, so remove
them. They have been around since ancient times but have no current
reason for existing. Removing them can simplify future grammar
refactoring.
---
src/backend/parser/gram.y | 86 +++++++++++-------------
src/interfaces/ecpg/preproc/ecpg.trailer | 4 +-
2 files changed, 41 insertions(+), 49 deletions(-)
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 3c78f2d1b5..378390af5d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -352,9 +352,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <chr> enable_trigger
%type <str> copy_file_name
- database_name access_method_clause access_method attr_name
+ access_method_clause attr_name
table_access_method_clause name cursor_name file_name
- index_name opt_index_name cluster_index_specification
+ opt_index_name cluster_index_specification
%type <list> func_name handler_name qual_Op qual_all_Op subquery_Op
opt_class opt_inline_handler opt_validator validator_clause
@@ -1184,7 +1184,7 @@ AlterRoleStmt:
opt_in_database:
/* EMPTY */ { $$ = NULL; }
- | IN_P DATABASE database_name { $$ = $3; }
+ | IN_P DATABASE name { $$ = $3; }
;
AlterRoleSetStmt:
@@ -3950,7 +3950,7 @@ part_elem: ColId opt_collate opt_class
;
table_access_method_clause:
- USING access_method { $$ = $2; }
+ USING name { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; }
;
@@ -3975,7 +3975,7 @@ OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; }
| /*EMPTY*/ { $$ = NULL; }
;
-ExistingIndex: USING INDEX index_name { $$ = $3; }
+ExistingIndex: USING INDEX name { $$ = $3; }
;
/*****************************************************************************
@@ -4640,7 +4640,7 @@ AlterExtensionContentsStmt:
n->object = (Node *) $6;
$$ = (Node *)n;
}
- | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING access_method
+ | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING name
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
n->extname = $3;
@@ -4649,7 +4649,7 @@ AlterExtensionContentsStmt:
n->object = (Node *) lcons(makeString($9), $7);
$$ = (Node *)n;
}
- | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING access_method
+ | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING name
{
AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
n->extname = $3;
@@ -5992,7 +5992,7 @@ opt_if_not_exists: IF_P NOT EXISTS { $$ = true; }
CreateOpClassStmt:
CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
- USING access_method opt_opfamily AS opclass_item_list
+ USING name opt_opfamily AS opclass_item_list
{
CreateOpClassStmt *n = makeNode(CreateOpClassStmt);
n->opclassname = $4;
@@ -6091,7 +6091,7 @@ opt_recheck: RECHECK
CreateOpFamilyStmt:
- CREATE OPERATOR FAMILY any_name USING access_method
+ CREATE OPERATOR FAMILY any_name USING name
{
CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt);
n->opfamilyname = $4;
@@ -6101,7 +6101,7 @@ CreateOpFamilyStmt:
;
AlterOpFamilyStmt:
- ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list
+ ALTER OPERATOR FAMILY any_name USING name ADD_P opclass_item_list
{
AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
n->opfamilyname = $4;
@@ -6110,7 +6110,7 @@ AlterOpFamilyStmt:
n->items = $8;
$$ = (Node *) n;
}
- | ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list
+ | ALTER OPERATOR FAMILY any_name USING name DROP opclass_drop_list
{
AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
n->opfamilyname = $4;
@@ -6147,7 +6147,7 @@ opclass_drop:
DropOpClassStmt:
- DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
+ DROP OPERATOR CLASS any_name USING name opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->objects = list_make1(lcons(makeString($6), $4));
@@ -6157,7 +6157,7 @@ DropOpClassStmt:
n->concurrent = false;
$$ = (Node *) n;
}
- | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
+ | DROP OPERATOR CLASS IF_P EXISTS any_name USING name opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->objects = list_make1(lcons(makeString($8), $6));
@@ -6170,7 +6170,7 @@ DropOpClassStmt:
;
DropOpFamilyStmt:
- DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
+ DROP OPERATOR FAMILY any_name USING name opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->objects = list_make1(lcons(makeString($6), $4));
@@ -6180,7 +6180,7 @@ DropOpFamilyStmt:
n->concurrent = false;
$$ = (Node *) n;
}
- | DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
+ | DROP OPERATOR FAMILY IF_P EXISTS any_name USING name opt_drop_behavior
{
DropStmt *n = makeNode(DropStmt);
n->objects = list_make1(lcons(makeString($8), $6));
@@ -6587,7 +6587,7 @@ CommentStmt:
n->comment = $8;
$$ = (Node *) n;
}
- | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text
+ | COMMENT ON OPERATOR CLASS any_name USING name IS comment_text
{
CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_OPCLASS;
@@ -6595,7 +6595,7 @@ CommentStmt:
n->comment = $9;
$$ = (Node *) n;
}
- | COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text
+ | COMMENT ON OPERATOR FAMILY any_name USING name IS comment_text
{
CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_OPFAMILY;
@@ -7437,7 +7437,7 @@ IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name
n->reset_default_tblspc = false;
$$ = (Node *)n;
}
- | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS index_name
+ | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS name
ON relation_expr access_method_clause '(' index_params ')'
opt_include opt_reloptions OptTableSpace where_clause
{
@@ -7480,12 +7480,12 @@ opt_concurrently:
;
opt_index_name:
- index_name { $$ = $1; }
+ name { $$ = $1; }
| /*EMPTY*/ { $$ = NULL; }
;
access_method_clause:
- USING access_method { $$ = $2; }
+ USING name { $$ = $2; }
| /*EMPTY*/ { $$ = DEFAULT_INDEX_TYPE; }
;
@@ -8532,7 +8532,7 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
n->missing_ok = false;
$$ = (Node *)n;
}
- | ALTER DATABASE database_name RENAME TO database_name
+ | ALTER DATABASE name RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_DATABASE;
@@ -8595,7 +8595,7 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
n->missing_ok = false;
$$ = (Node *)n;
}
- | ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
+ | ALTER OPERATOR CLASS any_name USING name RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_OPCLASS;
@@ -8604,7 +8604,7 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
n->missing_ok = false;
$$ = (Node *)n;
}
- | ALTER OPERATOR FAMILY any_name USING access_method RENAME TO name
+ | ALTER OPERATOR FAMILY any_name USING name RENAME TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_OPFAMILY;
@@ -9184,7 +9184,7 @@ AlterObjectSchemaStmt:
n->missing_ok = false;
$$ = (Node *)n;
}
- | ALTER OPERATOR CLASS any_name USING access_method SET SCHEMA name
+ | ALTER OPERATOR CLASS any_name USING name SET SCHEMA name
{
AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
n->objectType = OBJECT_OPCLASS;
@@ -9193,7 +9193,7 @@ AlterObjectSchemaStmt:
n->missing_ok = false;
$$ = (Node *)n;
}
- | ALTER OPERATOR FAMILY any_name USING access_method SET SCHEMA name
+ | ALTER OPERATOR FAMILY any_name USING name SET SCHEMA name
{
AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
n->objectType = OBJECT_OPFAMILY;
@@ -9449,7 +9449,7 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER DATABASE database_name OWNER TO RoleSpec
+ | ALTER DATABASE name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DATABASE;
@@ -9497,7 +9497,7 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleSpec
+ | ALTER OPERATOR CLASS any_name USING name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPCLASS;
@@ -9505,7 +9505,7 @@ AlterOwnerStmt: ALTER AGGREGATE aggregate_with_argtypes OWNER TO RoleSpec
n->newowner = $9;
$$ = (Node *)n;
}
- | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleSpec
+ | ALTER OPERATOR FAMILY any_name USING name OWNER TO RoleSpec
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPFAMILY;
@@ -10209,7 +10209,7 @@ LoadStmt: LOAD file_name
*****************************************************************************/
CreatedbStmt:
- CREATE DATABASE database_name opt_with createdb_opt_list
+ CREATE DATABASE name opt_with createdb_opt_list
{
CreatedbStmt *n = makeNode(CreatedbStmt);
n->dbname = $3;
@@ -10280,21 +10280,21 @@ opt_equal: '=' {}
*****************************************************************************/
AlterDatabaseStmt:
- ALTER DATABASE database_name WITH createdb_opt_list
+ ALTER DATABASE name WITH createdb_opt_list
{
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
n->dbname = $3;
n->options = $5;
$$ = (Node *)n;
}
- | ALTER DATABASE database_name createdb_opt_list
+ | ALTER DATABASE name createdb_opt_list
{
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
n->dbname = $3;
n->options = $4;
$$ = (Node *)n;
}
- | ALTER DATABASE database_name SET TABLESPACE name
+ | ALTER DATABASE name SET TABLESPACE name
{
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
n->dbname = $3;
@@ -10305,7 +10305,7 @@ AlterDatabaseStmt:
;
AlterDatabaseSetStmt:
- ALTER DATABASE database_name SetResetClause
+ ALTER DATABASE name SetResetClause
{
AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
n->dbname = $3;
@@ -10322,7 +10322,7 @@ AlterDatabaseSetStmt:
* This is implicitly CASCADE, no need for drop behavior
*****************************************************************************/
-DropdbStmt: DROP DATABASE database_name
+DropdbStmt: DROP DATABASE name
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $3;
@@ -10330,7 +10330,7 @@ DropdbStmt: DROP DATABASE database_name
n->options = NULL;
$$ = (Node *)n;
}
- | DROP DATABASE IF_P EXISTS database_name
+ | DROP DATABASE IF_P EXISTS name
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $5;
@@ -10338,7 +10338,7 @@ DropdbStmt: DROP DATABASE database_name
n->options = NULL;
$$ = (Node *)n;
}
- | DROP DATABASE database_name opt_with '(' drop_option_list ')'
+ | DROP DATABASE name opt_with '(' drop_option_list ')'
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $3;
@@ -10346,7 +10346,7 @@ DropdbStmt: DROP DATABASE database_name
n->options = $6;
$$ = (Node *)n;
}
- | DROP DATABASE IF_P EXISTS database_name opt_with '(' drop_option_list ')'
+ | DROP DATABASE IF_P EXISTS name opt_with '(' drop_option_list ')'
{
DropdbStmt *n = makeNode(DropdbStmt);
n->dbname = $5;
@@ -10648,7 +10648,7 @@ ClusterStmt:
$$ = (Node*)n;
}
/* kept for pre-8.3 compatibility */
- | CLUSTER opt_verbose index_name ON qualified_name
+ | CLUSTER opt_verbose name ON qualified_name
{
ClusterStmt *n = makeNode(ClusterStmt);
n->relation = $5;
@@ -10661,7 +10661,7 @@ ClusterStmt:
;
cluster_index_specification:
- USING index_name { $$ = $2; }
+ USING name { $$ = $2; }
| /*EMPTY*/ { $$ = NULL; }
;
@@ -14992,16 +14992,8 @@ name_list: name
name: ColId { $$ = $1; };
-database_name:
- ColId { $$ = $1; };
-
-access_method:
- ColId { $$ = $1; };
-
attr_name: ColLabel { $$ = $1; };
-index_name: ColId { $$ = $1; };
-
file_name: Sconst { $$ = $1; };
/*
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 0dbdfdc122..6ccc8ab916 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -114,7 +114,7 @@ connection_target: opt_database_name opt_server opt_port
}
;
-opt_database_name: database_name { $$ = $1; }
+opt_database_name: name { $$ = $1; }
| /*EMPTY*/ { $$ = EMPTY; }
;
@@ -962,7 +962,7 @@ dis_name: connection_object { $$ = $1; }
| /* EMPTY */ { $$ = mm_strdup("\"CURRENT\""); }
;
-connection_object: database_name { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); }
+connection_object: name { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); }
| DEFAULT { $$ = mm_strdup("\"DEFAULT\""); }
| char_variable { $$ = $1; }
;
base-commit: 7966b7980138ebcee7ae986ebcc393aea38a35c0
--
2.26.2
v1-0002-Fold-AlterForeignTableStmt-into-AlterTableStmt.patchtext/plain; charset=UTF-8; name=v1-0002-Fold-AlterForeignTableStmt-into-AlterTableStmt.patch; x-mac-creator=0; x-mac-type=0Download
From 9bba89f80b15356f43aa02d8bbd05e84fa6d36df Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 13 Apr 2020 16:16:26 +0200
Subject: [PATCH v1 2/6] Fold AlterForeignTableStmt into AlterTableStmt
All other relation types are handled by AlterTableStmt, so it's
unnecessary to make a different statement for foreign tables.
---
src/backend/parser/gram.y | 49 +++++++++++++++------------------------
1 file changed, 19 insertions(+), 30 deletions(-)
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 378390af5d..f00526e9c6 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -259,7 +259,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
AlterFdwStmt AlterForeignServerStmt AlterGroupStmt
AlterObjectDependsStmt AlterObjectSchemaStmt AlterOwnerStmt
AlterOperatorStmt AlterTypeStmt AlterSeqStmt AlterSystemStmt AlterTableStmt
- AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt AlterForeignTableStmt
+ AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt
AlterCompositeTypeStmt AlterUserMappingStmt
AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt
AlterDefaultPrivilegesStmt DefACLAction
@@ -851,7 +851,6 @@ stmt :
| AlterExtensionContentsStmt
| AlterFdwStmt
| AlterForeignServerStmt
- | AlterForeignTableStmt
| AlterFunctionStmt
| AlterGroupStmt
| AlterObjectDependsStmt
@@ -2027,6 +2026,24 @@ AlterTableStmt:
n->nowait = $14;
$$ = (Node *)n;
}
+ | ALTER FOREIGN TABLE relation_expr alter_table_cmds
+ {
+ AlterTableStmt *n = makeNode(AlterTableStmt);
+ n->relation = $4;
+ n->cmds = $5;
+ n->relkind = OBJECT_FOREIGN_TABLE;
+ n->missing_ok = false;
+ $$ = (Node *)n;
+ }
+ | ALTER FOREIGN TABLE IF_P EXISTS relation_expr alter_table_cmds
+ {
+ AlterTableStmt *n = makeNode(AlterTableStmt);
+ n->relation = $6;
+ n->cmds = $7;
+ n->relkind = OBJECT_FOREIGN_TABLE;
+ n->missing_ok = true;
+ $$ = (Node *)n;
+ }
;
alter_table_cmds:
@@ -5116,34 +5133,6 @@ CreateForeignTableStmt:
}
;
-/*****************************************************************************
- *
- * QUERY:
- * ALTER FOREIGN TABLE relname [...]
- *
- *****************************************************************************/
-
-AlterForeignTableStmt:
- ALTER FOREIGN TABLE relation_expr alter_table_cmds
- {
- AlterTableStmt *n = makeNode(AlterTableStmt);
- n->relation = $4;
- n->cmds = $5;
- n->relkind = OBJECT_FOREIGN_TABLE;
- n->missing_ok = false;
- $$ = (Node *)n;
- }
- | ALTER FOREIGN TABLE IF_P EXISTS relation_expr alter_table_cmds
- {
- AlterTableStmt *n = makeNode(AlterTableStmt);
- n->relation = $6;
- n->cmds = $7;
- n->relkind = OBJECT_FOREIGN_TABLE;
- n->missing_ok = true;
- $$ = (Node *)n;
- }
- ;
-
/*****************************************************************************
*
* QUERY:
--
2.26.2
On Tue, May 19, 2020 at 2:43 AM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:
Here is a series of patches to do some refactoring in the grammar around
the commands COMMENT, DROP, SECURITY LABEL, and ALTER EXTENSION ...
ADD/DROP. In the grammar, these commands (with some exceptions)
basically just take a reference to an object and later look it up in C
code. Some of that was already generalized individually for each
command (drop_type_any_name, drop_type_name, etc.). This patch combines
it into common lists for all these commands.
I haven't reviewed the code, but +1 for the idea.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On Tue, May 19, 2020 at 12:13 PM Peter Eisentraut <
peter.eisentraut@2ndquadrant.com> wrote:
Here is a series of patches to do some refactoring in the grammar around
the commands COMMENT, DROP, SECURITY LABEL, and ALTER EXTENSION ...
ADD/DROP. In the grammar, these commands (with some exceptions)
basically just take a reference to an object and later look it up in C
code. Some of that was already generalized individually for each
command (drop_type_any_name, drop_type_name, etc.). This patch combines
it into common lists for all these commands.Advantages:
- Avoids having to list each object type at least four times.
- Object types not supported by security labels or extensions are now
explicitly listed and give a proper error message. Previously, this was
just encoded in the grammar itself and specifying a non-supported object
type would just give a parse error.- Reduces lines of code in gram.y.
- Removes some old cruft.
I liked the idea.
I had quick glance through the patches and also did quick review and
testing.
I haven't found any issue with the patch.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Rushabh Lathia
On 2020-05-19 08:43, Peter Eisentraut wrote:
Here is a series of patches to do some refactoring in the grammar around
the commands COMMENT, DROP, SECURITY LABEL, and ALTER EXTENSION ...
ADD/DROP. In the grammar, these commands (with some exceptions)
basically just take a reference to an object and later look it up in C
code. Some of that was already generalized individually for each
command (drop_type_any_name, drop_type_name, etc.). This patch combines
it into common lists for all these commands.
While most of this patch set makes no behavior changes by design, I
should point out this little change hidden in the middle:
Remove deprecated syntax from CREATE/DROP LANGUAGE
Remove the option to specify the language name as a single-quoted
string. This has been obsolete since ee8ed85da3b. Removing it allows
better grammar refactoring.
The syntax of the CREATE FUNCTION LANGUAGE clause is not changed.
(ee8ed85da3b is in PG 7.2.)
I expect this to be uncontroversial, but it should be pointed out.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On May 18, 2020, at 11:43 PM, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
Here is a series of patches to do some refactoring in the grammar around the commands COMMENT, DROP, SECURITY LABEL, and ALTER EXTENSION ... ADD/DROP. In the grammar, these commands (with some exceptions) basically just take a reference to an object and later look it up in C code. Some of that was already generalized individually for each command (drop_type_any_name, drop_type_name, etc.). This patch combines it into common lists for all these commands.
Advantages:
- Avoids having to list each object type at least four times.
- Object types not supported by security labels or extensions are now explicitly listed and give a proper error message. Previously, this was just encoded in the grammar itself and specifying a non-supported object type would just give a parse error.
- Reduces lines of code in gram.y.
- Removes some old cruft.
I like the general direction you are going with this, but the decision in v1-0006 to move the error for invalid object types out of gram.y and into extension.c raises an organizational question. At some places in gram.y, there is C code that checks parsed tokens and ereports if they are invalid, in some sense extending the grammar right within gram.y. In many other places, including what you are doing in this patch, the token is merely stored in a Stmt object with the error checking delayed until command processing. For tokens which need to be checked against the catalogs, that decision makes perfect sense. But for ones where all the information necessary to validate the token exists in the parser, it is not clear to me why it gets delayed until command processing. Is there a design principle behind when these checks are done in gram.y vs. when they are delayed to the command processing? I'm guessing in v1-0006 that you are doing it this way because there are multiple places in gram.y where tokens would need to be checked, and by delaying the check until ExecAlterExtensionContentsStmt, you can put the check all in one place. Is that all it is?
I have had reason in the past to want to reorganize gram.y to have all these types of checks in a single, consistent format and location, rather than scattered through gram.y and backend/commands/. Does anybody else have an interest in this?
My interest in this stems from the fact that bison can be run to generate data files that can then be used in reverse to generate random SQL. The more the parsing logic is visible to bison, the more useful the generated data files are. But a single, consistent design for extra-grammatical error checks could help augment those files fairly well, too.
—
Mark Dilger
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On 2020-05-22 18:53, Mark Dilger wrote:
I like the general direction you are going with this, but the decision in v1-0006 to move the error for invalid object types out of gram.y and into extension.c raises an organizational question. At some places in gram.y, there is C code that checks parsed tokens and ereports if they are invalid, in some sense extending the grammar right within gram.y. In many other places, including what you are doing in this patch, the token is merely stored in a Stmt object with the error checking delayed until command processing. For tokens which need to be checked against the catalogs, that decision makes perfect sense. But for ones where all the information necessary to validate the token exists in the parser, it is not clear to me why it gets delayed until command processing. Is there a design principle behind when these checks are done in gram.y vs. when they are delayed to the command processing? I'm guessing in v1-0006 that you are doing it this way because there are multiple places in gram.y where tokens would need to be checked, and by delaying the check until ExecAlterExtensionContentsStmt, you can put the check all in one place. Is that all it is?
We have been for some time moving to a style where we rely on switch
statements around OBJECT_* constants to (a) decide what is allowed with
certain object types, and (b) make sure we have an explicit decision on
each object type and don't forget any. This has worked well, I think.
This is more of that. Before this patch, it would have been pretty hard
to find out which object types are supported with extensions or security
labels, except by very carefully reading the grammar.
Moreover, you now get a proper error message for unsupported object
types rather than just a generic parse error.
I have had reason in the past to want to reorganize gram.y to have all these types of checks in a single, consistent format and location, rather than scattered through gram.y and backend/commands/. Does anybody else have an interest in this?
My interest in this stems from the fact that bison can be run to generate data files that can then be used in reverse to generate random SQL. The more the parsing logic is visible to bison, the more useful the generated data files are. But a single, consistent design for extra-grammatical error checks could help augment those files fairly well, too.
It's certainly already the case that the grammar accepts statements that
end up being invalid, even if you ignore catalog lookup. I don't think
my patch moves the needle on this in a significant way.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On May 25, 2020, at 2:55 AM, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
On 2020-05-22 18:53, Mark Dilger wrote:
I like the general direction you are going with this, but the decision in v1-0006 to move the error for invalid object types out of gram.y and into extension.c raises an organizational question. At some places in gram.y, there is C code that checks parsed tokens and ereports if they are invalid, in some sense extending the grammar right within gram.y. In many other places, including what you are doing in this patch, the token is merely stored in a Stmt object with the error checking delayed until command processing. For tokens which need to be checked against the catalogs, that decision makes perfect sense. But for ones where all the information necessary to validate the token exists in the parser, it is not clear to me why it gets delayed until command processing. Is there a design principle behind when these checks are done in gram.y vs. when they are delayed to the command processing? I'm guessing in v1-0006 that you are doing it this way because there are multiple places in gram.y where tokens would need to be checked, and by delaying the check until ExecAlterExtensionContentsStmt, you can put the check all in one place. Is that all it is?
We have been for some time moving to a style where we rely on switch statements around OBJECT_* constants to (a) decide what is allowed with certain object types, and (b) make sure we have an explicit decision on each object type and don't forget any. This has worked well, I think.
Yes, I think so, too. I like that overall design.
This is more of that.
Yes, it is.
Before this patch, it would have been pretty hard to find out which object types are supported with extensions or security labels, except by very carefully reading the grammar.
Fair enough.
Moreover, you now get a proper error message for unsupported object types rather than just a generic parse error.
Sounds great.
I have had reason in the past to want to reorganize gram.y to have all these types of checks in a single, consistent format and location, rather than scattered through gram.y and backend/commands/. Does anybody else have an interest in this?
My interest in this stems from the fact that bison can be run to generate data files that can then be used in reverse to generate random SQL. The more the parsing logic is visible to bison, the more useful the generated data files are. But a single, consistent design for extra-grammatical error checks could help augment those files fairly well, too.It's certainly already the case that the grammar accepts statements that end up being invalid, even if you ignore catalog lookup. I don't think my patch moves the needle on this in a significant way.
I don't think it moves the needle too much, either. But since your patch is entirely a refactoring patch and not a feature patch, I thought it would be fair to ask larger questions about how the code should be structured. I like using enums and switch statements and getting better error messages, but there doesn't seem to be any fundamental reason why that should be in the command execution step. It feels like a layering violation to me.
I don't object to this patch getting committed. A subsequent patch to consolidate all the grammar checks into src/backend/parser and out of src/backend/commands won't be blocked by this.
—
Mark Dilger
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
On 2020-05-25 21:09, Mark Dilger wrote:
I don't think it moves the needle too much, either. But since your patch is entirely a refactoring patch and not a feature patch, I thought it would be fair to ask larger questions about how the code should be structured. I like using enums and switch statements and getting better error messages, but there doesn't seem to be any fundamental reason why that should be in the command execution step. It feels like a layering violation to me.
Most utility commands don't have an intermediate parse analysis pass.
They just go straight from the grammar to the execution. Maybe that
could be rethought, but that's the way it is now.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On Tue, May 26, 2020 at 4:28 AM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:
On 2020-05-25 21:09, Mark Dilger wrote:
I don't think it moves the needle too much, either. But since your patch is entirely a refactoring patch and not a feature patch, I thought it would be fair to ask larger questions about how the code should be structured. I like using enums and switch statements and getting better error messages, but there doesn't seem to be any fundamental reason why that should be in the command execution step. It feels like a layering violation to me.
Most utility commands don't have an intermediate parse analysis pass.
They just go straight from the grammar to the execution. Maybe that
could be rethought, but that's the way it is now.
I think it can and should be rethought at some point. The present
split leads to a lot of weird coding. We've had security
vulnerabilities that were due to things like passing the same RangeVar
to two different places, leading to two different lookups for the name
that could be induced to return different OIDs. It also leads to a lot
of fuzzy thinking about where locks are taken, in which order, and how
many times, and with what strength. The code for queries seems to have
been thought through a lot more carefully, because the existence of
prepared queries makes mistakes a lot more noticeable. I hope some day
someone will be motivated to improve the situation for DDL as well,
though it will probably be a thankless task.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Robert Haas <robertmhaas@gmail.com> writes:
On Tue, May 26, 2020 at 4:28 AM Peter Eisentraut
<peter.eisentraut@2ndquadrant.com> wrote:Most utility commands don't have an intermediate parse analysis pass.
They just go straight from the grammar to the execution. Maybe that
could be rethought, but that's the way it is now.
I think it can and should be rethought at some point.
The other problem is that the ones that do have explicit parse analysis
tend to be doing it at the wrong time. I've fixed some ALTER TABLE
problems by rearranging that, but we still have open bugs that are due
to this type of mistake, eg [1]/messages/by-id/16272-6e32da020e9a9381@postgresql.org. I agree that we need a rethink, and
we need it badly.
If this patch is changing when any parse-analysis-like actions happen,
then I would say that it needs very careful review --- much more than
the "refactoring" label would suggest. Maybe it's making things better,
or maybe it doesn't matter; but this area is a minefield.
regards, tom lane
On 2020-05-19 08:43, Peter Eisentraut wrote:
Here is a series of patches to do some refactoring in the grammar around
the commands COMMENT, DROP, SECURITY LABEL, and ALTER EXTENSION ...
ADD/DROP.
These patches have been committed.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services